@dbx-tools/appkit-mastra 0.9.140 → 0.9.141

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/src/agents.ts CHANGED
@@ -45,10 +45,13 @@ import { createCodeMode, createTool } from "@mastra/core/tools";
45
45
  import type { Workspace } from "@mastra/core/workspace";
46
46
  import { createSkillTools, createWorkspaceTools } from "@mastra/core/workspace";
47
47
  import type { PgVectorConfig, PostgresStoreConfig } from "@mastra/pg";
48
- import { QuickJsCodeModeTransport } from "@mastra/quickjs";
49
48
 
50
49
  import { buildRenderDataTool } from "./chart.ts";
51
- import type { MastraPluginConfig } from "./config.ts";
50
+ import type {
51
+ MastraCodeModeConfig,
52
+ MastraCodeModeTransport,
53
+ MastraPluginConfig,
54
+ } from "./config.ts";
52
55
  import { buildGenieToolkitProvider, resolveGenieSpaces } from "./genie.ts";
53
56
  import { withRequestMemoryScope, type MemoryBuilder } from "./memory.ts";
54
57
  import { buildModel, RESPONSES_PROVIDER_OPTIONS } from "./model.ts";
@@ -64,7 +67,28 @@ import {
64
67
  } from "./workspaces.ts";
65
68
 
66
69
  const codeModeLogger = log.logger("mastra/code-mode");
67
- let resolvedCodeModeTransport: Promise<CodeModeTransport> | undefined;
70
+ const ISOLATED_VM_PACKAGE = "@mastra/isolated-vm";
71
+ const QUICKJS_PACKAGE = "@mastra/quickjs";
72
+ let isolatedVmDependency: Promise<typeof import("@mastra/isolated-vm")> | undefined;
73
+ let quickJsDependency: Promise<typeof import("@mastra/quickjs")> | undefined;
74
+
75
+ type NormalizedCodeModeConfig = MastraCodeModeConfig;
76
+
77
+ interface ResolvedCodeModeConfig {
78
+ readonly id?: string;
79
+ readonly timeout?: number;
80
+ readonly provider: Exclude<MastraCodeModeTransport, "auto">;
81
+ readonly transport: CodeModeTransport;
82
+ }
83
+
84
+ type CodeModeFailureCategory =
85
+ "unsupported-runtime" | "dependency-unavailable" | "construction-failed";
86
+
87
+ interface CodeModeFailure {
88
+ readonly category: CodeModeFailureCategory;
89
+ readonly error?: Error;
90
+ readonly provider: Exclude<MastraCodeModeTransport, "auto">;
91
+ }
68
92
 
69
93
  /** Return whether this boot environment matches isolated-vm's supported app shape. */
