mirror of
https://github.com/langchain-ai/deepagentsjs.git
synced 2026-07-18 16:04:44 -04:00
Closed
opened 2026-02-16 06:17:30 -05:00 by yindo
·
0 comments
No Branch/Tag Specified
main
dependabot/npm_and_yarn/patch-deps-updates-main-c0f001c0f6
dependabot/npm_and_yarn/major-deps-updates-main-b7ceb5d816
dependabot/npm_and_yarn/minor-deps-updates-main-f52a01c0f6
dependabot/github_actions/major-deps-updates-5c183d6ffa
dependabot/github_actions/minor-deps-updates-38afab4f4d
dependabot/github_actions/patch-deps-updates-00a0d7aaea
dependabot/docker/examples/async-subagent-server/major-deps-updates-docker-4faa477378
feat/delete-backend-protocol
feat/write-file-overwrites
feat/recursive-delete-tool
corridor/fix-1119d955-1783568785287
open-swe/bump-langsmith-0-8-0
alex/initializer
cb/connectors-spec-19bb
open-swe/fs-interrupt-permissions
sydney/oolong-ptc-runners
cb/fs-permissions-interrupt-9517
hunter/swarm-oolong-eval
colifran/swarm-eval
colifran/interp-libs
colifran/workflow-poc
colifran/swarm-sub-mw-defaults
hunter/fix-ci-read-file-mime-guard
fix/filesystem-glob-suppress-permission-errors
hunter/middleware-replace-by-name
hunter/fix-node-vfs-absolute-exec-paths
colifran/lazy-skills
cb/fix-subagent-stream-same-type-isolation
fix/acp-filesystem-virtual-mode
colifran/skill-dist
colifran/skill-cli
open-swe/9065a8d9-c0c3-5c29-b106-1a195b97ddbd
colifran/permissions
colifran/repl-swarm
hunter/quickjs-pending-write-reads
colifran/swarm-in-repl
jacob/subagents
jacob/subagenttype
open-swe/7460276d-5f03-10ca-8a53-7653699f1133
colifran/swarm-tool
hunter/fix-sandbox-find-follow-symlinks
open-swe/dfd00850-86b7-5f87-2c10-3bd968b1c75e
colifran/swarm-refactor
colifran/swarm-table
colifran/swarm
open-swe/8d89ab28-9b47-3a19-427b-aacfa4c5d099
open-swe/086c3d27-2ff0-ebf5-5d74-4d35e38083c5
open-swe/23f64c62-afe9-dc40-bbe0-c86a558611b3
hunter/namespace-factories
alpha
baseten-integration
colifran/deprecate-backend-factories
colifran/agent-protocol-poc
colifran/a2a-subagents
ci/add-codeql-scanning
colifran/async-example
colifran/async-subagents-example
1.9.0-alpha.1
colifran/backend-rename
hunter/js-queue-lookahead-middleware
cb/secure-exec
cb/pass-checkpointer
colifran/multimodal-refactor-pr2
structured-output-evals
subagent-structured-output
colifran/multimodal-refactor-pr1
cb/async-agents
hunter/repl-rlm
cb/ptc-repl-network-policy
cb/ptc-repl
cb/ptc
open-swe/020b364c-2a7f-e2b2-30e0-4593befd0490
add-evals
hunter/structured-output-eval
cb/composite-fix
hunter/async-subagents
hunter/relo-evals
cb/summarization-improvements
hunter/deepbash
harbor-evals
hunter/trace-metadata
hunter/integration
cb/langsmith-sandbox
isolate-agent-skills
hunter/batch-task
fix-memory-load-state
add-e2e-test
cb/add-streaming-example
copilot/fix-partial-file-updates
copilot/fix-file-state-loss
nh/release-1.0.0
dqbd/fs-store
hunter/v1
dqbd/js
cb/createAgent-migration
cb/repo-update
palash/add-built-in-toosl
palash/skip-tools
palash/add-interrupt-config
brace/bump-langgraph
open-swe/6f37e688-42f4-458b-a26a-9de18f1c5ab8
palash/post-model-hook
palash/add-local
palash/add-post-model-hook-interrupt
palash/final-touch-ups
palash/subagent-fix
palash/add-langgraph-server
palash/update-readme
palash/change-name-to-deepagents
palash/fix-anthropic-zod-import
brace/fixes
open-swe/8357536e-2207-4292-a24d-00ea431ed4d4
open-swe/9453f008-7578-458d-bb92-e729e9fca363
deepagents@1.11.1
deepagents-acp@0.1.20
deepagents@1.11.0
deepagents-acp@0.1.19
@langchain/node-vfs@0.2.1
deepagents@1.10.8
deepagents-acp@0.1.18
deepagents@1.10.7
deepagents-acp@0.1.17
deepagents@1.10.6
deepagents-acp@0.1.16
@langchain/quickjs@0.6.0
@langchain/modal@0.1.5
@langchain/daytona@0.2.1
deepagents@1.10.5
deepagents-acp@0.1.15
@langchain/quickjs@0.5.1
deepagents@1.10.4
deepagents-acp@0.1.14
@langchain/quickjs@0.5.0
@langchain/node-vfs@0.2.0
deepagents@1.10.2
deepagents-acp@0.1.12
deepagents@1.10.1
deepagents-acp@0.1.11
@langchain/quickjs@0.4.0
deepagents@1.10.0
deepagents-acp@0.1.10
@langchain/quickjs@0.3.0
deepagents@1.9.1
deepagents-acp@0.1.9
@langchain/quickjs@0.2.6
deepagents@1.9.0
deepagents-acp@0.1.8
@langchain/sandbox-standard-tests@1.0.0
@langchain/quickjs@0.2.5
@langchain/node-vfs@0.1.4
@langchain/modal@0.1.4
deepagents@1.9.0-alpha.1
deepagents-acp@0.1.8-alpha.0
@langchain/quickjs@0.2.5-alpha.0
@langchain/node-vfs@0.1.4-alpha.0
@langchain/modal@0.1.4-alpha.0
@langchain/deno@0.2.2-alpha.0
@langchain/daytona@0.2.0-alpha.0
deepagents@1.8.8
deepagents-acp@0.1.7
@langchain/quickjs@0.2.4
deepagents@1.8.7
deepagents-acp@0.1.6
@langchain/quickjs@0.2.3
@langchain/daytona@0.2.0
deepagents@1.8.6
deepagents-acp@0.1.5
@langchain/quickjs@0.2.2
@langchain/deno@0.2.2
deepagents@1.9.0-alpha.0
deepagents-acp@0.1.5-alpha.0
@langchain/sandbox-standard-tests@1.0.0-alpha.0
@langchain/quickjs@1.0.0-alpha.0
@langchain/node-vfs@1.0.0-alpha.0
@langchain/modal@1.0.0-alpha.0
@langchain/deno@1.0.0-alpha.0
@langchain/daytona@1.0.0-alpha.0
deepagents@1.8.5
deepagents-acp@0.1.4
@langchain/quickjs@0.2.1
@langchain/node-vfs@0.1.3
deepagents@1.8.3
deepagents-acp@0.1.2
deepagents-acp@0.1.0
deepagents@1.8.1
@langchain/modal@0.1.3
deepagents@1.8.0
@langchain/sandbox-standard-tests@0.1.0
@langchain/node-vfs@0.1.2
@langchain/deno@0.2.1
@langchain/daytona@0.1.2
deepagents@1.7.6
deepagents@1.7.5
deepagents@1.7.4
@langchain/deno@0.2.0
@langchain/deno@0.1.2
deepagents@1.7.3
deepagents@1.7.2
@langchain/modal@0.1.2
deepagents@1.7.1
@langchain/node-vfs@0.1.1
@langchain/modal@0.1.1
@langchain/deno@0.1.1
@langchain/daytona@0.1.1
deepagents@1.7.0
@langchain/node-vfs@0.1.0
@langchain/modal@0.1.0
@langchain/deno@0.1.0
@langchain/daytona@0.1.0
deepagents@1.6.3
deepagents@1.6.2
deepagents@1.6.1
deepagents@1.6.0
deepagents@1.5.1
deepagents@1.5.0
deepagents@1.4.2
deepagents@1.4.1
deepagents@1.4.0
v1.3.1
v1.3.0
v1.2.0
v1.1.1
v1.1.0
No Label
pull-request
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: langchain-ai/deepagentsjs#228
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/langchain-ai/deepagentsjs/pull/229
Author: @hntrl
Created: 2/14/2026
Status: ❌ Closed
Base:
main← Head:hunter/deepbash📝 Commits (10+)
525b968feat: add WASIX execution backend foundation29cee28feat: add ProxyFileSystem, WASIX runtime, and TS-WASM wiring50277fafeat: wire real bash execution via @wasmer/sdk34a7a0dfeat: add subagent spawning protocol via filesystem RPC53d0fe4refactor: rename deepagent-cli to subagent-cli01496f7feat: add interactive shell() method to WasixBackend251ea8dfeat: add daemon and attach demo for interactive WASIX shell8b7866ffeat: add composable filesystem mounts via BackendProtocol282ae8ffix: daemon demo backends to implement full BackendProtocolda4c505fix: use bash -i for interactive shell mode📊 Changes
57 files changed (+12133 additions, -67 deletions)
View changed files
📝
.gitignore(+7 -1)📝
eslint.config.ts(+1 -1)➕
libs/deepbash/assets/.gitignore(+2 -0)➕
libs/deepbash/assets/subagent.wasm(+0 -0)➕
libs/deepbash/examples/attach.ts(+88 -0)➕
libs/deepbash/examples/daemon.ts(+195 -0)➕
libs/deepbash/examples/demo-backend.ts(+178 -0)➕
libs/deepbash/examples/test.ts(+42 -0)➕
libs/deepbash/package.json(+92 -0)➕
libs/deepbash/rollup.config.mjs(+133 -0)➕
libs/deepbash/rust/.cargo/config.toml(+5 -0)➕
libs/deepbash/rust/Cargo.toml(+4 -0)➕
libs/deepbash/rust/runtime/.cargo/config.toml(+13 -0)➕
libs/deepbash/rust/runtime/.gitignore(+1 -0)➕
libs/deepbash/rust/runtime/Cargo.toml(+151 -0)➕
libs/deepbash/rust/runtime/rust-toolchain.toml(+6 -0)➕
libs/deepbash/rust/runtime/src/fs/directory.rs(+337 -0)➕
libs/deepbash/rust/runtime/src/fs/mod.rs(+3 -0)➕
libs/deepbash/rust/runtime/src/instance.rs(+262 -0)➕
libs/deepbash/rust/runtime/src/js_runtime.rs(+133 -0)...and 37 more files
📄 Description
This PR introduces
deepbash, an in-process WASM-based bash execution backend for deepagents. Instead of shelling out to Docker containers, remote sandboxes, or the host OS, agents execute bash commands inside a WebAssembly sandbox with a virtual filesystem all within a single node processThe Problem
We need to give models access to a shell. The current approaches all have fundamental tradeoffs:
The core tension: virtual backends (in-memory filesystem) can't expose their state to child processes spawned via
execute(). A real bash process can't see your virtual FS. Containers solve this but add latency, infrastructure dependencies, and opacity. We wanted something that runs in-process, gives subprocess access to a shared virtual filesystem, and lets the host introspect every file operation.The Solution: WASIX in WebAssembly
WASIX extends the WASI (WebAssembly System Interface) spec with POSIX features that standard WASI lacks — critically, subprocess spawning (
proc_spawn) and Berkeley sockets (sock_open,sock_connect). Processes inside a WASIX sandbox share a virtual filesystem, meaningbash -c "python script.py && cat output.json"works because both bash and python see the same virtual files.We forked the wasmer-js runtime (~5K lines of Rust) into a purpose-built package that strips networking, the Wasmer registry client, and deployment infrastructure, replacing them with fully offline package resolution from locally bundled
.webcassets. The result is a self-contained WASM module (~5.4 MB) that boots a complete bash + coreutils environment with zero network calls.Architecture
Execution Flow
When an agent calls
execute("grep -r TODO src/ | wc -l"):Key Design Decisions
1. Why fork wasmer-js instead of using
@wasmer/sdk?The
@wasmer/sdknpm package works, but it has problems for our use case:bash.webcdependencies (coreutils) are resolved by queryingregistry.wasmer.iovia GraphQL and downloading ~4.5 MB fromcdn.wasmer.ioon every cold startDirectoryclass is non-extensible — you can't inject custom filesystem handlers (not implemented yet, but the idea is we can pass direct backend protocol methods to the runtime)The fork (
deepbash-runtime) preserves the battle-tested execution machinery (Command.run()→task_dedicated→run_command) while replacing the registry/networking layer withInMemorySource+ aregisterLocalPackage()API. The hot path is now:2. Why WASIX instead of standard WASI?
WASIX is Wasmer's extension of WASI that adds features standard WASI lacks:
proc_spawn(subprocesses)sock_*(Berkeley sockets)pthread_create)fd_pipe(inter-process pipes)proc_signal(signals)The subprocess story is the dealbreaker. Without
proc_spawn,bash -c "grep foo *.py | wc -l"can't work — bash needs to fork child processes that share the filesystem. WASIX is the only WASM standard that supports this, and Wasmer is the only runtime that implements it. Both are MIT licensed.3. Subagent spawning: filesystem RPC, not stdout markers
Instead of parsing stdout for magic markers (fragile, can collide with real output), we use a filesystem-based RPC protocol:
Inside the sandbox, the
subagentCLI (a 110 KB Rust binary compiled to WASM) writes JSON request files:On the host side, after command execution completes,
DeepbashBackendreads/.rpc/requests/*.json, parses theSpawnRequestobjects, and returns them alongside the command output. The deepagents middleware then creates actual subagents from these requests.Why this approach:
/.rpc/requests/ls /.rpc/requests/to see pending spawnsmethodfield supports future RPC operations beyondspawn4. Composable filesystem mounts via BackendProtocol
Rather than a monolithic virtual filesystem, deepbash supports mounting any BackendProtocol implementation into the WASIX sandbox at arbitrary paths:
Before execution, files are downloaded from each mounted backend and populated into WASIX
Directoryobjects. After execution, a byte-level diff detects changes and uploads modified/new files back to the original backend. The WASIX process sees a unified filesystem while each mount path is backed by a different storage system.This means an agent can
cat /data/config.json, edit it, andcpit to/work/— the change to/data/config.jsonflows back to the real filesystem, while the copy in/work/stays in ephemeral state.5. Interactive shell mode (daemon + attach)
Beyond batch
execute()calls, deepbash supports persistent interactive shell sessions:This enables the daemon/attach architecture demonstrated in
examples/: a background process owns the WASIX sandbox, and multiple clients can attach to it for interactive shell access. The shell process persists across commands, maintaining environment variables, working directory, and process state.The Rust Layer
deepbash contains two Rust crates:
rust/runtime/— The WASIX runtime (~5K lines, forked from wasmer-js)Core dependencies:
wasmer 6.1.0— WASM engine (JS backend)wasmer-wasix 0.601.0— WASIX syscall implementationwebc 10.0.1— WEBC container parservirtual-fs 0.601.0— Virtual filesystem traitsKey modifications from upstream:
src/lib.rs— AddedregisterLocalPackage()+setSdkUrl()APIssrc/package_loader.rs— Checks localGLOBAL_CONTAINERSstore before HTTPsrc/runtime.rs—InMemorySourcereplacesBackendSourcefor dependency resolutionsrc/net.rs— Gutted (empty module)src/registry/,wasmer-backend-apidep,bincodedep, WebSocket supportrust/subagent-cli/— The subagent RPC binary (~165 lines)A minimal Rust program compiled to
wasm32-wasip1that provides thesubagent spawn <task>command inside the WASIX environment. Writes JSON files to/.rpc/requests/using only POSIX filesystem operations. Compiled output: 110 KB.How DeepbashBackend Fits the Framework
deepbash implements
SandboxBackendProtocolfrom the deepagents framework by extendingBaseSandbox:BaseSandboxprovides default implementations for all file operations (read,write,edit,grep,glob) by composing pure POSIX shell commands and routing them throughexecute(). This means DeepbashBackend only needs to implement three methods:execute(),uploadFiles(),downloadFiles(). Everything else — the entireBackendProtocolsurface — works automatically through the inherited shell-based implementations.The integration with
createDeepAgentis a one-liner:File Changes Summary
New package:
libs/deepbash/(~15,000 lines added)src/backend.ts,src/types.ts,src/index.ts,src/node.tsrust/runtime/src/**(~50 files)rust/subagent-cli/src/main.rsassets/bash.webc,assets/coreutils.webc,assets/subagent.wasmtests/backend.test.ts,tests/backend.int.test.ts,tests/mounts.int.test.ts,tests/spawn.int.test.tsexamples/daemon.ts,examples/attach.ts,examples/test.tsrollup.config.mjs,scripts/download-assets.sh,package.jsonVerification
What's Next
FileSystemtrait enables read-only mounts, write-blocklists, etc. (architecture supports it, not yet implemented)FileSystemtrait callbacks for streaming file change events during executionstack_checkpoint/stack_restore: WASIX syscalls for pausing and resuming execution mid-command🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
[PR #229] feat: deepbashto [PR #229] [CLOSED] feat: deepbash