@mastra/platform-workspace 1.7.0 → 1.8.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/dist/factory-sandbox.d.ts +39 -0
- package/dist/factory-sandbox.d.ts.map +1 -0
- package/dist/index.cjs +170 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +171 -4
- package/dist/index.js.map +1 -1
- package/dist/sandbox.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PublicSchema } from '@mastra/core/schema';
|
|
2
|
+
import { FactorySandbox } from '@mastra/core/workspace';
|
|
3
|
+
import type { FactorySandboxBuilds, FactorySandboxContext } from '@mastra/core/workspace';
|
|
4
|
+
import type { PlatformRepoTemplateResolver } from './repo-template.js';
|
|
5
|
+
import { PlatformSandbox } from './sandbox.js';
|
|
6
|
+
import type { PlatformSandboxOptions } from './sandbox.js';
|
|
7
|
+
/** User-tunable settings of a platform factory sandbox. Every field is optional; absent means the provider default. */
|
|
8
|
+
export interface PlatformFactorySandboxSettings extends Record<string, unknown> {
|
|
9
|
+
/** vCPUs for the sandbox template. Part of the template identity. */
|
|
10
|
+
cpuCount?: number;
|
|
11
|
+
/** Memory in MB for the sandbox template. Part of the template identity. */
|
|
12
|
+
memoryMb?: number;
|
|
13
|
+
/** Minutes idle before the sandbox pauses. Runtime only. */
|
|
14
|
+
idleTimeoutMinutes?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface PlatformFactorySandboxOptions extends Omit<PlatformSandboxOptions, 'id' | 'sandboxId' | 'sessionId' | 'template'> {
|
|
17
|
+
/** Options for the environment's repo template. */
|
|
18
|
+
template?: {
|
|
19
|
+
/** Build-only environment, excluded from template identity and runtime sandboxes. */
|
|
20
|
+
buildEnv?: Record<string, string>;
|
|
21
|
+
};
|
|
22
|
+
/** Provider-side defaults used when a setting is unset. Never stored by factory. */
|
|
23
|
+
defaults?: Partial<PlatformFactorySandboxSettings>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The platform host contract for factory: every session sandbox is a
|
|
27
|
+
* {@link PlatformSandbox} whose template is {@link createRepoTemplate} over
|
|
28
|
+
* the session's repositories, sized by the factory's environment settings.
|
|
29
|
+
*/
|
|
30
|
+
export declare class PlatformFactorySandbox extends FactorySandbox<PlatformFactorySandboxSettings> {
|
|
31
|
+
#private;
|
|
32
|
+
readonly provider = "platform";
|
|
33
|
+
readonly settings: PublicSchema<PlatformFactorySandboxSettings>;
|
|
34
|
+
readonly builds: FactorySandboxBuilds<PlatformFactorySandboxSettings>;
|
|
35
|
+
constructor(options?: PlatformFactorySandboxOptions);
|
|
36
|
+
template(ctx: FactorySandboxContext, settings: PlatformFactorySandboxSettings): PlatformRepoTemplateResolver | undefined;
|
|
37
|
+
create(ctx: FactorySandboxContext, settings: PlatformFactorySandboxSettings): PlatformSandbox;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=factory-sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory-sandbox.d.ts","sourceRoot":"","sources":["../src/factory-sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAIV,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAG3D,uHAAuH;AACvH,MAAM,WAAW,8BAA+B,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC7E,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAwDD,MAAM,WAAW,6BAA8B,SAAQ,IAAI,CACzD,sBAAsB,EACtB,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAC9C;IACC,mDAAmD;IACnD,QAAQ,CAAC,EAAE;QACT,qFAAqF;QACrF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACnC,CAAC;IACF,oFAAoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;CACpD;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,cAAc,CAAC,8BAA8B,CAAC;;IACxF,QAAQ,CAAC,QAAQ,cAAc;IAC/B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,8BAA8B,CAAC,CAAC;IAehE,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC,8BAA8B,CAAC,CAGnE;IAEF,YAAY,OAAO,GAAE,6BAAkC,EAOtD;IAED,QAAQ,CACN,GAAG,EAAE,qBAAqB,EAC1B,QAAQ,EAAE,8BAA8B,GACvC,4BAA4B,GAAG,SAAS,CAQ1C;IAED,MAAM,CAAC,GAAG,EAAE,qBAAqB,EAAE,QAAQ,EAAE,8BAA8B,GAAG,eAAe,CAiB5F;CA4CF"}
|
package/dist/index.cjs
CHANGED
|
@@ -25,9 +25,9 @@ let buffer = require("buffer");
|
|
|
25
25
|
let path = require("path");
|
|
26
26
|
path = __toESM(path, 1);
|
|
27
27
|
let _mastra_core_workspace = require("@mastra/core/workspace");
|
|
28
|
+
let crypto = require("crypto");
|
|
28
29
|
let e2b = require("e2b");
|
|
29
30
|
let child_process = require("child_process");
|
|
30
|
-
let crypto = require("crypto");
|
|
31
31
|
let util = require("util");
|
|
32
32
|
//#region src/client.ts
|
|
33
33
|
const DEFAULT_PROXY_URL = "https://workspaces.mastra.ai";
|
|
@@ -1434,7 +1434,12 @@ var PlatformSandbox = class PlatformSandbox extends _mastra_core_workspace.Mastr
|
|
|
1434
1434
|
sessionId: this._client.sessionId,
|
|
1435
1435
|
mode,
|
|
1436
1436
|
totalMs: Date.now() - startedAt,
|
|
1437
|
-
requestMs
|
|
1437
|
+
requestMs,
|
|
1438
|
+
...mode === "provision" && this._templateDefinition ? {
|
|
1439
|
+
templateHash: templateHash(this._templateDefinition),
|
|
1440
|
+
templateBoot: this.templatePending ? "pending" : "exact",
|
|
1441
|
+
...this.templatePending ? { pendingTemplateId: this.templatePending.templateId } : {}
|
|
1442
|
+
} : {}
|
|
1438
1443
|
});
|
|
1439
1444
|
}
|
|
1440
1445
|
/**
|
|
@@ -2021,6 +2026,17 @@ var PlatformSandbox = class PlatformSandbox extends _mastra_core_workspace.Mastr
|
|
|
2021
2026
|
return defaultInstructions;
|
|
2022
2027
|
}
|
|
2023
2028
|
};
|
|
2029
|
+
/**
|
|
2030
|
+
* Diagnostic fingerprint of the serialized template a sandbox was provisioned
|
|
2031
|
+
* with: the same definition (repositories, pinned heads, setup commands,
|
|
2032
|
+
* resources) hashes the same on warm and cold boots. `family` is excluded, as
|
|
2033
|
+
* in the server's exact-content identity. Not the server's cache digest, which
|
|
2034
|
+
* also normalizes resources.
|
|
2035
|
+
*/
|
|
2036
|
+
function templateHash(definition) {
|
|
2037
|
+
const { family: _family, ...content } = definition;
|
|
2038
|
+
return (0, crypto.createHash)("sha256").update(JSON.stringify(content)).digest("hex").slice(0, 16);
|
|
2039
|
+
}
|
|
2024
2040
|
//#endregion
|
|
2025
2041
|
//#region ../../packages/_internals/workspace/dist/index.js
|
|
2026
2042
|
/** Directory, relative to the template's build cwd, that holds every marker below. */
|
|
@@ -2474,6 +2490,157 @@ const platformFilesystemProvider = {
|
|
|
2474
2490
|
createFilesystem: (config) => new PlatformFilesystem(config)
|
|
2475
2491
|
};
|
|
2476
2492
|
//#endregion
|
|
2493
|
+
//#region src/factory-sandbox.ts
|
|
2494
|
+
/** Applied when neither the environment setting nor a host default is set. */
|
|
2495
|
+
const DEFAULT_SETTINGS = {
|
|
2496
|
+
cpuCount: 2,
|
|
2497
|
+
memoryMb: 1024,
|
|
2498
|
+
idleTimeoutMinutes: 5
|
|
2499
|
+
};
|
|
2500
|
+
const SETTINGS_SCHEMA = {
|
|
2501
|
+
type: "object",
|
|
2502
|
+
properties: {
|
|
2503
|
+
cpuCount: {
|
|
2504
|
+
type: "integer",
|
|
2505
|
+
title: "CPU",
|
|
2506
|
+
description: "vCPUs for the sandbox template",
|
|
2507
|
+
default: DEFAULT_SETTINGS.cpuCount,
|
|
2508
|
+
minimum: 1,
|
|
2509
|
+
maximum: 64
|
|
2510
|
+
},
|
|
2511
|
+
memoryMb: {
|
|
2512
|
+
type: "integer",
|
|
2513
|
+
title: "Memory (MB)",
|
|
2514
|
+
description: "Memory in MB for the sandbox template",
|
|
2515
|
+
default: DEFAULT_SETTINGS.memoryMb,
|
|
2516
|
+
minimum: 512,
|
|
2517
|
+
maximum: 65536
|
|
2518
|
+
},
|
|
2519
|
+
idleTimeoutMinutes: {
|
|
2520
|
+
type: "integer",
|
|
2521
|
+
title: "Idle timeout (minutes)",
|
|
2522
|
+
description: "Minutes idle before the sandbox pauses",
|
|
2523
|
+
default: DEFAULT_SETTINGS.idleTimeoutMinutes,
|
|
2524
|
+
minimum: 1,
|
|
2525
|
+
maximum: 1440
|
|
2526
|
+
}
|
|
2527
|
+
},
|
|
2528
|
+
additionalProperties: false
|
|
2529
|
+
};
|
|
2530
|
+
/**
|
|
2531
|
+
* The settings schema with the provider's effective defaults as `default`:
|
|
2532
|
+
* the built-in values, overridden by the host's `idleTimeoutMinutes` option and
|
|
2533
|
+
* then its `defaults` option. The schema
|
|
2534
|
+
* is what clients show as placeholders, so it must match what the provider
|
|
2535
|
+
* applies when a setting is unset.
|
|
2536
|
+
*/
|
|
2537
|
+
function settingsSchema(defaults) {
|
|
2538
|
+
const effective = {
|
|
2539
|
+
...DEFAULT_SETTINGS,
|
|
2540
|
+
...defaults
|
|
2541
|
+
};
|
|
2542
|
+
const properties = Object.fromEntries(Object.entries(SETTINGS_SCHEMA.properties).map(([key, property]) => [key, {
|
|
2543
|
+
...property,
|
|
2544
|
+
default: effective[key]
|
|
2545
|
+
}]));
|
|
2546
|
+
return {
|
|
2547
|
+
...SETTINGS_SCHEMA,
|
|
2548
|
+
properties
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
/**
|
|
2552
|
+
* The platform host contract for factory: every session sandbox is a
|
|
2553
|
+
* {@link PlatformSandbox} whose template is {@link createRepoTemplate} over
|
|
2554
|
+
* the session's repositories, sized by the factory's environment settings.
|
|
2555
|
+
*/
|
|
2556
|
+
var PlatformFactorySandbox = class extends _mastra_core_workspace.FactorySandbox {
|
|
2557
|
+
provider = "platform";
|
|
2558
|
+
settings;
|
|
2559
|
+
#options;
|
|
2560
|
+
/**
|
|
2561
|
+
* Builders by template id from this process's `builds.start` calls. Platform
|
|
2562
|
+
* has no build status endpoint; re-calling the same builder's idempotent
|
|
2563
|
+
* `build()` is the status poll. After a restart earlier builds read as
|
|
2564
|
+
* `unknown`.
|
|
2565
|
+
*
|
|
2566
|
+
* TODO: once the platform API exposes build status and build history, read
|
|
2567
|
+
* `get` from the API instead of this in-memory cache and add `builds.list`.
|
|
2568
|
+
*/
|
|
2569
|
+
#builders = /* @__PURE__ */ new Map();
|
|
2570
|
+
builds = {
|
|
2571
|
+
start: (ctx, settings) => this.#startBuild(ctx, settings),
|
|
2572
|
+
get: (ctx, settings, buildId) => this.#getBuild(ctx, settings, buildId)
|
|
2573
|
+
};
|
|
2574
|
+
constructor(options = {}) {
|
|
2575
|
+
super();
|
|
2576
|
+
this.#options = options;
|
|
2577
|
+
this.settings = settingsSchema({
|
|
2578
|
+
...options.idleTimeoutMinutes !== void 0 ? { idleTimeoutMinutes: options.idleTimeoutMinutes } : {},
|
|
2579
|
+
...options.defaults
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
template(ctx, settings) {
|
|
2583
|
+
const { defaults, template } = this.#options;
|
|
2584
|
+
return createRepoTemplate({
|
|
2585
|
+
...ctx,
|
|
2586
|
+
...template?.buildEnv ? { buildEnv: template.buildEnv } : {},
|
|
2587
|
+
cpuCount: settings.cpuCount ?? defaults?.cpuCount ?? DEFAULT_SETTINGS.cpuCount,
|
|
2588
|
+
memoryMB: settings.memoryMb ?? defaults?.memoryMb ?? DEFAULT_SETTINGS.memoryMb
|
|
2589
|
+
});
|
|
2590
|
+
}
|
|
2591
|
+
create(ctx, settings) {
|
|
2592
|
+
const { defaults, template: _template, ...options } = this.#options;
|
|
2593
|
+
return new PlatformSandbox({
|
|
2594
|
+
...options,
|
|
2595
|
+
id: ctx.sessionId,
|
|
2596
|
+
sessionId: ctx.sessionId,
|
|
2597
|
+
sandboxId: ctx.sandboxId,
|
|
2598
|
+
template: this.template(ctx, settings),
|
|
2599
|
+
...ctx.workingDirectory ? { workingDirectory: ctx.workingDirectory } : {},
|
|
2600
|
+
idleTimeoutMinutes: settings.idleTimeoutMinutes ?? defaults?.idleTimeoutMinutes ?? options.idleTimeoutMinutes ?? DEFAULT_SETTINGS.idleTimeoutMinutes
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2603
|
+
async #startBuild(ctx, settings) {
|
|
2604
|
+
const builder = await this.#resolveBuilder(ctx, settings);
|
|
2605
|
+
const result = await builder.build(this.#buildOptions());
|
|
2606
|
+
this.#builders.set(result.templateId, builder);
|
|
2607
|
+
return {
|
|
2608
|
+
buildId: result.templateId,
|
|
2609
|
+
templateId: result.templateId,
|
|
2610
|
+
status: mapStatus(result.status)
|
|
2611
|
+
};
|
|
2612
|
+
}
|
|
2613
|
+
async #getBuild(_ctx, _settings, buildId) {
|
|
2614
|
+
const builder = this.#builders.get(buildId);
|
|
2615
|
+
if (!builder) return {
|
|
2616
|
+
buildId,
|
|
2617
|
+
status: "unknown",
|
|
2618
|
+
error: `Build ${buildId} was not started by this process; its status cannot be read.`
|
|
2619
|
+
};
|
|
2620
|
+
return toBuild(await builder.build(this.#buildOptions()));
|
|
2621
|
+
}
|
|
2622
|
+
async #resolveBuilder(ctx, settings) {
|
|
2623
|
+
const builder = await this.template(ctx, settings)?.();
|
|
2624
|
+
if (!builder) throw new Error("PlatformFactorySandbox.builds: the session context yields no template to build");
|
|
2625
|
+
return builder;
|
|
2626
|
+
}
|
|
2627
|
+
#buildOptions() {
|
|
2628
|
+
const { defaults: _defaults, template: _template, env: _env, ...options } = this.#options;
|
|
2629
|
+
return options;
|
|
2630
|
+
}
|
|
2631
|
+
};
|
|
2632
|
+
function mapStatus(status) {
|
|
2633
|
+
return status;
|
|
2634
|
+
}
|
|
2635
|
+
function toBuild(result) {
|
|
2636
|
+
return {
|
|
2637
|
+
buildId: result.templateId,
|
|
2638
|
+
templateId: result.templateId,
|
|
2639
|
+
status: mapStatus(result.status),
|
|
2640
|
+
...result.error ? { error: result.error } : {}
|
|
2641
|
+
};
|
|
2642
|
+
}
|
|
2643
|
+
//#endregion
|
|
2477
2644
|
//#region src/address-registry.ts
|
|
2478
2645
|
/**
|
|
2479
2646
|
* Concrete in-process {@link SandboxAddressRegistry}. Backed by a `Map`; no
|
|
@@ -2510,6 +2677,7 @@ var InProcessSandboxAddressRegistry = class {
|
|
|
2510
2677
|
exports.InProcessSandboxAddressRegistry = InProcessSandboxAddressRegistry;
|
|
2511
2678
|
exports.PlatformApiError = PlatformApiError;
|
|
2512
2679
|
exports.PlatformClient = PlatformClient;
|
|
2680
|
+
exports.PlatformFactorySandbox = PlatformFactorySandbox;
|
|
2513
2681
|
exports.PlatformFilesystem = PlatformFilesystem;
|
|
2514
2682
|
exports.PlatformSandbox = PlatformSandbox;
|
|
2515
2683
|
exports.PrivateNetExecHttpError = PrivateNetExecHttpError;
|