Skip to content

feat(agent-os): use agent-os-client from crates.io and pass sidecar binary path from npm package#5234

Open
NathanFlurry wants to merge 1 commit into
stack/feat-rivetkit-agent-os-phase-3-process-11-arms-exec-spawn-wait-kill-stop-list-all-tree-get-writestdin-closestdin-execresultdto-unkrssztfrom
stack/feat-agent-os-use-agent-os-client-from-crates-io-and-pass-sidecar-binary-path-from-npm-package-xkllkonn
Open

feat(agent-os): use agent-os-client from crates.io and pass sidecar binary path from npm package#5234
NathanFlurry wants to merge 1 commit into
stack/feat-rivetkit-agent-os-phase-3-process-11-arms-exec-spawn-wait-kill-stop-list-all-tree-get-writestdin-closestdin-execresultdto-unkrssztfrom
stack/feat-agent-os-use-agent-os-client-from-crates-io-and-pass-sidecar-binary-path-from-npm-package-xkllkonn

Conversation

@NathanFlurry

@NathanFlurry NathanFlurry commented Jun 12, 2026

Copy link
Copy Markdown
Member

No description provided.

@NathanFlurry

Copy link
Copy Markdown
Member Author

Stack for rivet-dev/rivet

Current stack:

Dependencies:

Get stack: forklift get 5234
Push local edits: forklift submit
Merge when ready: forklift merge 5234

@claude

claude Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

PR Review: feat(agent-os): use agent-os-client from crates.io and pass sidecar binary path from npm package\n\nGood overall direction — moving from path deps to published crates and wiring up the sidecar binary path from npm are both the right calls. A few issues worth addressing before merge.\n\n---\n\n### Critical\n\n**unsafe { std::env::set_var } in rivetkit-typescript/packages/rivetkit-napi/src/agent_os.rs:68-78\n\nThe SAFETY comment claims this runs once before any VM is created, but this assumption can be violated: (1) if createAgentOsFactory is called more than once (tests, hot-reload), concurrent calls race on the env var; (2) Node.js libuv/thread-pool threads can read env vars concurrently with this write; (3) it is a process-global side effect affecting every dependency that reads AGENT_OS_SIDECAR_BIN. The safer fix is to pass the path through the structured config JSON alongside software and moduleAccessCwd, and have Rust config parsing forward it to the client directly, avoiding the global mutation entirely.\n\n---\n\n### Memory\n\nPreviewStore grows unbounded in actions/preview.rs\n\nExpired tokens are only evicted lazily on resolve lookup. An actor that creates many preview URLs and never explicitly calls expireSignedPreviewUrl will accumulate stale entries indefinitely. At minimum, create should sweep expired entries before inserting, or the run loop should run a periodic GC pass.\n\n---\n\n### Correctness\n\nMulti-value HTTP headers silently dropped**\n\nIn run.rs::proxy_preview and actions/network.rs::fetch, response headers are collected into a HashMap/BTreeMap keyed by name. insert silently overwrites duplicates, corrupting legitimately multi-valued headers like Set-Cookie. Consider Vec<(String, String)> to preserve all values, or document the limitation.\n\nInconsistent header UTF-8 handling between proxy and fetch\n\nproxy_preview uses String::from_utf8_lossy (replaces bad bytes with the replacement character) while network::fetch uses to_str().unwrap_or_default() (returns empty string). Pick one and use it consistently.\n\n---\n\n### Style (per CLAUDE.md)\n\n**map_err(|e| anyhow!(e)) pattern in cron.rs and session.rs\n\nCLAUDE.md: "Prefer .context() over the anyhow! macro." If the underlying error already implements std::error::Error, ? or .map_err(anyhow::Error::from) suffices. If context is useful, use .context(\"...\").\n\n---\n\n### Minor\n\nUnsafe cast in flattenSoftware (agent-os/actor/index.ts:42)\n\nout.push(input as SoftwareDescriptorLike) bypasses type checking. The downstream typeof d.commandDir === \"string\" guards handle bad shapes at runtime, but a plain-object check (Object.getPrototypeOf(input) === Object.prototype) would be more precise.\n\nTruthy check for kind classification may misfire (actor/index.ts:55)**\n\nd.hostTool || d.toolkit ? \"tool\" : \"agent\" misclassifies if either field is falsy but present (empty string, 0, false). Prefer d.hostTool != null || d.toolkit != null.\n\n---\n\n### Non-issues\n\n- _ => in mod.rs::dispatch matches on &str, not an enum — CLAUDE.md's explicit-variant rule does not apply.\n- f64 for epoch-millis timestamps is fine; current values (~1.7e12) are well within 2^53.\n- PreviewStore as a plain HashMap is correct — it is single-threaded local state owned by the run loop.

@NathanFlurry NathanFlurry force-pushed the stack/feat-agent-os-use-agent-os-client-from-crates-io-and-pass-sidecar-binary-path-from-npm-package-xkllkonn branch from 94738d3 to 3db3433 Compare June 12, 2026 23:05
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