import { C as Container } from './container-BQx27_d-.cjs'; import './contracts-BHo4LdY2.cjs'; /** * Structural copies of the LangChain Deep Agents backend contract. * * Deep Agents is not a dependency of this package — an adapter that imported it * would drag LangChain into every browser bundle that only wanted a container. * The protocol is structural, so declaring the same shapes here is enough: * `createDeepAgent({ backend: new SandboxedJsBackend(box) })` type-checks * against `SandboxBackendProtocolV2` without the two packages ever meeting. * * Mirrors `deepagents@1.13.2` (`SandboxBackendProtocolV2`, `ExecuteResponse`, * and the `*Result` types). Re-verify against the installed version when * bumping Deep Agents. */ type MaybePromise = T | Promise; type FileOperationError = "file_not_found" | "permission_denied" | "is_directory" | "invalid_path"; interface FileInfo { path: string; is_dir?: boolean; size?: number; modified_at?: string; } interface ExecuteResponse { /** stdout and stderr interleaved, exactly as the command wrote them. */ output: string; exitCode: number | null; truncated: boolean; } interface FileUploadResponse { path: string; error: FileOperationError | null; } interface FileDownloadResponse { path: string; content: Uint8Array | null; error: FileOperationError | null; } interface GrepMatch { path: string; line: number; text: string; } interface LsResult { error?: string; files?: FileInfo[]; } interface ReadResult { error?: string; content?: string | Uint8Array; mimeType?: string; totalLines?: number; startLine?: number; endLine?: number; nextOffset?: number; } interface ReadRawResult { error?: string; data?: { content: string | Uint8Array; mimeType?: string; }; } interface WriteResult { error?: string; path?: string; } interface EditResult { error?: string; path?: string; occurrences?: number; } interface DeleteResult { error?: string; path?: string; } interface GrepResult { error?: string; matches?: GrepMatch[]; truncated?: boolean; } interface GlobResult { error?: string; files?: FileInfo[]; truncated?: boolean; } /** The surface Deep Agents' filesystem and execution middleware actually call. */ interface SandboxBackendProtocolV2 { readonly id: string; execute(command: string): MaybePromise; ls(path: string): MaybePromise; read(filePath: string, offset?: number, limit?: number): MaybePromise; readRaw(filePath: string): MaybePromise; write(filePath: string, content: string): MaybePromise; edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean): MaybePromise; grep(pattern: string, path?: string | null, glob?: string | null, maxCount?: number | null): MaybePromise; glob(pattern: string, path?: string): MaybePromise; delete?(filePath: string): MaybePromise; uploadFiles?(files: Array<[string, Uint8Array]>): MaybePromise; downloadFiles?(paths: string[]): MaybePromise; } interface SandboxedJsBackendOptions { /** Identity reported to Deep Agents. Defaults to a random per-instance id. */ id?: string; /** Working directory every `execute` starts in. Defaults to the container's. */ cwd?: string; /** Wall-clock limit for a single `execute`. Default 120_000ms. */ timeoutMs?: number; /** Characters of combined output kept per command before truncating. Default 30_000. */ maxOutputChars?: number; /** Default line window for `read`. Default 500. */ defaultReadLimit?: number; /** Cap on entries returned by `glob`. Default 1_000. */ maxGlobResults?: number; /** Cap on matches returned by `grep` when the caller gives no `maxCount`. Default 200. */ defaultGrepMaxCount?: number; } /** * A sandboxedjs {@link Container} behind the LangChain Deep Agents backend * contract. * * Deep Agents' `BaseSandbox` derives its filesystem tools from `execute` by * shelling out to `find`, `stat`, `awk` and `grep`. This backend answers them * from {@link Container.fs} instead: the container's filesystem is an in-process * object, so going through the shell would only add parsing and quoting bugs * between the agent and data already in memory. `execute` still runs the real * POSIX shell, so agent-authored commands behave the way the agent expects. * * ```ts * const box = await createContainer({ cwd: "/app", network: { allowOutbound: true } }); * const agent = createDeepAgent({ model, backend: new SandboxedJsBackend(box) }); * ``` * * The instance holds the container but does not own it: call * {@link Container.dispose} yourself when the run is over. */ declare class SandboxedJsBackend implements SandboxBackendProtocolV2 { readonly container: Container; readonly id: string; private readonly cwd; private readonly timeoutMs; private readonly maxOutputChars; private readonly defaultReadLimit; private readonly maxGlobResults; private readonly defaultGrepMaxCount; constructor(container: Container, options?: SandboxedJsBackendOptions); execute(command: string): Promise; ls(path: string): Promise; read(filePath: string, offset?: number, limit?: number): Promise; readRaw(filePath: string): Promise; write(filePath: string, content: string): Promise; edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean): Promise; delete(filePath: string): Promise; glob(pattern: string, path?: string): Promise; grep(pattern: string, path?: string | null, glob?: string | null, maxCount?: number | null): Promise; uploadFiles(files: Array<[string, Uint8Array]>): Promise; downloadFiles(paths: string[]): Promise; } /** * What the agent's environment actually is. * * Every claim here is a behaviour this package implements. Coding agents fail * in a sandbox mostly by assuming a host they do not have — reaching for * `docker`, `sudo`, `systemctl`, `curl localhost:3000`, or a background process * that outlives the turn. Saying plainly what exists is what stops that. */ declare const SANDBOX_ENVIRONMENT_PROMPT = "# Your environment\n\nYou are working inside a sandboxedjs container: a Linux-like environment that\nruns entirely inside a JavaScript process. There is no Docker, no VM, and no\nhost machine you can reach. Everything below is real and available to you.\n\n## What you have\n\n- A POSIX shell (`sh`/`bash` syntax): pipes, redirection, `&&`, `||`,\n subshells, globs, heredocs, variables, functions, `for`/`while`/`case`.\n- Around 140 coreutils: `ls cat cp mv rm mkdir find grep sed awk head tail\n sort uniq wc diff patch tar gzip curl chmod ln touch echo printf test` and\n the rest of the usual set.\n- Node.js, with `node`, `npm` and `npx`. `npm install` resolves against\n the real npm registry when outbound network is enabled.\n- Python 3 via `python3` and `pip`, when the host enabled the Python runtime.\n- A writable virtual filesystem rooted at `/`, persistent for the life of the\n container.\n- A virtual network stack. Servers you start inside the container really listen\n on their ports and can really be requested.\n\n## What you do not have\n\n- No Docker, no VM, no `systemctl`, no `service`, no `apt`/`apt-get`,\n no `yum`, no `brew`. Never try to install system packages.\n- No `sudo` and no reason for it: you already run as the container's user and\n the filesystem is yours.\n- No access to the host machine, its files, its network interfaces, or its\n environment variables. Nothing outside the container exists for you.\n- No GUI, no browser, no interactive editors. Do not run `vim`, `nano`,\n `less`, or `top`; they will hang or fail. Read files by reading them and\n edit them by editing them.\n- No long-running foreground commands. A command that never exits will hit the\n execution timeout and the turn is wasted.\n\n## Running servers\n\nStart servers in the background and never block on them:\n\n```sh\nnode server.js > /tmp/server.log 2>&1 &\n```\n\nThen poll the log for readiness rather than requesting the port immediately.\nDo not run a dev server in the foreground. Do not use `curl localhost:PORT`\nto prove a server works unless you started it in the background first \u2014 the\nhost, not you, is the one that will connect to it.\n\n## How your work is used\n\nThe container is the deliverable. Files you write to the filesystem are what\nthe user receives and what a preview will serve. Write real, complete files to\nreal paths \u2014 do not print a project to stdout and call it done."; /** * Operating rules, in the register a coding harness uses. * * Deliberately about this environment rather than about coding in general: the * host's own system prompt owns the latter, and repeating it only dilutes both. */ declare const SANDBOX_AGENT_RULES = "# Rules\n\n1. Verify before you claim. If you say a server runs or a build passes, you\n ran it in this container and read the output. Never report success you have\n not observed.\n2. One command, one purpose. Chain with `&&` when steps depend on each other\n so a failure stops the chain instead of hiding under a later success.\n3. Read a file before editing it. Edits are literal string replacements; they\n fail when you are guessing at the current contents.\n4. Use absolute paths in file tools. Use `cd` inside a single shell command\n when a command needs a working directory.\n5. Install dependencies with `npm install `, in the directory that has\n the `package.json`. Do not hand-write `node_modules` or invent versions\n in `package.json` \u2014 let the installer resolve them.\n6. Background every server and long task, redirect its output to a log file,\n then poll the log. Never leave a command running in the foreground.\n7. Keep command output small. Pipe noisy commands through `tail`, `head`\n or `grep`. Output is truncated past the backend's limit and you will lose\n the part you needed.\n8. When a command fails, read stderr and fix the cause. Do not retry the same\n command unchanged, and do not work around a failure by faking its result.\n9. Prefer the project's own tooling \u2014 `npm run build`, `npm test`,\n `npx vite` \u2014 over reimplementing what it already does.\n10. Do not attempt to escape the container, reach the host, or disable the\n network policy. Outbound access is the host's decision, not yours.\n11. Prefer the non-interactive form of a command when one exists \u2014 pass the\n flags that pre-answer its questions. A generator that asks nothing is\n faster and its result is the same every run.\n12. An interactive prompt is not a failure. If a command stops on a question\n or a menu, answer it: send the text, or the arrow keys and Enter that the\n prompt names. Read what is on screen before answering, and do not send a\n second answer until the screen has changed."; /** A Deep Agents skill: markdown with the frontmatter its loader parses. */ interface SandboxSkill { name: string; description: string; /** Full file content, frontmatter included, ready to write to disk. */ content: string; } /** * Skills covering the workflows that break first in a sandbox. * * Each is a procedure that has to be followed exactly once to work, and that a * model otherwise improvises differently every run — which is what makes an * agent look unstable when the container underneath is fine. */ declare const SANDBOX_SKILLS: SandboxSkill[]; /** * The whole prompt in one string, for hosts that do not use Deep Agents' skills * middleware and just want to append it to a system prompt. */ declare function sandboxSystemPrompt(options?: { skills?: boolean; }): string; /** * Write the skills into the container as files, one directory each. * * This is the layout Deep Agents' skills middleware discovers: point its * `sources` at the same directory and it loads them itself, so the host does * not have to put any of this in its system prompt. */ declare function installSandboxSkills(container: Container, directory?: string): Promise; export { type DeleteResult, type EditResult, type ExecuteResponse, type FileDownloadResponse, type FileInfo, type FileOperationError, type FileUploadResponse, type GlobResult, type GrepMatch, type GrepResult, type LsResult, type MaybePromise, type ReadRawResult, type ReadResult, SANDBOX_AGENT_RULES, SANDBOX_ENVIRONMENT_PROMPT, SANDBOX_SKILLS, type SandboxBackendProtocolV2, type SandboxSkill, SandboxedJsBackend, type SandboxedJsBackendOptions, type WriteResult, installSandboxSkills, sandboxSystemPrompt };