@mastra/daytona 0.9.0-alpha.1 → 0.9.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # @mastra/daytona
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added a `secrets` option to `DaytonaSandbox` for injecting Daytona Secrets into sandboxes. Map environment variable names to Daytona Secret names and the real value is substituted into HTTPS request headers at egress — the raw credential never enters the sandbox. ([#22322](https://github.com/mastra-ai/mastra/pull/22322))
8
+
9
+ ```typescript
10
+ const sandbox = new DaytonaSandbox({
11
+ secrets: {
12
+ GITHUB_TOKEN: 'github-token',
13
+ },
14
+ });
15
+ ```
16
+
17
+ Closes https://github.com/mastra-ai/mastra/issues/22314
18
+
19
+ - Added computer-use support to `DaytonaSandbox`. Workspaces backed by Daytona can now take screenshots, control the mouse and keyboard, inspect the display, and open a noVNC viewer through the standard computer tools. ([#21701](https://github.com/mastra-ai/mastra/pull/21701))
20
+
21
+ ```typescript
22
+ const sandbox = new DaytonaSandbox();
23
+ await sandbox.start();
24
+
25
+ await sandbox.computer.leftClick(100, 200);
26
+ const screenshot = await sandbox.computer.screenshot();
27
+ ```
28
+
29
+ Desktop services start lazily on the first computer operation. Set `computerUse: false` to disable the capability or `computerUse: { autoStart: false }` to manage those services directly.
30
+
31
+ ### Patch Changes
32
+
33
+ - Fixed a leak where every command left its process handle behind, by removing Daytona's own `executeCommand` in favour of the shared one, which releases them. ([#21984](https://github.com/mastra-ai/mastra/pull/21984))
34
+
35
+ Command results now match every other provider: `command` holds the full command string, and the separate `args` array is gone.
36
+
37
+ ```typescript
38
+ const result = await sandbox.executeCommand('echo', ['hello']);
39
+ // before: result.command === 'echo', result.args === ['hello']
40
+ // after: result.command === 'echo hello', result.args === undefined
41
+ ```
42
+
43
+ - Starting a sandbox now reports whether it created a fresh sandbox or reconnected to an existing one, so an `onStart` handler can run first-time setup only when it's actually needed: ([#21984](https://github.com/mastra-ai/mastra/pull/21984))
44
+
45
+ ```typescript
46
+ new E2BSandbox({
47
+ id: 'session-1',
48
+ onStart: async ({ outcome }) => {
49
+ if (outcome === 'created') await cloneRepo();
50
+ },
51
+ });
52
+ ```
53
+
54
+ - Honor the sandbox runtime environment (`setEnv()`/`getEnv()` from `@mastra/core`) in every workspace sandbox provider. Environment variables set after construction now reach subsequent commands on all providers: ([#22250](https://github.com/mastra-ai/mastra/pull/22250))
55
+
56
+ - Process-manager-routed providers (E2B, Blaxel, Cloudflare, Daytona, Docker, Modal, Vercel microVM spawns) inherit the merge from the core spawn wrapper; their duplicated per-manager env plumbing is removed.
57
+ - Providers with their own exec transports (AgentCore, Apple Container, Railway, Vercel microVM and serverless `executeCommand`, Platform's private-network, WebSocket lease, and E2B lease paths) now merge `getEnv()` under per-call env.
58
+
59
+ Constructor `env` continues to behave as before: it seeds the sandbox runtime environment, and providers that bake env into the VM or container at creation time (Docker, Modal, Railway, Apple Container, Vercel, Platform) still do so. Per-call `env` on `executeCommand` still takes precedence for that command only.
60
+
61
+ Removed exported types (minor bump for these two packages): `BlaxelProcessManagerOptions` from `@mastra/blaxel` and `RailwayProcessManagerOptions` from `@mastra/railway`. Both existed only to pass `env` into a process manager constructed by hand; the core spawn wrapper now owns that merge, so the option and its type are gone.
62
+
63
+ - Updated dependencies [[`79f04a7`](https://github.com/mastra-ai/mastra/commit/79f04a7f6c6829da541139f638f2f1d267916e08), [`65edab1`](https://github.com/mastra-ai/mastra/commit/65edab1c233d17b8f163bad12fca410d0e6f16b1), [`1e47b75`](https://github.com/mastra-ai/mastra/commit/1e47b7520cab4cfaa8daed52f17e2e6d14ff7539), [`ab20a38`](https://github.com/mastra-ai/mastra/commit/ab20a38d0275f8d85e0f3833bd87ef487bcc609f), [`fd4d5fe`](https://github.com/mastra-ai/mastra/commit/fd4d5fe4f943699b85db5e74404f190d5a6b8c2a), [`ae8790c`](https://github.com/mastra-ai/mastra/commit/ae8790c4bfaa088d2ab279d1dcc06f326b9fd109), [`2c85f42`](https://github.com/mastra-ai/mastra/commit/2c85f428e04ccd63ea31a7ec80b5b327afdad555), [`11bbeb9`](https://github.com/mastra-ai/mastra/commit/11bbeb9b108ef2264e05acefc6dafb9cbb342921), [`48ef1f1`](https://github.com/mastra-ai/mastra/commit/48ef1f1d24eedafbb07f64e659a81b52b67b8bf6), [`aa3a85d`](https://github.com/mastra-ai/mastra/commit/aa3a85daf094c683bb97efdf4b6a696d2e474af5), [`d29d06f`](https://github.com/mastra-ai/mastra/commit/d29d06fe00bbd35b4571150ea04c59d2ed783c71), [`e6516df`](https://github.com/mastra-ai/mastra/commit/e6516dfcdae4f4ac0e7971d84359a81385ee602f), [`1a485f3`](https://github.com/mastra-ai/mastra/commit/1a485f3538f5ec64d58bd8b5e1e99de0c695c87b), [`0d37487`](https://github.com/mastra-ai/mastra/commit/0d37487d9f349388a3f1cef6a536cf9dcc4b6273), [`8661d7d`](https://github.com/mastra-ai/mastra/commit/8661d7d7179f0a024456aabdd8679bcecd09ac28), [`dbbfeb8`](https://github.com/mastra-ai/mastra/commit/dbbfeb85ec949dc9ebc0755e1ad262e4f5eba8db), [`575e343`](https://github.com/mastra-ai/mastra/commit/575e343900451021d96110916497d334af7bc252), [`0b2a3d1`](https://github.com/mastra-ai/mastra/commit/0b2a3d1783875c5b97b7b36ab3d03d7360e0dde7), [`6bb5d71`](https://github.com/mastra-ai/mastra/commit/6bb5d7193fe9166b219f0fccae17db7a5ae86e65), [`3cc9d00`](https://github.com/mastra-ai/mastra/commit/3cc9d00b2b4333e0377a5e9df5eff92c17ce7630), [`cacb839`](https://github.com/mastra-ai/mastra/commit/cacb8392d9e74189b56d857290b0615f98a2683d), [`57de7d6`](https://github.com/mastra-ai/mastra/commit/57de7d644ba7146edb4e9e6111ec4fa98c3a59e9), [`c8e4cea`](https://github.com/mastra-ai/mastra/commit/c8e4ceac9a390d78c8327dff3cdb2861dd71957f), [`ed01e9a`](https://github.com/mastra-ai/mastra/commit/ed01e9a807514a904374bf687a7b8f18750f6f78), [`b47b26e`](https://github.com/mastra-ai/mastra/commit/b47b26e6fe95cb8a3482be2c5e52de157fe59d0b), [`0d37487`](https://github.com/mastra-ai/mastra/commit/0d37487d9f349388a3f1cef6a536cf9dcc4b6273), [`733a537`](https://github.com/mastra-ai/mastra/commit/733a537489a858b5880b2e98809334fba895a221), [`e8e299c`](https://github.com/mastra-ai/mastra/commit/e8e299cc6abdfc39947e2fec25803493015d3882), [`edfc548`](https://github.com/mastra-ai/mastra/commit/edfc548886bc7bae17b681f8b6b41a47eb32bcd2), [`b05f486`](https://github.com/mastra-ai/mastra/commit/b05f48612984d5fe2447ea2d6cdd5c604d285b97), [`a8a4871`](https://github.com/mastra-ai/mastra/commit/a8a4871215f51da95c47129602157ce5372f634a), [`eb9ecaa`](https://github.com/mastra-ai/mastra/commit/eb9ecaa89c36e889749e3b825cfc507ce7f7980b), [`4ff3ee2`](https://github.com/mastra-ai/mastra/commit/4ff3ee2bff7ed07528b4817f8f49639031c72a4d), [`9207dfa`](https://github.com/mastra-ai/mastra/commit/9207dfab8062e5fc68b751684797ff86fe0b4e70), [`5165cdc`](https://github.com/mastra-ai/mastra/commit/5165cdcdcf50e144bb8113278535196cc9b07065), [`e737014`](https://github.com/mastra-ai/mastra/commit/e737014e0fc7035759762bb5b48baef1d6c0f6a7), [`6bb5d71`](https://github.com/mastra-ai/mastra/commit/6bb5d7193fe9166b219f0fccae17db7a5ae86e65), [`f591643`](https://github.com/mastra-ai/mastra/commit/f591643becdf0be9bddce6ba1748e64bc30d77f1), [`63796ba`](https://github.com/mastra-ai/mastra/commit/63796ba0fda60253be17535e68f6bbbf1e6ffa09), [`b1ad324`](https://github.com/mastra-ai/mastra/commit/b1ad324d657f3544b0701332aef7eb10e9a36258), [`61c566d`](https://github.com/mastra-ai/mastra/commit/61c566dd2f2cde2b23ed8f139924e530d4202214), [`c24754c`](https://github.com/mastra-ai/mastra/commit/c24754c1fb6fe144e5051e536e98c8a18b0214ac), [`12c61d2`](https://github.com/mastra-ai/mastra/commit/12c61d280c8cb208bc3c8dbcbe5dcc60cf9d1cd0), [`c46eb09`](https://github.com/mastra-ai/mastra/commit/c46eb09ce4987509af57a0ac582c61241a6dd2f1), [`9ee8120`](https://github.com/mastra-ai/mastra/commit/9ee8120ce17f76b9f617489e05a283353742690a), [`d975e92`](https://github.com/mastra-ai/mastra/commit/d975e924d4936f46c386bd3dee39c671720289f6), [`45dd6ee`](https://github.com/mastra-ai/mastra/commit/45dd6ee089bd7df0d0c98a10098e483fd388e04a), [`4e9a228`](https://github.com/mastra-ai/mastra/commit/4e9a2283d5fd6ed1b70a2751eb3dc2cbf82ada20), [`d6ce34a`](https://github.com/mastra-ai/mastra/commit/d6ce34aeceb06ddf3d595a1eed5cc74f481a46a1), [`f95f468`](https://github.com/mastra-ai/mastra/commit/f95f468cf1e7c2b924a13826494f98b8f2ccd581), [`30ed33e`](https://github.com/mastra-ai/mastra/commit/30ed33ee14084a26019aba15fceadda6d6ddefaf), [`04a815f`](https://github.com/mastra-ai/mastra/commit/04a815fc8971d29e97fcdcc5008a1eb472fc00ff), [`1cfa878`](https://github.com/mastra-ai/mastra/commit/1cfa8784d8da0dfaa0317e5048bc48b6084a5ea5), [`9a12ef3`](https://github.com/mastra-ai/mastra/commit/9a12ef3fccf3f4186db0f294f4ee1f02cf4d8db2), [`32d3583`](https://github.com/mastra-ai/mastra/commit/32d358332cb8ac2306b83b73cf3536e74dbd435e), [`7960688`](https://github.com/mastra-ai/mastra/commit/7960688828e04eaf3106e34f7758fa580257eef6), [`91ad69d`](https://github.com/mastra-ai/mastra/commit/91ad69d64994c89199b0c55399e64ed91c61df2f), [`8dc408d`](https://github.com/mastra-ai/mastra/commit/8dc408d34438f9e13297f792c11a5cfd6cf952e1), [`c92def1`](https://github.com/mastra-ai/mastra/commit/c92def10a13c822972c96f0a4ca6ffc1f4258aed), [`63041eb`](https://github.com/mastra-ai/mastra/commit/63041eb4c50b520a0a80e03d4cd6ea99f67715a0), [`c118318`](https://github.com/mastra-ai/mastra/commit/c1183181c9804303db4b511c2e2648f8b714712b), [`c5eaec5`](https://github.com/mastra-ai/mastra/commit/c5eaec5a860d80d0e3805e67db0414b87ac8cbed), [`fc07c64`](https://github.com/mastra-ai/mastra/commit/fc07c6465043e08e99193a6751a01c56ffc2e7a1), [`cced745`](https://github.com/mastra-ai/mastra/commit/cced745a056ec2225c5bc702e32d848847aa8b65), [`542dee2`](https://github.com/mastra-ai/mastra/commit/542dee254167f974ff8cbbbfc0ce10f9a2616a7b), [`3c19dce`](https://github.com/mastra-ai/mastra/commit/3c19dcef8e73062a80627a4927eae3ec11145afd), [`aca2869`](https://github.com/mastra-ai/mastra/commit/aca2869b2031982f3c4a2f52525c9be7cf123ef8), [`a58483c`](https://github.com/mastra-ai/mastra/commit/a58483cff1a9d41fce7c931843f48cb0ac450f64), [`a58483c`](https://github.com/mastra-ai/mastra/commit/a58483cff1a9d41fce7c931843f48cb0ac450f64), [`e6f8450`](https://github.com/mastra-ai/mastra/commit/e6f845074d478527026b18d85031b23353e1d0a4), [`895e9df`](https://github.com/mastra-ai/mastra/commit/895e9dfc17d6f34299eca64e317ded9e5f5e5ef8), [`e66b2ba`](https://github.com/mastra-ai/mastra/commit/e66b2ba100db63eaeab6e21e1ea34b113f2ec781), [`3e8727e`](https://github.com/mastra-ai/mastra/commit/3e8727e11ec1a5d733acedb5c872896394be18c1)]:
64
+ - @mastra/core@1.62.0
65
+
66
+ ## 0.9.0-alpha.2
67
+
68
+ ### Minor Changes
69
+
70
+ - Added computer-use support to `DaytonaSandbox`. Workspaces backed by Daytona can now take screenshots, control the mouse and keyboard, inspect the display, and open a noVNC viewer through the standard computer tools. ([#21701](https://github.com/mastra-ai/mastra/pull/21701))
71
+
72
+ ```typescript
73
+ const sandbox = new DaytonaSandbox();
74
+ await sandbox.start();
75
+
76
+ await sandbox.computer.leftClick(100, 200);
77
+ const screenshot = await sandbox.computer.screenshot();
78
+ ```
79
+
80
+ Desktop services start lazily on the first computer operation. Set `computerUse: false` to disable the capability or `computerUse: { autoStart: false }` to manage those services directly.
81
+
82
+ ### Patch Changes
83
+
84
+ - Updated dependencies [[`48ef1f1`](https://github.com/mastra-ai/mastra/commit/48ef1f1d24eedafbb07f64e659a81b52b67b8bf6), [`63796ba`](https://github.com/mastra-ai/mastra/commit/63796ba0fda60253be17535e68f6bbbf1e6ffa09), [`3c19dce`](https://github.com/mastra-ai/mastra/commit/3c19dcef8e73062a80627a4927eae3ec11145afd)]:
85
+ - @mastra/core@1.62.0-alpha.12
86
+
3
87
  ## 0.9.0-alpha.1
4
88
 
5
89
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -618,6 +618,8 @@ function validateMountPath(mountPath) {
618
618
  }
619
619
  /** Allowlist for marker filenames from ls output — e.g. "mount-abc123" */
620
620
  const SAFE_MARKER_NAME = /^mount-[a-z0-9]+$/;
621
+ /** Default port of the noVNC web viewer started by Daytona computer use. */
622
+ const DEFAULT_NOVNC_PORT = 6080;
621
623
  /** Patterns indicating the sandbox is dead/gone (@daytonaio/sdk@0.143.0). */
622
624
  const SANDBOX_DEAD_PATTERNS = [
623
625
  /sandbox is not running/i,
@@ -690,6 +692,9 @@ var DaytonaSandbox = class DaytonaSandbox extends _mastra_core_workspace.MastraS
690
692
  _createdAt = null;
691
693
  _workingDir = null;
692
694
  _isRetrying = false;
695
+ _computerUseStarted = null;
696
+ computerUseAutoStart;
697
+ noVncPort;
693
698
  timeout;
694
699
  language;
695
700
  resources;
@@ -742,6 +747,10 @@ var DaytonaSandbox = class DaytonaSandbox extends _mastra_core_workspace.MastraS
742
747
  ...options.target !== void 0 && { target: options.target }
743
748
  };
744
749
  this._constructorOptions = { ...options };
750
+ const computerUseOption = options.computerUse ?? true;
751
+ this.computerUseAutoStart = typeof computerUseOption === "object" ? computerUseOption.autoStart ?? true : true;
752
+ this.noVncPort = typeof computerUseOption === "object" ? computerUseOption.noVncPort ?? DEFAULT_NOVNC_PORT : DEFAULT_NOVNC_PORT;
753
+ if (computerUseOption !== false) this.computer = this.createComputer();
745
754
  }
746
755
  generateId() {
747
756
  return `daytona-sandbox-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -876,6 +885,7 @@ var DaytonaSandbox = class DaytonaSandbox extends _mastra_core_workspace.MastraS
876
885
  await this._daytona.stop(this._sandbox);
877
886
  } catch {}
878
887
  this._sandbox = null;
888
+ this._computerUseStarted = null;
879
889
  }
880
890
  /**
881
891
  * Destroy the Daytona sandbox and clean up all resources.
@@ -892,6 +902,7 @@ var DaytonaSandbox = class DaytonaSandbox extends _mastra_core_workspace.MastraS
892
902
  this._sandbox = null;
893
903
  this._daytonaSandboxId = void 0;
894
904
  this._daytona = null;
905
+ this._computerUseStarted = null;
895
906
  this.mounts?.clear();
896
907
  }
897
908
  /**
@@ -955,6 +966,96 @@ var DaytonaSandbox = class DaytonaSandbox extends _mastra_core_workspace.MastraS
955
966
  })));
956
967
  }
957
968
  /**
969
+ * Ensure the Daytona computer use processes (Xvfb, xfce4, x11vnc, noVNC)
970
+ * are running. Memoized per attached sandbox; the memo is reset when the
971
+ * sandbox stops, dies, or is destroyed so a fresh sandbox restarts them.
972
+ */
973
+ async ensureComputerUseStarted() {
974
+ if (!this.computerUseAutoStart) return;
975
+ if (!this._computerUseStarted) this._computerUseStarted = this.daytona.computerUse.start().then(() => void 0).catch((error) => {
976
+ this._computerUseStarted = null;
977
+ throw error;
978
+ });
979
+ return this._computerUseStarted;
980
+ }
981
+ /**
982
+ * Build the {@link SandboxComputer} capability backed by Daytona's
983
+ * computer use API (`sandbox.computerUse`).
984
+ *
985
+ * Every operation ensures the sandbox is running and the desktop processes
986
+ * are started, and retries once if the sandbox died (mirroring command
987
+ * execution behavior).
988
+ */
989
+ createComputer() {
990
+ const run = async (fn) => {
991
+ await this.ensureRunning();
992
+ return this.retryOnDead(async () => {
993
+ await this.ensureComputerUseStarted();
994
+ return fn(this.daytona.computerUse);
995
+ });
996
+ };
997
+ return {
998
+ screenshot: async () => {
999
+ const response = await run((computerUse) => computerUse.screenshot.takeFullScreen());
1000
+ if (!response.screenshot) throw new Error(`${LOG_PREFIX} Daytona returned an empty screenshot response`);
1001
+ return {
1002
+ data: new Uint8Array(Buffer.from(response.screenshot, "base64")),
1003
+ mediaType: "image/png"
1004
+ };
1005
+ },
1006
+ leftClick: async (x, y) => {
1007
+ await run((computerUse) => computerUse.mouse.click(x, y, "left"));
1008
+ },
1009
+ rightClick: async (x, y) => {
1010
+ await run((computerUse) => computerUse.mouse.click(x, y, "right"));
1011
+ },
1012
+ doubleClick: async (x, y) => {
1013
+ await run((computerUse) => computerUse.mouse.click(x, y, "left", true));
1014
+ },
1015
+ moveMouse: async (x, y) => {
1016
+ await run((computerUse) => computerUse.mouse.move(x, y));
1017
+ },
1018
+ drag: async (from, to) => {
1019
+ await run((computerUse) => computerUse.mouse.drag(from.x, from.y, to.x, to.y));
1020
+ },
1021
+ scroll: async (direction, amount) => {
1022
+ await run(async (computerUse) => {
1023
+ const position = await computerUse.mouse.getPosition();
1024
+ return computerUse.mouse.scroll(position.x ?? 0, position.y ?? 0, direction, amount);
1025
+ });
1026
+ },
1027
+ type: async (text) => {
1028
+ await run((computerUse) => computerUse.keyboard.type(text));
1029
+ },
1030
+ press: async (key) => {
1031
+ await run((computerUse) => Array.isArray(key) ? computerUse.keyboard.hotkey(key.join("+")) : computerUse.keyboard.press(key));
1032
+ },
1033
+ getScreenSize: async () => {
1034
+ const info = await run((computerUse) => computerUse.display.getInfo());
1035
+ const display = info.displays?.find((d) => d.isActive) ?? info.displays?.[0];
1036
+ if (!display || display.width === void 0 || display.height === void 0) throw new Error(`${LOG_PREFIX} Daytona did not return display information`);
1037
+ return {
1038
+ width: display.width,
1039
+ height: display.height
1040
+ };
1041
+ },
1042
+ getCursorPosition: async () => {
1043
+ const position = await run((computerUse) => computerUse.mouse.getPosition());
1044
+ return {
1045
+ x: position.x ?? 0,
1046
+ y: position.y ?? 0
1047
+ };
1048
+ },
1049
+ streamUrl: async () => {
1050
+ try {
1051
+ return (await run(() => this.daytona.getPreviewLink(this.noVncPort)))?.url ?? null;
1052
+ } catch {
1053
+ return null;
1054
+ }
1055
+ }
1056
+ };
1057
+ }
1058
+ /**
958
1059
  * Mount a filesystem at a path in the sandbox.
959
1060
  * Uses FUSE tools (s3fs, gcsfuse) to mount cloud storage.
960
1061
  */
@@ -1389,6 +1490,7 @@ var DaytonaSandbox = class DaytonaSandbox extends _mastra_core_workspace.MastraS
1389
1490
  */
1390
1491
  handleSandboxTimeout() {
1391
1492
  this._sandbox = null;
1493
+ this._computerUseStarted = null;
1392
1494
  if (this.mounts) {
1393
1495
  for (const [path, entry] of this.mounts.entries) if (entry.state === "mounted" || entry.state === "mounting") this.mounts.set(path, { state: "pending" });
1394
1496
  }