sbox-sdk 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +137 -0
  3. package/dist/adapter/index.d.ts +22 -0
  4. package/dist/adapter/index.d.ts.map +1 -0
  5. package/dist/adapter/index.js +16 -0
  6. package/dist/agent-tools/index.d.ts +13 -0
  7. package/dist/agent-tools/index.d.ts.map +1 -0
  8. package/dist/agent-tools/index.js +9 -0
  9. package/dist/agent-tools/policy.d.ts +48 -0
  10. package/dist/agent-tools/policy.d.ts.map +1 -0
  11. package/dist/agent-tools/policy.js +51 -0
  12. package/dist/agent-tools/registry.d.ts +9 -0
  13. package/dist/agent-tools/registry.d.ts.map +1 -0
  14. package/dist/agent-tools/registry.js +412 -0
  15. package/dist/agent-tools/result.d.ts +32 -0
  16. package/dist/agent-tools/result.d.ts.map +1 -0
  17. package/dist/agent-tools/result.js +14 -0
  18. package/dist/agent-tools/types.d.ts +76 -0
  19. package/dist/agent-tools/types.d.ts.map +1 -0
  20. package/dist/agent-tools/types.js +1 -0
  21. package/dist/ai/index.d.ts +36 -0
  22. package/dist/ai/index.d.ts.map +1 -0
  23. package/dist/ai/index.js +40 -0
  24. package/dist/ai-sdk/index.d.ts +31 -0
  25. package/dist/ai-sdk/index.d.ts.map +1 -0
  26. package/dist/ai-sdk/index.js +80 -0
  27. package/dist/anthropic/index.d.ts +42 -0
  28. package/dist/anthropic/index.d.ts.map +1 -0
  29. package/dist/anthropic/index.js +64 -0
  30. package/dist/aws-lambda/index.d.ts +87 -0
  31. package/dist/aws-lambda/index.d.ts.map +1 -0
  32. package/dist/aws-lambda/index.js +290 -0
  33. package/dist/beam/index.d.ts +92 -0
  34. package/dist/beam/index.d.ts.map +1 -0
  35. package/dist/beam/index.js +222 -0
  36. package/dist/blaxel/index.d.ts +125 -0
  37. package/dist/blaxel/index.d.ts.map +1 -0
  38. package/dist/blaxel/index.js +220 -0
  39. package/dist/cli.d.ts +3 -0
  40. package/dist/cli.d.ts.map +1 -0
  41. package/dist/cli.js +249 -0
  42. package/dist/cloudflare/index.d.ts +64 -0
  43. package/dist/cloudflare/index.d.ts.map +1 -0
  44. package/dist/cloudflare/index.js +259 -0
  45. package/dist/codesandbox/index.d.ts +100 -0
  46. package/dist/codesandbox/index.d.ts.map +1 -0
  47. package/dist/codesandbox/index.js +227 -0
  48. package/dist/conformance/index.d.ts +20 -0
  49. package/dist/conformance/index.d.ts.map +1 -0
  50. package/dist/conformance/index.js +189 -0
  51. package/dist/daytona/index.d.ts +64 -0
  52. package/dist/daytona/index.d.ts.map +1 -0
  53. package/dist/daytona/index.js +258 -0
  54. package/dist/e2b/index.d.ts +63 -0
  55. package/dist/e2b/index.d.ts.map +1 -0
  56. package/dist/e2b/index.js +411 -0
  57. package/dist/fly/index.d.ts +75 -0
  58. package/dist/fly/index.d.ts.map +1 -0
  59. package/dist/fly/index.js +222 -0
  60. package/dist/index.d.ts +21 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +16 -0
  63. package/dist/internal/capabilities.d.ts +57 -0
  64. package/dist/internal/capabilities.d.ts.map +1 -0
  65. package/dist/internal/capabilities.js +68 -0
  66. package/dist/internal/client.d.ts +9 -0
  67. package/dist/internal/client.d.ts.map +1 -0
  68. package/dist/internal/client.js +126 -0
  69. package/dist/internal/encoding.d.ts +8 -0
  70. package/dist/internal/encoding.d.ts.map +1 -0
  71. package/dist/internal/encoding.js +20 -0
  72. package/dist/internal/errors.d.ts +45 -0
  73. package/dist/internal/errors.d.ts.map +1 -0
  74. package/dist/internal/errors.js +79 -0
  75. package/dist/internal/exec.d.ts +19 -0
  76. package/dist/internal/exec.d.ts.map +1 -0
  77. package/dist/internal/exec.js +208 -0
  78. package/dist/internal/plugin.d.ts +38 -0
  79. package/dist/internal/plugin.d.ts.map +1 -0
  80. package/dist/internal/plugin.js +1 -0
  81. package/dist/internal/runtime.d.ts +8 -0
  82. package/dist/internal/runtime.d.ts.map +1 -0
  83. package/dist/internal/runtime.js +21 -0
  84. package/dist/internal/sandbox.d.ts +12 -0
  85. package/dist/internal/sandbox.d.ts.map +1 -0
  86. package/dist/internal/sandbox.js +438 -0
  87. package/dist/internal/shell.d.ts +36 -0
  88. package/dist/internal/shell.d.ts.map +1 -0
  89. package/dist/internal/shell.js +88 -0
  90. package/dist/internal/stream.d.ts +15 -0
  91. package/dist/internal/stream.d.ts.map +1 -0
  92. package/dist/internal/stream.js +58 -0
  93. package/dist/internal/types.d.ts +381 -0
  94. package/dist/internal/types.d.ts.map +1 -0
  95. package/dist/internal/types.js +1 -0
  96. package/dist/langchain/index.d.ts +25 -0
  97. package/dist/langchain/index.d.ts.map +1 -0
  98. package/dist/langchain/index.js +61 -0
  99. package/dist/mastra/index.d.ts +43 -0
  100. package/dist/mastra/index.d.ts.map +1 -0
  101. package/dist/mastra/index.js +69 -0
  102. package/dist/memory/index.d.ts +57 -0
  103. package/dist/memory/index.d.ts.map +1 -0
  104. package/dist/memory/index.js +573 -0
  105. package/dist/modal/index.d.ts +67 -0
  106. package/dist/modal/index.d.ts.map +1 -0
  107. package/dist/modal/index.js +223 -0
  108. package/dist/morph/index.d.ts +91 -0
  109. package/dist/morph/index.d.ts.map +1 -0
  110. package/dist/morph/index.js +221 -0
  111. package/dist/northflank/index.d.ts +74 -0
  112. package/dist/northflank/index.d.ts.map +1 -0
  113. package/dist/northflank/index.js +265 -0
  114. package/dist/openai/index.d.ts +25 -0
  115. package/dist/openai/index.d.ts.map +1 -0
  116. package/dist/openai/index.js +71 -0
  117. package/dist/railway/index.d.ts +109 -0
  118. package/dist/railway/index.d.ts.map +1 -0
  119. package/dist/railway/index.js +219 -0
  120. package/dist/runloop/index.d.ts +69 -0
  121. package/dist/runloop/index.d.ts.map +1 -0
  122. package/dist/runloop/index.js +226 -0
  123. package/dist/testing/index.d.ts +44 -0
  124. package/dist/testing/index.d.ts.map +1 -0
  125. package/dist/testing/index.js +61 -0
  126. package/dist/vercel/index.d.ts +63 -0
  127. package/dist/vercel/index.d.ts.map +1 -0
  128. package/dist/vercel/index.js +241 -0
  129. package/package.json +252 -0
  130. package/src/aws-lambda/runner/Dockerfile +15 -0
  131. package/src/aws-lambda/runner/README.md +59 -0
  132. package/src/aws-lambda/runner/server.mjs +91 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vivek Kornepalli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # sbox-sdk
