@mastra/platform-workspace 1.5.0 → 1.6.0-alpha.1
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/README.md +17 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/index.cjs +49 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +49 -8
- package/dist/index.js.map +1 -1
- package/dist/repo-template.d.ts +4 -2
- package/dist/repo-template.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -8,6 +8,23 @@ Mastra Platform workspace provider. It gives agents environment-scoped sandbox e
|
|
|
8
8
|
npm install @mastra/platform-workspace
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
All options can be passed to the constructor or read from environment variables:
|
|
14
|
+
|
|
15
|
+
| Option | Env var | Required |
|
|
16
|
+
| ----------------- | ------------------------------ | ------------------------------- |
|
|
17
|
+
| `accessToken` | `MASTRA_PLATFORM_ACCESS_TOKEN` | Yes |
|
|
18
|
+
| `projectId` | `MASTRA_PROJECT_ID` | Yes |
|
|
19
|
+
| `environmentId` | `MASTRA_ENVIRONMENT_ID` | Yes (sandbox) |
|
|
20
|
+
| `actingUserId` | — | No (sandbox) |
|
|
21
|
+
| `sandboxProvider` | `SANDBOX_PROVIDER` | No (sandbox, defaults to `e2b`) |
|
|
22
|
+
| `bucketName` | `MASTRA_PLATFORM_BUCKET_NAME` | Yes (filesystem) |
|
|
23
|
+
|
|
24
|
+
The proxy URL defaults to `https://workspaces.mastra.ai`. Set `MASTRA_PLATFORM_REGION` to `us` or `eu` (case-insensitive) to route to the regional replica at `https://workspaces.us.mastra.ai` or `https://workspaces.eu.mastra.ai`. An explicit `MASTRA_WORKSPACE_PROXY_URL` (useful for staging) overrides both.
|
|
25
|
+
|
|
26
|
+
Requests to the proxy are authenticated with `Authorization: Bearer <accessToken>`. For sandbox requests authenticated with a project access token, set `actingUserId` to the stable opaque user subject from your authentication system. It is sent as `x-acting-user-id` for token partitioning and attribution; it is not an authorization claim.
|
|
27
|
+
|
|
11
28
|
## Usage
|
|
12
29
|
|
|
13
30
|
```typescript
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC/D;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC/D;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,KAAK,CAAC;AA6BhD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7E;AAUD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,qBAAqB;IAKjE,WAAW;IACX,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,eAAe;IACf,SAAS;IACT,QAAQ;IACR,KAAK;EAER;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;CACd;AAkBD,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2HAA2H;IAC3H,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,yGAAyG;IACzG,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1C,YAAY,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EASvC;CACF;AAED,qBAAa,cAAc;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,qFAAqF;IACrF,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC;IAE7B,YAAY,OAAO,EAAE,qBAAqB,EAUzC;IAEK,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEnF;IAEK,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE3F;YAEa,aAAa;CA2B5B"}
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,23 @@ let util = require("util");
|
|
|
31
31
|
let crypto = require("crypto");
|
|
32
32
|
//#region src/client.ts
|
|
33
33
|
const DEFAULT_PROXY_URL = "https://workspaces.mastra.ai";
|
|
34
|
+
const REGIONAL_PROXY_URLS = {
|
|
35
|
+
us: "https://workspaces.us.mastra.ai",
|
|
36
|
+
eu: "https://workspaces.eu.mastra.ai"
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Resolves the workspace proxy URL, preferring an explicit
|
|
40
|
+
* `MASTRA_WORKSPACE_PROXY_URL` override, then a regional replica selected by
|
|
41
|
+
* `MASTRA_PLATFORM_REGION` (case-insensitive `us` or `eu`), then the global
|
|
42
|
+
* default. Unknown region values fall through to the global default.
|
|
43
|
+
*/
|
|
44
|
+
function resolveProxyUrl() {
|
|
45
|
+
const override = process.env.MASTRA_WORKSPACE_PROXY_URL?.trim();
|
|
46
|
+
if (override) return override;
|
|
47
|
+
const region = process.env.MASTRA_PLATFORM_REGION?.trim().toLowerCase();
|
|
48
|
+
if (region === "us" || region === "eu") return REGIONAL_PROXY_URLS[region];
|
|
49
|
+
return DEFAULT_PROXY_URL;
|
|
50
|
+
}
|
|
34
51
|
/**
|
|
35
52
|
* Default per-request timeout for calls to the workspace proxy. Applied only
|
|
36
53
|
* when the caller doesn't already pass an `AbortSignal`. Long-running routes
|
|
@@ -53,7 +70,7 @@ function resolvePlatformOptions(options) {
|
|
|
53
70
|
accessToken: requireOption(options.accessToken ?? process.env.MASTRA_PLATFORM_ACCESS_TOKEN, "accessToken"),
|
|
54
71
|
projectId: requireOption(options.projectId ?? process.env.MASTRA_PROJECT_ID, "projectId"),
|
|
55
72
|
actingUserId: options.actingUserId?.trim() || void 0,
|
|
56
|
-
proxyUrl: (
|
|
73
|
+
proxyUrl: resolveProxyUrl().replace(/\/$/, ""),
|
|
57
74
|
sandboxProvider: resolveSandboxProvider(configuredSandboxProvider),
|
|
58
75
|
sessionId: options.sessionId,
|
|
59
76
|
threadId: options.threadId,
|
|
@@ -2015,6 +2032,14 @@ const BUILD_TOKEN_ENV = "MASTRA_REPOSITORY_ACCESS_TOKEN";
|
|
|
2015
2032
|
const CLONE_URL_ALLOWED_CHARS = /^[a-z0-9:/._-]+$/i;
|
|
2016
2033
|
const CLONE_URL_HOST_PATTERN = /^[a-z0-9.-]+$/i;
|
|
2017
2034
|
const CLONE_URL_SEGMENT_PATTERN = /^[\w.-]+$/;
|
|
2035
|
+
/** Last default-branch head resolved per clone URL, shared across resolvers in this process. */
|
|
2036
|
+
const lastKnownHeads = /* @__PURE__ */ new Map();
|
|
2037
|
+
const MAX_LAST_KNOWN_HEADS = 1e3;
|
|
2038
|
+
function rememberHead(cloneUrl, sha) {
|
|
2039
|
+
lastKnownHeads.delete(cloneUrl);
|
|
2040
|
+
lastKnownHeads.set(cloneUrl, sha);
|
|
2041
|
+
if (lastKnownHeads.size > MAX_LAST_KNOWN_HEADS) lastKnownHeads.delete(lastKnownHeads.keys().next().value);
|
|
2042
|
+
}
|
|
2018
2043
|
/**
|
|
2019
2044
|
* Create a lazy repository template definition for PlatformSandbox, mirroring
|
|
2020
2045
|
* `@mastra/e2b`'s `createRepoTemplate`: pass the sandbox context through and a
|
|
@@ -2025,8 +2050,10 @@ const CLONE_URL_SEGMENT_PATTERN = /^[\w.-]+$/;
|
|
|
2025
2050
|
* what gets cloned and what the template is identified by can't drift — and
|
|
2026
2051
|
* pins repositories to their current default-branch commit. Private repository
|
|
2027
2052
|
* credentials are used for head resolution and sent to the provider as
|
|
2028
|
-
* transient build envs; they never enter the serialized definition.
|
|
2029
|
-
*
|
|
2053
|
+
* transient build envs; they never enter the serialized definition. A failed
|
|
2054
|
+
* head lookup reuses the last head resolved for the same clone URL in this
|
|
2055
|
+
* process. If the repository cannot be resolved, or no head has been resolved
|
|
2056
|
+
* yet, the resolver keeps `cpuCount` and
|
|
2030
2057
|
* `memoryMB` in a resources-only template so the sandbox still boots at the
|
|
2031
2058
|
* requested size, and the caller's runtime setup materializes the checkout.
|
|
2032
2059
|
*/
|
|
@@ -2057,16 +2084,30 @@ function createRepoTemplate(options) {
|
|
|
2057
2084
|
}
|
|
2058
2085
|
const token = access.authorization?.token;
|
|
2059
2086
|
let headError;
|
|
2060
|
-
const
|
|
2087
|
+
const resolved = await (token ? resolveHead(cloneUrl, token) : resolveHead(cloneUrl)).catch((error) => {
|
|
2061
2088
|
headError = error;
|
|
2062
2089
|
});
|
|
2063
|
-
|
|
2064
|
-
|
|
2090
|
+
let sha;
|
|
2091
|
+
if (resolved && SHA_PATTERN.test(resolved)) {
|
|
2092
|
+
sha = resolved;
|
|
2093
|
+
rememberHead(cloneUrl, sha);
|
|
2094
|
+
} else {
|
|
2095
|
+
const lastKnown = lastKnownHeads.get(cloneUrl);
|
|
2096
|
+
if (!lastKnown) {
|
|
2097
|
+
console.warn("[platform-workspace] repo template skipped: could not resolve default-branch head", {
|
|
2098
|
+
cloneUrl,
|
|
2099
|
+
sha: resolved,
|
|
2100
|
+
error: redactSecrets(headError)
|
|
2101
|
+
});
|
|
2102
|
+
return resourcesOnly();
|
|
2103
|
+
}
|
|
2104
|
+
console.warn("[platform-workspace] repo template pinned to the last known default-branch head", {
|
|
2065
2105
|
cloneUrl,
|
|
2066
|
-
sha,
|
|
2106
|
+
sha: lastKnown,
|
|
2107
|
+
resolved,
|
|
2067
2108
|
error: redactSecrets(headError)
|
|
2068
2109
|
});
|
|
2069
|
-
|
|
2110
|
+
sha = lastKnown;
|
|
2070
2111
|
}
|
|
2071
2112
|
const workingDirectory = options.workingDirectory === void 0 ? void 0 : trimTrailingSlashes(assertWorkingDirectory(options.workingDirectory));
|
|
2072
2113
|
const repoDir = repoDirName(cloneUrl);
|