Mirror astrid:[email protected] (per-request HTTP controls) + catch up the contracts pin
Goal
Mirror the astrid:[email protected] host contract (per-request HTTP controls) into the JS SDK, matching the Rust SDK. Deferred from the [email protected] rollout because sdk-js's contracts submodule is several feature-PRs behind and doesn't carry [email protected] yet. Nothing is broken today — this is catch-up work, not a fix.
Reference implementation (mirror its API shape): unicity-astrid/sdk-rust#60 — the Rust SDK equivalent. Contract source: host/[email protected] in unicity-astrid/wit (on main). Kernel impl: unicity-astrid/astrid#1050. Design: unicity-astrid/rfcs#22 (host_abi, the "HTTP: per-request control" section).
Current state (file refs)
contractssubmodule pin:9742f80— behindwitmain(812c833) by #14 (process un-stub), #15 (file-injection), #16 (session 1.1.0), #17 ([email protected]). Onlycontracts/host/[email protected]exists locally;[email protected]is not yet pulled in.packages/astrid-sdk/src/http.ts(~346 lines): hand-writtenRequest(class @ line 74) /Response(138) builder. ImportshttpRequest as hostRequest/httpStreamStart as hostStreamStartfrom "astrid:http/[email protected]"(lines 18-25).toWit()(128) builds the @1.0.0http-request-data.send(172) /stream(250) /fetch(319) call the host fns. No per-request options field onRequestyet.- Codegen:
prebuildrunsscripts/generate-contracts.mjs(jco-based) which generates the host bindings (httpRequest, etc.) fromcontracts/.scripts/sync-contracts-wit.shsyncs the bus bundle.build=tsc -b. Node >= 20. (sdk-js binds the host ABI only via the twohostRequest/hostStreamStartcall sites — noastrid-sys-style world.)
Steps
- Bump the
contractssubmodule pin9742f80→812c833(latestwit/mainwith[email protected]). NOTE: this also pulls in #14/#15/#16 — re-runscripts/sync-contracts-wit.shto regen the bus bundle; the bundle diff will include the session 1.1.0 / process / file-injection interface records (additive).httpis ahost/package, not in the bundle. Commit the submodule pointer + the regenerated bundle together (the Rust SDK's CLAUDE.md documents this pin≠mirror discipline; sdk-js mirrors it). - Multi-version staging check (CRITICAL — the trap that bit the Rust SDK).
astrid:httpnow ships TWO version files ([email protected]+[email protected]) incontracts/host/. wit-bindgen/jco rejects two files declaring different(package, version)identifiers in onedeps/<dir>/("package identifierastrid:[email protected]does not match previous package name ofastrid:[email protected]"). The Rust SDK fixed this inastrid-sys/build.rsby staging each version in its owndeps/astrid-<pkg>@<version>/dir. Check whethergenerate-contracts.mjs/ jco hits the same collision once both http files are present; if so, apply the analogous per-version-dir staging. http.ts: switch the host import toastrid:http/[email protected](thehttp-request-opts/http-stream-start-optsfns); add the per-request options to theRequestbuilder andtoWit()(constructrequest-options); call the*-optshost fns fromsend/stream/fetch; addresponse-metaaccessors toResponse; surface the new error arms. Keep backward compatibility: an untouchedRequest→ all-unset options == @1.0.0 behaviour.
The surface to mirror (from the @1.1.0 contract / sdk-rust#60)
Request options (all optional; unset == @1.0.0):
- timeouts:
connect-ms/first-byte-ms/between-bytes-ms/total-ms— builder e.g..timeout()(total) /.connectTimeout()/.firstByteTimeout()/.readTimeout()(between-bytes), in ms. The four timeout fields are DEFAULTS a caller may override (even larger), not ceilings. redirect:follow|error|manual(.redirect());max-redirects(.maxRedirects()) — a ceiling the host clamps to.max-response-bytes,max-decompressed-bytes,auto-decompress— body/decompression caps.https-only(.httpsOnly()),integrity(sha256-<base64>/ sha384 / sha512).
Response meta (response-meta on the buffered response): final-url, redirect-count, elapsed-ms, wire-bytes → Response accessors.
New error-code arms to surface: redirect-blocked, too-many-redirects, integrity-mismatch, scheme-denied, decompression-bomb (plus dns-error / tls-error already in @1.0.0).
Defer (same as the Rust SDK)
http-upload(streaming request body) — the host returns not-implemented.http-stream.trailers— the host returnsnone. Don't surface a non-functional API; leave// TODOnotes. (These will be enabled when the kernel implements them — tracked against[email protected]follow-ups.)
Verify
npm run build(tsc -b) green;http.tscompiles against the new@1.1.0bindings; the codegen regenerates cleanly.- No version bump — releases are a separate PR per the SDK's release process.
Broader note
This bump catches sdk-js's contracts up by several feature-PRs (process un-stub, file-injection, session 1.1.0, http 1.1.0). The bundle/codegen changes are additive, but confirm the regen + tsc -b stay green against the newer contracts — that catch-up is part of the work, not just the http surface.
Source: astrid-runtime/sdk-js