@mastra/editor 0.11.0-alpha.2 → 0.11.0-alpha.4

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/index.cjs CHANGED
@@ -146,7 +146,7 @@ var init_agent_builder = __esm({
146
146
  // src/ee/agent-builder-agent.ts
147
147
  function createBuilderAgent(args) {
148
148
  const memory = new import_memory2.Memory();
149
- return new import_agent3.Agent({
149
+ const config = {
150
150
  instructions: `You are the Agent Builder.
151
151
 
152
152
  Your job: turn a non-technical user's plain-language request into a fully configured, production-quality agent in a single turn.
@@ -167,6 +167,10 @@ Examples of communication style:
167
167
  - Bad: "Agent created with weatherTool and recipeWorkflow attached."
168
168
  - Good: "Your agent can check the weather and suggest recipes that match the day's conditions."
169
169
 
170
+ # Form snapshot
171
+
172
+ A "Current agent configuration (authoritative)" block is injected into your context every turn. It lists every form field with its current value AND a directive telling you exactly which setter to call (or skip) for that field. Treat the snapshot as the single source of truth for what is and isn't already set \u2014 do not try to infer state from anywhere else, and do not re-call setters for fields whose directive says "already set".
173
+
170
174
  # Authoring loop
171
175
 
172
176
  Follow these five steps in order, every time:
@@ -184,20 +188,19 @@ Ask yourself:
184
188
 
185
189
  ## Step B \u2014 Define the agent's identity
186
190
 
187
- Before building the agent, define:
188
- - Agent name: short, memorable, anchored to the outcome. Never "Agent X" or generic labels
191
+ Decide on:
192
+ - Agent name: short, memorable, anchored to the outcome. Never "Agent X" or generic labels.
189
193
  - Description: exactly one sentence in plain user-facing language explaining what the agent helps with.
190
194
 
191
- Call \`set-agent-name\` and \`set-agent-description\` to set the agent's identity. Skip any whose feature is not available in the form snapshot.
195
+ The snapshot will tell you whether to call \`set-agent-name\` and \`set-agent-description\` or skip them.
192
196
 
193
197
  ## Step C \u2014 Decide capabilities
194
198
 
195
- Read the form snapshot already injected into your context. It lists the user's current selections plus the available tools, agents, workflows, stored skills, models, and workspaces.
199
+ The form snapshot lists what's currently attached. Use it together with the available tools, agents, workflows, stored skills, and models listed in the corresponding tool descriptions to decide:
196
200
 
197
- Then:
198
201
  - Pick the *minimum* set of existing tools/agents/workflows/stored skills that satisfies the outcome. Adding irrelevant capabilities makes the agent worse, not better.
199
202
  - Prefer existing tools, workflows, agents, and stored skills before creating anything new.
200
- - \`set-agent-skills\` attaches user-available stored skills from the form snapshot.
203
+ - \`set-agent-skills\` attaches user-available stored skills.
201
204
  - Only call \`createSkillTool\` when (a) no existing stored skill matches reusable operating instructions the produced agent needs, AND (b) that operating instruction is genuinely needed for the outcome. Do not use stored skills as a substitute for missing integrations or tools.
202
205
  - If a specific external connection is required (e.g. a sheet tool for a spreadsheet-driven outcome) and none is available, the new agent's system prompt must instruct it to refuse cleanly and explain what the user needs to connect.
203
206
 
@@ -214,15 +217,7 @@ Before calling \`set-agent-instructions\`, privately write a concrete run contra
214
217
 
215
218
  ## Step E \u2014 Write the agent
216
219
 
217
- Call the capability tools. Skip any whose feature is not available in the form snapshot.
218
-
219
- 1. \`set-agent-model\` \u2014 pick the best model for the use case from the available models list. Rules:
220
- - Choose only a model id that appears in the available models list. Never invent, assume, or copy example model ids.
221
- - For coding, reasoning-heavy, or planning agents, prefer the most capable available model.
222
- - For short, simple, structured, or high-volume tasks, prefer a lower-latency/lower-cost available model when quality will not materially suffer.
223
- - If several plausible models are available, choose the newest or strongest option based on the metadata visible in the snapshot.
224
- 2. \`set-agent-tools\` \u2014 attach the minimum set chosen in Step C. Also use \`set-agent-skills\` and \`set-agent-browser-enabled\` only when applicable and supported by the snapshot.
225
- 3. \`set-agent-instructions\` \u2014 write the new agent's system prompt from scratch, tailored to the user's specific outcome and the run contract from Step D.
220
+ Read the per-field directives in the form snapshot. Call only the setters the snapshot tells you to call, each at most once, with the final value. Skip every field marked "already set" or "no setter". Skip any field that isn't listed at all (its feature is disabled).
226
221
 
227
222
  Before calling \`set-agent-instructions\`, self-audit the draft. It must pass every check:
228
223
  - No placeholders remain (no \`<...>\`, "TBD", "TODO", "your tool", or generic policy gaps).
@@ -282,7 +277,8 @@ The system prompt written into \`set-agent-instructions\` MUST include all of th
282
277
  id: "builder-agent",
283
278
  name: "Agent Builder Agent",
284
279
  description: "An agent that can build agents"
285
- });
280
+ };
281
+ return new import_agent3.Agent(config);
286
282
  }
287
283
  var import_agent3, import_memory2, import_workspace7, import_node_path, import_node_url, import_meta, __filename, __dirname, workspacePath, workspace;
288
284
  var init_agent_builder_agent = __esm({
@@ -342,6 +338,7 @@ __export(index_exports, {
342
338
  });
343
339
  module.exports = __toCommonJS(index_exports);
344
340
  var import_processor_provider2 = require("@mastra/core/processor-provider");
341
+ var import_storage = require("@mastra/core/storage");
345
342
  var import_tool_provider2 = require("@mastra/core/tool-provider");
346
343
 
347
344
  // src/namespaces/base.ts
@@ -1045,6 +1042,14 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1045
1042
  * Returns the (possibly mutated) agent.
1046
1043
  */
1047
1044
  async applyStoredOverrides(agent, options, requestContext) {
1045
+ const editorConfig = agent.__getEditorConfig?.();
1046
+ if (editorConfig === false) {
1047
+ return agent;
1048
+ }
1049
+ const instructionsEditable = editorConfig === void 0 ? true : editorConfig.instructions === true;
1050
+ const toolsConfig = editorConfig === void 0 ? true : editorConfig.tools;
1051
+ const toolsEditable = toolsConfig === true;
1052
+ const toolDescriptionsEditable = typeof toolsConfig === "object" && toolsConfig !== null && toolsConfig.description === true;
1048
1053
  let storedConfig = null;
1049
1054
  try {
1050
1055
  this.ensureRegistered();
@@ -1066,7 +1071,7 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1066
1071
  }
1067
1072
  const fork = agent.__fork();
1068
1073
  this.logger?.debug(`[applyStoredOverrides] Applying stored overrides to code agent "${agent.id}"`);
1069
- if (storedConfig.instructions !== void 0 && storedConfig.instructions !== null) {
1074
+ if (instructionsEditable && storedConfig.instructions !== void 0 && storedConfig.instructions !== null) {
1070
1075
  const resolved = this.resolveStoredInstructions(storedConfig.instructions);
1071
1076
  if (resolved !== void 0) {
1072
1077
  fork.__updateInstructions(resolved);
@@ -1076,7 +1081,7 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1076
1081
  const hasStoredMCPClients = storedConfig.mcpClients != null;
1077
1082
  const hasStoredIntegrationTools = storedConfig.integrationTools != null;
1078
1083
  const hasStoredToolProviders = storedConfig.toolProviders != null && Object.keys(storedConfig.toolProviders).length > 0;
1079
- if (hasStoredTools || hasStoredMCPClients || hasStoredIntegrationTools || hasStoredToolProviders) {
1084
+ if (toolsEditable && (hasStoredTools || hasStoredMCPClients || hasStoredIntegrationTools || hasStoredToolProviders)) {
1080
1085
  const hasConditionalTools = this.isConditionalVariants(storedConfig.tools);
1081
1086
  const hasConditionalMCPClients = storedConfig.mcpClients != null && this.isConditionalVariants(storedConfig.mcpClients);
1082
1087
  const hasConditionalIntegrationTools = storedConfig.integrationTools != null && this.isConditionalVariants(storedConfig.integrationTools);
@@ -1135,6 +1140,28 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1135
1140
  );
1136
1141
  fork.__setTools({ ...codeTools, ...registryTools, ...mcpTools, ...integrationTools });
1137
1142
  }
1143
+ } else if (toolDescriptionsEditable && hasStoredTools) {
1144
+ const hasConditionalTools = this.isConditionalVariants(storedConfig.tools);
1145
+ if (hasConditionalTools) {
1146
+ const originalTools = agent.listTools.bind(agent);
1147
+ const toolsFn = async ({ requestContext: requestContext2 }) => {
1148
+ const codeTools = await originalTools({ requestContext: requestContext2 });
1149
+ const resolvedToolsConfig = this.accumulateObjectVariants(
1150
+ storedConfig.tools,
1151
+ requestContext2.toJSON()
1152
+ );
1153
+ return this.applyStoredToolDescriptions(codeTools, resolvedToolsConfig);
1154
+ };
1155
+ fork.__setTools(toolsFn);
1156
+ } else {
1157
+ const codeTools = await fork.listTools();
1158
+ fork.__setTools(
1159
+ this.applyStoredToolDescriptions(
1160
+ codeTools,
1161
+ storedConfig.tools
1162
+ )
1163
+ );
1164
+ }
1138
1165
  }
1139
1166
  if (storedConfig.resolvedVersionId) {
1140
1167
  const existing = fork.toRawConfig() ?? {};
@@ -1435,6 +1462,20 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1435
1462
  return resolveInstructionBlocks(blocks, context, { promptBlocksStorage: promptBlocksStore });
1436
1463
  };
1437
1464
  }
1465
+ applyStoredToolDescriptions(codeTools, storedTools) {
1466
+ if (!storedTools || Array.isArray(storedTools)) {
1467
+ return codeTools;
1468
+ }
1469
+ let nextTools;
1470
+ for (const [toolKey, toolConfig] of Object.entries(storedTools)) {
1471
+ if (!toolConfig.description || !(toolKey in codeTools)) {
1472
+ continue;
1473
+ }
1474
+ nextTools ?? (nextTools = { ...codeTools });
1475
+ nextTools[toolKey] = { ...codeTools[toolKey], description: toolConfig.description };
1476
+ }
1477
+ return nextTools ?? codeTools;
1478
+ }
1438
1479
  /**
1439
1480
  * Resolve stored tool IDs to actual tool instances from Mastra's registry.
1440
1481
  * Applies description overrides from per-tool config when present.
@@ -2549,6 +2590,8 @@ var MastraEditor = class {
2549
2590
  this.__logger = config?.logger;
2550
2591
  this.__toolProviders = config?.toolProviders ?? {};
2551
2592
  this.__processorProviders = { ...import_processor_provider2.BUILT_IN_PROCESSOR_PROVIDERS, ...config?.processorProviders };
2593
+ this.__source = config?.source;
2594
+ this.__codePath = config?.codePath ?? "./mastra/editor";
2552
2595
  this.__filesystems = /* @__PURE__ */ new Map();
2553
2596
  this.__filesystems.set(localFilesystemProvider.id, localFilesystemProvider);
2554
2597
  for (const [id, provider] of Object.entries(config?.filesystems ?? {})) {
@@ -2586,6 +2629,21 @@ var MastraEditor = class {
2586
2629
  if (!this.__logger) {
2587
2630
  this.__logger = mastra.getLogger();
2588
2631
  }
2632
+ if (this.__source === "code") {
2633
+ const filesystemStore = new import_storage.FilesystemStore({ dir: this.__codePath });
2634
+ const existingStorage = mastra.getStorage();
2635
+ if (existingStorage) {
2636
+ mastra.setStorage(
2637
+ new import_storage.MastraCompositeStore({
2638
+ id: `${existingStorage.id}-with-editor-filesystem`,
2639
+ default: existingStorage,
2640
+ editor: filesystemStore
2641
+ })
2642
+ );
2643
+ } else {
2644
+ mastra.setStorage(filesystemStore);
2645
+ }
2646
+ }
2589
2647
  this.ensureBuilderWorkspaces().then(() => this.reconcileBuilderWorkspaces()).catch((err) => {
2590
2648
  this.__logger?.warn("[MastraEditor] Failed to persist/reconcile builder workspaces on startup", {
2591
2649
  error: err
@@ -2734,6 +2792,10 @@ var MastraEditor = class {
2734
2792
  );
2735
2793
  }
2736
2794
  }
2795
+ /** Returns the editor's configured source, or undefined if unset. */
2796
+ getSource() {
2797
+ return this.__source;
2798
+ }
2737
2799
  /** Registered tool providers */
2738
2800
  getToolProvider(id) {
2739
2801
  return this.__toolProviders[id];