70
94
  function supportsIsolatedVmTransport(): boolean {
@@ -77,6 +101,36 @@ function supportsIsolatedVmTransport(): boolean {
77
101
  return [...process.execArgv, ...nodeOptions].includes("--no-node-snapshot");
78
102
  }
79
103
 
104
+ /** Return whether the current runtime satisfies QuickJS' published engine floor. */
105
+ function supportsQuickJsTransport(): boolean {
106
+ if (process.versions.bun) return true;
107
+ if (process.release.name !== "node") return false;
108
+ const [majorText, minorText] = process.versions.node.split(".");
109
+ const major = Number.parseInt(majorText ?? "", 10);
110
+ const minor = Number.parseInt(minorText ?? "", 10);
111
+ return (
112
+ Number.isFinite(major) &&
113
+ Number.isFinite(minor) &&
114
+ (major > 20 || (major === 20 && minor >= 19))
115
+ );
116
+ }
117
+
118
+ /** Import the optional native transport at most once for this process. */
119
+ function loadIsolatedVmDependency(): Promise<typeof import("@mastra/isolated-vm")> {
120
+ isolatedVmDependency ??= import(/* @vite-ignore */ ISOLATED_VM_PACKAGE) as Promise<
121
+ typeof import("@mastra/isolated-vm")
122
+ >;
123
+ return isolatedVmDependency;
124
+ }
125
+
126
+ /** Import the optional portable transport at most once for this process. */
127
+ function loadQuickJsDependency(): Promise<typeof import("@mastra/quickjs")> {
128
+ quickJsDependency ??= import(/* @vite-ignore */ QUICKJS_PACKAGE) as Promise<
129
+ typeof import("@mastra/quickjs")
130
+ >;
131
+ return quickJsDependency;
132
+ }
133
+
80
134
  /**
81
135
  * Tool record accepted by every Mastra `Agent.tools` field and by the
82
136
  * `tools(plugins)` callback on {@link MastraAgentDefinition}.
@@ -607,26 +661,125 @@ function appendInstructionBlock(instructions: AgentInstructions, block: string):
607
661
  return [instructions, { role: "system", content: block }] as AgentInstructions;
608
662
  }
609
663
 
610
- /** Resolve one native Code Mode transport during plugin startup. */
611
- function codeModeTransport(): Promise<CodeModeTransport> {
612
- resolvedCodeModeTransport ??= (async () => {
664
+ /** Normalize the public Code Mode shorthand into one startup configuration. */
665
+ function normalizeCodeModeConfig(
666
+ codeMode: MastraPluginConfig["codeMode"],
667
+ ): NormalizedCodeModeConfig | undefined {
668
+ if (codeMode === undefined || codeMode === false) return undefined;
669
+ return typeof codeMode === "string" ? { transport: codeMode } : codeMode;
670
+ }
671
+
672
+ /** Try one optional Code Mode transport without applying fallback policy. */
673
+ async function tryCodeModeTransport(
674
+ provider: Exclude<MastraCodeModeTransport, "auto">,
675
+ ): Promise<ResolvedCodeModeConfig | CodeModeFailure> {
676
+ if (provider === "isolated-vm") {
613
677
  if (!supportsIsolatedVmTransport()) {
614
- codeModeLogger.info("transport selected", { provider: "quickjs" });
615
- return new QuickJsCodeModeTransport();
678
+ return { category: "unsupported-runtime", provider };
616
679
  }
680
+ let module: typeof import("@mastra/isolated-vm");
617
681
  try {
618
- const { IsolatedVmCodeModeTransport } = await import("@mastra/isolated-vm");
619
- const transport = new IsolatedVmCodeModeTransport();
620
- codeModeLogger.info("transport selected", { provider: "isolated-vm" });
621
- return transport;
682
+ module = await loadIsolatedVmDependency();
622
683
  } catch (caught) {
623
- codeModeLogger.warn("isolated-vm unavailable; using QuickJS", {
684
+ return {
685
+ category: "dependency-unavailable",
624
686
  error: errorUtils.toError(caught),
625
- });
626
- return new QuickJsCodeModeTransport();
687
+ provider,
688
+ };
689
+ }
690
+ try {
691
+ return { provider, transport: new module.IsolatedVmCodeModeTransport() };
692
+ } catch (caught) {
693
+ return {
694
+ category: "construction-failed",
695
+ error: errorUtils.toError(caught),
696
+ provider,
697
+ };
627
698
  }
628
- })();
629
- return resolvedCodeModeTransport;
699
+ }
700
+
701
+ if (!supportsQuickJsTransport()) {
702
+ return { category: "unsupported-runtime", provider };
703
+ }
704
+ let module: typeof import("@mastra/quickjs");
705
+ try {
706
+ module = await loadQuickJsDependency();
707
+ } catch (caught) {
708
+ return {
709
+ category: "dependency-unavailable",
710
+ error: errorUtils.toError(caught),
711
+ provider,
712
+ };
713
+ }
714
+ try {
715
+ return { provider, transport: new module.QuickJsCodeModeTransport() };
716
+ } catch (caught) {
717
+ return {
718
+ category: "construction-failed",
719
+ error: errorUtils.toError(caught),
720
+ provider,
721
+ };
722
+ }
723
+ }
724
+
725
+ function isCodeModeFailure(
726
+ result: ResolvedCodeModeConfig | CodeModeFailure,
727
+ ): result is CodeModeFailure {
728
+ return "category" in result;
729
+ }
730
+
731
+ /** Produce the actionable startup error for an explicitly required transport. */
732
+ function requiredCodeModeError(failure: CodeModeFailure): ConfigurationError {
733
+ const runtime = process.versions.bun
734
+ ? `Bun ${process.versions.bun}`
735
+ : `${process.release.name} ${process.versions.node}`;
736
+ const install = `bun add ${failure.provider === "isolated-vm" ? ISOLATED_VM_PACKAGE : QUICKJS_PACKAGE}`;
737
+ const reason =
738
+ failure.category === "unsupported-runtime"
739
+ ? `is not supported by ${runtime}`
740
+ : failure.category === "dependency-unavailable"
741
+ ? "could not be loaded"
742
+ : "could not be initialized";
743
+ return new ConfigurationError(
744
+ `mastra: codeMode transport "${failure.provider}" ${reason}. Install the optional transport with \`${install}\` and use a supported runtime.`,
745
+ failure.error ? { cause: failure.error } : undefined,
746
+ );
747
+ }
748
+
749
+ /** Resolve the configured optional transport once during plugin startup. */
750
+ async function resolveCodeModeConfig(
751
+ codeMode: MastraPluginConfig["codeMode"],
752
+ ): Promise<ResolvedCodeModeConfig | undefined> {
753
+ const config = normalizeCodeModeConfig(codeMode);
754
+ if (!config) return undefined;
755
+
756
+ const providers: readonly Exclude<MastraCodeModeTransport, "auto">[] =
757
+ config.transport === "auto" ? ["isolated-vm", "quickjs"] : [config.transport];
758
+ const failures: CodeModeFailure[] = [];
759
+ for (const provider of providers) {
760
+ const result = await tryCodeModeTransport(provider);
761
+ if (!isCodeModeFailure(result)) {
762
+ codeModeLogger.info("transport selected", { provider });
763
+ return { ...result, id: config.id, timeout: config.timeout };
764
+ }
765
+ failures.push(result);
766
+ if (config.transport !== "auto") throw requiredCodeModeError(result);
767
+ const fields = {
768
+ category: result.category,
769
+ provider,
770
+ ...(result.error ? { error: result.error } : {}),
771
+ };
772
+ if (result.category === "unsupported-runtime") {
773
+ codeModeLogger.info("automatic transport unsupported", fields);
774
+ } else {
775
+ codeModeLogger.warn("automatic transport unavailable", fields);
776
+ }
777
+ }
778
+
779
+ codeModeLogger.info("automatic Code Mode disabled", {
780
+ reasons: failures.map(({ category, provider }) => ({ category, provider })),
781
+ });
782
+ return undefined;
630
783
  }
631
784
 
632
785
  type CodeModeResolver<TRequestContext extends Record<string, unknown> | unknown = unknown> = (
@@ -640,12 +793,11 @@ type CodeModeResolver<TRequestContext extends Record<string, unknown> | unknown
640
793
 
641
794
  /** Build request-scoped native Code Mode over all executable context tools. */
642
795
  async function buildCodeMode<TRequestContext extends Record<string, unknown> | unknown>(
643
- config: MastraPluginConfig,
796
+ config: ResolvedCodeModeConfig,
644
797
  tools: MastraTools,
645
798
  workspace: Workspace | undefined,
646
799
  requestContext: RequestContext<TRequestContext>,
647
800
  ): Promise<ReturnType<typeof createCodeMode> | undefined> {
648
- if (config.codeMode === false) return undefined;
649
801
  const workspaceTools = workspace
650
802
  ? await createWorkspaceTools(workspace, { requestContext, workspace })
651
803
  : {};
@@ -660,10 +812,13 @@ async function buildCodeMode<TRequestContext extends Record<string, unknown> | u
660
812
  ),
661
813
  ) as ToolsInput;
662
814
  if (Object.keys(executableTools).length === 0) return undefined;
663
- const options = typeof config.codeMode === "object" ? config.codeMode : {};
664
815
  const codeMode = createCodeMode(
665
- { tools: executableTools, ...options },
666
- await codeModeTransport(),
816
+ {
817
+ tools: executableTools,
818
+ ...(config.id !== undefined ? { id: config.id } : {}),
819
+ ...(config.timeout !== undefined ? { timeout: config.timeout } : {}),
820
+ },
821
+ config.transport,
667
822
  );
668
823
  if (!("mastra_workspace_read_file" in workspaceTools)) return codeMode;
669
824
  return {
@@ -674,11 +829,11 @@ async function buildCodeMode<TRequestContext extends Record<string, unknown> | u
674
829
 
675
830
  /** Resolve Code Mode lazily so workspace and dynamic tool policy follow each request. */
676
831
  function codeModeResolver<TRequestContext extends Record<string, unknown> | unknown>(
677
- config: MastraPluginConfig,
832
+ config: ResolvedCodeModeConfig | undefined,
678
833
  tools: MastraTools,
679
834
  workspace: Workspace | undefined,
680
835
  ): CodeModeResolver<TRequestContext> | undefined {
681
- if (config.codeMode === false) return undefined;
836
+ if (!config) return undefined;
682
837
  return ({ requestContext }) => buildCodeMode(config, tools, workspace, requestContext);
683
838
  }
684
839
 
@@ -731,6 +886,7 @@ export async function buildAgents(opts: {
731
886
  standardSkills = [],
732
887
  excludedWorkspaceSkillNames = [],
733
888
  } = opts;
889
+ const codeModeConfig = await resolveCodeModeConfig(config.codeMode);
734
890
  const definitions = resolveDefinitions(config);
735
891
  const ids = Object.keys(definitions);
736
892
  const defaultAgentId = config.defaultAgent ?? ids[0] ?? FALLBACK_AGENT_ID;
@@ -798,7 +954,7 @@ export async function buildAgents(opts: {
798
954
  const gated = approvalGatedToolIds(tools);
799
955
  if (gated.length > 0) approvalGatedByAgent.push({ agentId: id, toolIds: gated });
800
956
  const memory = memoryBuilder?.forAgent(id, def);
801
- const resolveCodeMode = codeModeResolver(config, tools, workspace);
957
+ const resolveCodeMode = codeModeResolver(codeModeConfig, tools, workspace);
802
958
  const agent = new Agent({
803
959
  id,
804
960
  name: def.name ?? id,
package/src/config.ts CHANGED
@@ -166,8 +166,13 @@ export interface MastraWorkspaceSkillsConfig {
166
166
  ttlMs?: number;
167
167
  }
168
168
 
169
+ /** Native Mastra Code Mode execution transport. */
170
+ export type MastraCodeModeTransport = "auto" | "isolated-vm" | "quickjs";
171
+
169
172
  /** Native Mastra Code Mode settings for sandboxed multi-tool orchestration. */
170
173
  export interface MastraCodeModeConfig {
174
+ /** Code Mode execution transport. */
175
+ transport: MastraCodeModeTransport;
171
176
  /** Generated orchestration tool id. Defaults to `execute_typescript`. */
172
177
  id?: string;
173
178
  /** Maximum orchestration program runtime in milliseconds. Defaults to 30 seconds. */
@@ -237,14 +242,14 @@ export interface MastraPluginConfig extends BasePluginConfig {
237
242
  memory?: boolean | MastraMemoryConfig;
238
243
  /**
239
244
  * Expose executable tools available to the current request through native
240
- * Mastra Code Mode. Defaults on whenever the request has executable tools.
241
- * The plugin selects Mastra's isolated-vm transport once during startup and
242
- * falls back to Mastra QuickJS when the native transport is unavailable.
243
- * These transports do not execute through the workspace command sandbox;
244
- * SSH is used only when an exposed SSH-backed tool is called. Set `false` to
245
- * opt out.
245
+ * Mastra Code Mode. Defaults to `false`. `auto` selects an installed,
246
+ * runtime-supported optional transport during startup and leaves Code Mode
247
+ * disabled when none is available. Explicit transport values fail startup
248
+ * when their optional dependency or runtime support is unavailable. These
249
+ * transports do not execute through the workspace command sandbox; SSH is
250
+ * used only when an exposed SSH-backed tool is called.
246
251
  */
247
- codeMode?: boolean | MastraCodeModeConfig;
252
+ codeMode?: false | MastraCodeModeTransport | MastraCodeModeConfig;
248
253
  /**
249
254
  * Sandbox for auto-created agent workspaces. Defaults to Monty. `false`
250
255
  * disables command execution; `true` or `"monty"` selects Monty; an explicit
@@ -700,9 +705,10 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
700
705
  "PgVector store for Mastra semantic recall. `true` captures the `lakebase` plugin's existing service-principal pool; an object opens a separately configured store. Auto-enabled when the `lakebase` plugin is registered.",
701
706
  },
702
707
  codeMode: {
703
- type: ["boolean", "object"],
708
+ type: ["boolean", "string", "object"],
709
+ default: false,
704
710
  description:
705
- "Expose all executable tools available to the current request through native Mastra Code Mode for TypeScript batching, aggregation, and arithmetic. The plugin uses Mastra isolated-vm with the existing QuickJS fallback; neither transport runs through the workspace command sandbox, so SSH is used only when an SSH-backed tool is called. False disables it.",
711
+ 'Expose executable request tools through native Mastra Code Mode for TypeScript batching, aggregation, and arithmetic. Defaults to false. Use "auto" to select an installed supported optional transport or stay disabled, "isolated-vm" to require the native transport, "quickjs" to require the portable transport, or an object with transport plus id and timeout. Neither transport runs through the workspace command sandbox.',
706
712
  },
707
713
  sandbox: {
708
714
  type: ["boolean", "string", "object"],