2
+
3
+ One unified SDK for agent **sandbox** providers (E2B, Vercel Sandbox, Cloudflare Sandbox, and more). Write your code once; swap the adapter import to change provider — the rest of your code stays the same.
4
+
5
+ > Status: **alpha** (`0.0.1`). Ships adapters for E2B, Vercel, Cloudflare, Daytona, Modal, Fly, AWS Lambda, Northflank, Runloop, CodeSandbox, Morph, Blaxel, Beam, and Railway — plus a built-in **in-memory** provider for tests/dev. E2B is the most battle-tested; the newer adapters pass the shared conformance suite offline but are less proven against live APIs.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install sbox-sdk
11
+ # then install the provider SDK you use (optional peer dependency):
12
+ npm install @e2b/code-interpreter
13
+ ```
14
+
15
+ ## Quickstart
16
+
17
+ ```ts
18
+ import { createSandboxClient } from "sbox-sdk";
19
+ import { e2b } from "sbox-sdk/e2b";
20
+
21
+ const client = createSandboxClient({
22
+ provider: e2b({ apiKey: process.env.E2B_API_KEY! }),
23
+ });
24
+ const sandbox = await client.create({ template: "python-3.12", ttlMs: 60_000 });
25
+
26
+ // exec — await for a buffered result (never throws on non-zero exit):
27
+ const res = await sandbox.commands.run("echo hi", { cwd: "/app" });
28
+ console.log(res.exitCode, res.stdout);
29
+
30
+ // ...or for-await the SAME handle to stream live:
31
+ for await (const ev of sandbox.commands.run(["python", "train.py"])) {
32
+ if (ev.type === "stdout") process.stdout.write(ev.data);
33
+ }
34
+
35
+ // filesystem (web-standard bodies in, StoredFile out):
36
+ await sandbox.files.write("/app/data.json", JSON.stringify({ ok: true }));
37
+ const text = await (await sandbox.files.read("/app/data.json")).text();
38
+
39
+ await sandbox.destroy();
40
+ await client.dispose();
41
+ ```
42
+
43
+ Zero config? `createSandboxClient()` defaults to an in-memory provider — great for tests:
44
+
45
+ ```ts
46
+ import { createSandboxClient } from "sbox-sdk";
47
+ const sb = await createSandboxClient().create();
48
+ await sb.commands.run("echo works offline");
49
+ ```
50
+
51
+ ## Swap providers, keep your code
52
+
53
+ ```ts
54
+ import { vercel } from "sbox-sdk/vercel";
55
+ const client = createSandboxClient({
56
+ provider: vercel({ token, teamId, projectId }),
57
+ });
58
+ // every sandbox.commands / sandbox.files call site above is unchanged
59
+ ```
60
+
61
+ ## Providers
62
+
63
+ Import a provider from its subpath and install its SDK as an (optional) peer:
64
+
65
+ | Provider | Import | Peer SDK |
66
+ | ----------- | ---------------------- | --------------------------------- |
67
+ | E2B | `sbox-sdk/e2b` | `@e2b/code-interpreter` |
68
+ | Vercel | `sbox-sdk/vercel` | `@vercel/sandbox` |
69
+ | Cloudflare | `sbox-sdk/cloudflare` | `@cloudflare/sandbox` |
70
+ | Daytona | `sbox-sdk/daytona` | `@daytonaio/sdk` |
71
+ | Modal | `sbox-sdk/modal` | `modal` |
72
+ | Fly | `sbox-sdk/fly` | _none (REST)_ |
73
+ | AWS Lambda | `sbox-sdk/aws-lambda` | `@aws-sdk/client-lambda-microvms` |
74
+ | Northflank | `sbox-sdk/northflank` | `@northflank/js-client` |
75
+ | Runloop | `sbox-sdk/runloop` | `@runloop/api-client` |
76
+ | CodeSandbox | `sbox-sdk/codesandbox` | `@codesandbox/sdk` |
77
+ | Morph | `sbox-sdk/morph` | `morphcloud` |
78
+ | Blaxel | `sbox-sdk/blaxel` | `@blaxel/core` |
79
+ | Beam | `sbox-sdk/beam` | `@beamcloud/beam-js` |
80
+ | Railway | `sbox-sdk/railway` | `railway` |
81
+
82
+ The in-memory provider (`sbox-sdk/memory`, also the zero-config default) needs no peer.
83
+
84
+ ## Capability gating
85
+
86
+ Each provider declares a static capability table. Sub-APIs that a provider doesn't support are typed `undefined` — calling them is a **compile error**, and unsupported features throw `NotSupportedError` at runtime _before_ any network call.
87
+
88
+ ```ts
89
+ // `sandbox.code` only exists on providers with a code interpreter (e.g. E2B):
90
+ if (sandbox.code) {
91
+ const exec = await sandbox.code.runCode(
92
+ "import matplotlib.pyplot as plt; plt.plot([1,2,3])"
93
+ );
94
+ for (const r of exec.results)
95
+ if (r.mime["image/png"]) save(r.mime["image/png"]);
96
+ }
97
+
98
+ // runtime tri-state level (native | emulated | unsupported):
99
+ console.log(sandbox.capabilities.map.snapshot);
100
+
101
+ // dynamic providers: `can()` narrows at runtime + type level:
102
+ if (sandbox.can("snapshot")) await sandbox.snapshots.create({ name: "ckpt" });
103
+ ```
104
+
105
+ ## Errors
106
+
107
+ All providers normalize to one `SandboxError` taxonomy (`code`, `provider`, `retryable`, …). Key rules:
108
+
109
+ - `commands.run(...)` **never throws on a non-zero exit** — the exit code is data (`result.exitCode`).
110
+ - `files.exists()` returns `false` only on NotFound; auth/timeout errors throw.
111
+ - `NotSupportedError` is thrown synchronously, before any network call.
112
+
113
+ ## Writing an adapter
114
+
115
+ Implement the `SandboxProvider` contract from `sbox-sdk/adapter` and run it through the shared conformance suite:
116
+
117
+ ```ts
118
+ import { runConformance } from "sbox-sdk/conformance";
119
+ const report = await runConformance(myProvider());
120
+ expect(report.passed).toBe(true);
121
+ ```
122
+
123
+ ## CLI
124
+
125
+ The package ships a `sbox` bin. `caps` and `doctor` run fully offline; `exec`
126
+ and `list` read credentials from the environment.
127
+
128
+ ```bash
129
+ npx sbox caps e2b # print a provider's capability matrix
130
+ npx sbox doctor e2b # check node + whether the provider SDK is installed
131
+ npx sbox exec e2b -- echo hi # run one command in a fresh sandbox
132
+ npx sbox list e2b # list live sandboxes
133
+ ```
134
+
135
+ ## License
136
+
137
+ MIT
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `sbox-sdk/adapter` — the authoring kit for provider adapters. Implement
3
+ * `SandboxProvider` and return it from a factory wrapped in `defineProvider`.
4
+ * Everything an adapter needs (contract types, capability helpers, the error
5
+ * taxonomy, and shell-emulation helpers) is re-exported from here.
6
+ */
7
+ import type { CapabilityMap } from "../internal/capabilities.js";
8
+ import type { SandboxProvider } from "../internal/types.js";
9
+ /** Typed-identity wrapper so a provider factory infers its Caps/Raw/Opts. */
10
+ export declare function defineProvider<Caps extends CapabilityMap, Raw, Opts>(factory: (opts: Opts) => SandboxProvider<Caps, Raw>): (opts: Opts) => SandboxProvider<Caps, Raw>;
11
+ export type { SandboxProvider, DriverHandle, DriverExec, DriverProcess, CallContext, MaybePromise, SandboxSpec, SandboxInfo, SandboxState, ResourceSpec, VolumeMount, SecretRef, ExecOptions, ExecResult, OutputEvent, ProcessInfo, FileBody, FileType, FileInfo, DirEntry, StoredFile, FsEvent, Preview, EgressPolicy, SshCredentials, KernelContext, RichResult, CodeExecution, SnapshotRef, ListFilter, } from "../internal/types.js";
12
+ export { baseCapabilities, defaultFlags, freezeCapabilities, isCapable, assertCapability, } from "../internal/capabilities.js";
13
+ export type { CapabilityMap, CapabilityLevel, CapabilityName, CapabilityFlags, Capabilities, PreviewModel, } from "../internal/capabilities.js";
14
+ export { SandboxError, NotSupportedError, ProviderNotFoundError, AllProvidersFailedError, isRetryableStatus, isRetryableError, } from "../internal/errors.js";
15
+ export type { SandboxErrorCode, SandboxErrorInit, ProviderAttempt, } from "../internal/errors.js";
16
+ export { shellQuote, joinCmd, buildExecCommand, parseLsOutput, parseStatOutput, EXIT_MARKER, } from "../internal/shell.js";
17
+ export type { BuiltExec } from "../internal/shell.js";
18
+ export { detectRuntime, hasFetch } from "../internal/runtime.js";
19
+ export type { Runtime } from "../internal/runtime.js";
20
+ export { AsyncQueue, numExit } from "../internal/stream.js";
21
+ export { base64ToBytes, bytesToBase64 } from "../internal/encoding.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,SAAS,aAAa,EAAE,GAAG,EAAE,IAAI,EAClE,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,GAClD,CAAC,IAAI,EAAE,IAAI,KAAK,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAE5C;AAGD,YAAY,EACV,eAAe,EACf,YAAY,EACZ,UAAU,EACV,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,OAAO,EACP,OAAO,EACP,YAAY,EACZ,cAAc,EACd,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,SAAS,EACT,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,aAAa,EACb,eAAe,EACf,cAAc,EACd,eAAe,EACf,YAAY,EACZ,YAAY,GACb,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,UAAU,EACV,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /** Typed-identity wrapper so a provider factory infers its Caps/Raw/Opts. */
2
+ export function defineProvider(factory) {
3
+ return factory;
4
+ }
5
+ // ---- capability helpers + types ----
6
+ export { baseCapabilities, defaultFlags, freezeCapabilities, isCapable, assertCapability, } from "../internal/capabilities.js";
7
+ // ---- error taxonomy ----
8
+ export { SandboxError, NotSupportedError, ProviderNotFoundError, AllProvidersFailedError, isRetryableStatus, isRetryableError, } from "../internal/errors.js";
9
+ // ---- shell-emulation helpers (for exec-over-transport adapters) ----
10
+ export { shellQuote, joinCmd, buildExecCommand, parseLsOutput, parseStatOutput, EXIT_MARKER, } from "../internal/shell.js";
11
+ // ---- runtime probe ----
12
+ export { detectRuntime, hasFetch } from "../internal/runtime.js";
13
+ // ---- stream bridge (push callbacks -> AsyncIterable<OutputEvent>) ----
14
+ export { AsyncQueue, numExit } from "../internal/stream.js";
15
+ // ---- encoding helpers (exec-over-text fs) ----
16
+ export { base64ToBytes, bytesToBase64 } from "../internal/encoding.js";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `sbox-sdk/agent-tools` — the framework-agnostic agent-tooling core. Build a
3
+ * provider-neutral tool set from any sandbox, then project it into a framework
4
+ * with one of the adapter subpaths (`sbox-sdk/ai-sdk`, `/openai`, …) or feed it
5
+ * to the (future) MCP server. Depends only on the core SDK + `zod`.
6
+ */
7
+ export { createSandboxTools } from "./registry.js";
8
+ export type { ToolName, Risk, ToolAnnotations, ToolRunContext, ToolSpec, ToolSetOptions, FrameworkAdapter, } from "./types.js";
9
+ export { ok, err } from "./result.js";
10
+ export type { ToolResult, ToolResultContent } from "./result.js";
11
+ export { decide, effectiveRisk, enforcePolicy, DEFAULT_DECISIONS, } from "./policy.js";
12
+ export type { Decision, SandboxPolicy, ApprovalRequest, AuditRecord, } from "./policy.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,YAAY,EACV,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,cAAc,EACd,QAAQ,EACR,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACtC,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EACL,MAAM,EACN,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,QAAQ,EACR,aAAa,EACb,eAAe,EACf,WAAW,GACZ,MAAM,aAAa,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `sbox-sdk/agent-tools` — the framework-agnostic agent-tooling core. Build a
3
+ * provider-neutral tool set from any sandbox, then project it into a framework
4
+ * with one of the adapter subpaths (`sbox-sdk/ai-sdk`, `/openai`, …) or feed it
5
+ * to the (future) MCP server. Depends only on the core SDK + `zod`.
6
+ */
7
+ export { createSandboxTools } from "./registry.js";
8
+ export { ok, err } from "./result.js";
9
+ export { decide, effectiveRisk, enforcePolicy, DEFAULT_DECISIONS, } from "./policy.js";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The single, framework-agnostic approval model. One `SandboxPolicy` is
3
+ * authored once; each adapter translates a `Decision` into that framework's
4
+ * native human-in-the-loop mechanism (AI SDK `needsApproval`, OpenAI
5
+ * interruptions, Mastra `suspend()`, or an `onApprovalRequest` gate).
6
+ */
7
+ import type { Risk, ToolName, ToolRunContext, ToolSpec } from "./types.js";
8
+ export type Decision = "allow" | "ask" | "deny";
9
+ export interface ApprovalRequest {
10
+ readonly tool: ToolName;
11
+ readonly title: string;
12
+ readonly input: unknown;
13
+ readonly risk: Risk;
14
+ readonly sandboxId: string;
15
+ }
16
+ export interface AuditRecord {
17
+ readonly tool: ToolName;
18
+ readonly input: unknown;
19
+ readonly risk: Risk;
20
+ readonly decision: Decision;
21
+ readonly sandboxId: string;
22
+ }
23
+ export interface SandboxPolicy {
24
+ /** Per-risk default decision. Defaults to DEFAULT_DECISIONS below. */
25
+ defaults?: Partial<Record<Risk, Decision>>;
26
+ /** Per-tool override; may inspect the actual input. Wins over `defaults`. */
27
+ rules?: Partial<Record<ToolName, (input: unknown, ctx: ToolRunContext) => Decision>>;
28
+ /** Hard removal — tool never appears in the produced set. */
29
+ forbid?: ToolName[];
30
+ /** Used by adapters with no native HITL (Anthropic, LangChain without a graph). */
31
+ onApprovalRequest?: (req: ApprovalRequest) => boolean | Promise<boolean>;
32
+ /** Observe every decision (logging, metrics, audit trails). */
33
+ audit?: (rec: AuditRecord) => void;
34
+ }
35
+ /** Sensible default: only destructive actions pause for approval. */
36
+ export declare const DEFAULT_DECISIONS: Readonly<Record<Risk, Decision>>;
37
+ /** Effective risk for a given input (refined for multi-verb tools). */
38
+ export declare function effectiveRisk(spec: ToolSpec, input: unknown): Risk;
39
+ /** Resolve the approval decision for one tool call. */
40
+ export declare function decide(spec: ToolSpec, input: unknown, ctx: ToolRunContext, policy?: SandboxPolicy): Decision;
41
+ /**
42
+ * Shared approval gate used by adapters without native HITL (and as the portable
43
+ * default everywhere). Returns `null` when the call may proceed, or a denial
44
+ * message the model can read. `"ask"` awaits `onApprovalRequest` when configured;
45
+ * otherwise it proceeds (human-in-the-loop is opt-in). Emits `audit` records.
46
+ */
47
+ export declare function enforcePolicy(spec: ToolSpec, input: unknown, ctx: ToolRunContext, policy?: SandboxPolicy): Promise<string | null>;
48
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/agent-tools/policy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3E,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC3C,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CACb,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,KAAK,QAAQ,CAAC,CACpE,CAAC;IACF,6DAA6D;IAC7D,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,+DAA+D;IAC/D,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;CACpC;AAED,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAI9D,CAAC;AAEF,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAElE;AAED,uDAAuD;AACvD,wBAAgB,MAAM,CACpB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,aAAa,GACrB,QAAQ,CAUV;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwBxB"}
@@ -0,0 +1,51 @@
1
+ /** Sensible default: only destructive actions pause for approval. */
2
+ export const DEFAULT_DECISIONS = {
3
+ destructive: "ask",
4
+ mutating: "allow",
5
+ safe: "allow",
6
+ };
7
+ /** Effective risk for a given input (refined for multi-verb tools). */
8
+ export function effectiveRisk(spec, input) {
9
+ return spec.riskFor?.(input) ?? spec.risk;
10
+ }
11
+ /** Resolve the approval decision for one tool call. */
12
+ export function decide(spec, input, ctx, policy) {
13
+ if (policy?.forbid?.includes(spec.name)) {
14
+ return "deny";
15
+ }
16
+ const rule = policy?.rules?.[spec.name];
17
+ if (rule) {
18
+ return rule(input, ctx);
19
+ }
20
+ const risk = effectiveRisk(spec, input);
21
+ return policy?.defaults?.[risk] ?? DEFAULT_DECISIONS[risk];
22
+ }
23
+ /**
24
+ * Shared approval gate used by adapters without native HITL (and as the portable
25
+ * default everywhere). Returns `null` when the call may proceed, or a denial
26
+ * message the model can read. `"ask"` awaits `onApprovalRequest` when configured;
27
+ * otherwise it proceeds (human-in-the-loop is opt-in). Emits `audit` records.
28
+ */
29
+ export async function enforcePolicy(spec, input, ctx, policy) {
30
+ const risk = effectiveRisk(spec, input);
31
+ const sandboxId = ctx.sandbox?.id ?? "";
32
+ const audit = (decision) => policy?.audit?.({ decision, input, risk, sandboxId, tool: spec.name });
33
+ const decision = decide(spec, input, ctx, policy);
34
+ if (decision === "deny") {
35
+ audit("deny");
36
+ return `Denied by policy: ${spec.name} is not permitted.`;
37
+ }
38
+ if (decision === "ask" && policy?.onApprovalRequest) {
39
+ const approved = await policy.onApprovalRequest({
40
+ input,
41
+ risk,
42
+ sandboxId,
43
+ title: spec.title,
44
+ tool: spec.name,
45
+ });
46
+ audit(approved ? "allow" : "deny");
47
+ return approved ? null : `Approval denied for ${spec.name}.`;
48
+ }
49
+ audit("allow");
50
+ return null;
51
+ }
@@ -0,0 +1,9 @@
1
+ import type { Sandbox } from "../internal/types.js";
2
+ import type { ToolSetOptions, ToolSpec } from "./types.js";
3
+ /**
4
+ * Build the provider-neutral tool set for a sandbox: only the tools whose
5
+ * capabilities the provider supports, minus `forbid`, intersected with `only`.
6
+ * This `ToolSpec[]` is the input to every `toXTools` adapter.
7
+ */
8
+ export declare function createSandboxTools(sandbox: Sandbox, opts?: ToolSetOptions): ToolSpec[];
9
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/agent-tools/registry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,KAAK,EAKV,cAAc,EACd,QAAQ,EACT,MAAM,YAAY,CAAC;AA+cpB;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,GAAE,cAAmB,GACxB,QAAQ,EAAE,CASZ"}