@mastra/editor 0.14.1 → 0.14.2-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/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # @mastra/editor
2
2
 
3
+ ## 0.14.2-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed Studio instruction edits dropping `providerOptions` from code-defined agents. When code defines instructions as a structured system message — for example with an Anthropic prompt-cache breakpoint — editing and publishing the instructions in Studio replaced them with a plain string, silently removing the provider options. Every request then paid full uncached input cost until the override was removed. ([#22493](https://github.com/mastra-ai/mastra/pull/22493))
8
+
9
+ Studio now owns only the wording: the published text is wrapped back in the code-defined message envelope when the override is applied, so provider options survive edits. This applies retroactively — existing published overrides pick up the code envelope on upgrade, with no migration needed.
10
+
11
+ ```ts
12
+ const agent = new Agent({
13
+ id: 'voice-agent',
14
+ name: 'Voice Agent',
15
+ instructions: {
16
+ role: 'system',
17
+ content: 'You are a helpful voice assistant.',
18
+ providerOptions: { anthropic: { cacheControl: { type: 'ephemeral' } } },
19
+ },
20
+ model: 'anthropic/claude-sonnet-4-6',
21
+ });
22
+
23
+ // Before: after publishing an instructions edit in Studio, the agent ran with a
24
+ // plain string — the cacheControl breakpoint was gone until the override was deleted.
25
+ // After: the edited text is published inside the same system message, and
26
+ // providerOptions.anthropic.cacheControl keeps working.
27
+ ```
28
+
29
+ Instructions delegated entirely to Studio (`editor: { instructions: true }`) have no code-defined envelope and are unaffected. Fixes https://github.com/mastra-ai/mastra/issues/10980
30
+
31
+ - Updated dependencies [[`0885364`](https://github.com/mastra-ai/mastra/commit/0885364c2fc7fa31febcfc444fc1ba5231ac1257)]:
32
+ - @mastra/core@1.63.1-alpha.2
33
+ - @mastra/memory@1.28.1-alpha.1
34
+
35
+ ## 0.14.2-alpha.0
36
+
37
+ ### Patch Changes
38
+
39
+ - Updated dependencies [[`295e506`](https://github.com/mastra-ai/mastra/commit/295e506b9e6cec99e7181c5f712648888cd9486f), [`8c3be07`](https://github.com/mastra-ai/mastra/commit/8c3be0761a862c5c035ed6e5d633de87cbba20e7), [`078affd`](https://github.com/mastra-ai/mastra/commit/078affdaea57ac5e95a77e9e7b197d1878190684), [`9e3403e`](https://github.com/mastra-ai/mastra/commit/9e3403e9868240cb18841898e84cf008ebd7a87e), [`791bf5e`](https://github.com/mastra-ai/mastra/commit/791bf5e81cd27e2e1cff66122f1380ab8a3dda41)]:
40
+ - @mastra/memory@1.28.1-alpha.0
41
+ - @mastra/core@1.63.1-alpha.1
42
+ - @mastra/mcp@1.17.2
43
+
3
44
  ## 0.14.1
4
45
 
5
46
  ### Patch Changes
package/LICENSE.md CHANGED
@@ -1,10 +1,12 @@
1
1
  Portions of this software are licensed as follows:
2
2
 
3
- - All content that resides under any directory named "ee/" within this
3
+ - All content that resides under any directory named `ee/` within this
4
4
  repository, including but not limited to:
5
- - `packages/core/src/auth/ee/`
6
- - `packages/server/src/server/auth/ee/`
7
- is licensed under the license defined in `ee/LICENSE`.
5
+ - `@mastra/core/auth/ee`
6
+ - `@mastra/core/agent-builder/ee`
7
+ - `@mastra/editor/ee`
8
+
9
+ is licensed under the license defined in [`ee/LICENSE`](https://github.com/mastra-ai/mastra/blob/main/ee/LICENSE).
8
10
 
9
11
  - All third-party components incorporated into the Mastra Software are
10
12
  licensed under the original license provided by the owner of the
package/dist/index.cjs CHANGED
@@ -905,7 +905,7 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
905
905
  this.logger?.debug(`[applyStoredOverrides] Applying stored overrides to code agent "${agent.id}"`);
906
906
  if (instructionsEditable && storedConfig.instructions !== void 0 && storedConfig.instructions !== null) {
907
907
  const resolved = this.resolveStoredInstructions(storedConfig.instructions);
908
- if (resolved !== void 0) fork.__updateInstructions(resolved);
908
+ if (resolved !== void 0) fork.__updateInstructions(this.mergeInstructionEnvelope(agent, resolved));
909
909
  }
910
910
  const hasStoredTools = storedConfig.tools != null;
911
911
  const hasStoredMCPClients = storedConfig.mcpClients != null;
@@ -1192,6 +1192,54 @@ var EditorAgentNamespace = class extends CrudEditorNamespace {
1192
1192
  return resolveInstructionBlocks(blocks, context, { promptBlocksStorage: promptBlocksStore });
1193
1193
  };
1194
1194
  }
1195
+ /**
1196
+ * Wrap stored instruction text in the code-defined agent's message envelope.
1197
+ *
1198
+ * Stored overrides can only carry plain text (`string | AgentInstructionBlock[]`),
1199
+ * but code-defined instructions may be structured system messages carrying
1200
+ * `providerOptions` (e.g. `anthropic.cacheControl` prompt-cache breakpoints).
1201
+ * Studio owns the wording; code keeps the envelope, so publishing an edit
1202
+ * can't silently drop provider options.
1203
+ *
1204
+ * When the code instructions are plain text (or absent, e.g. editor-owned
1205
+ * agents), the stored value is returned unchanged. When code instructions are
1206
+ * an array of messages, the last message's envelope is kept: an Anthropic
1207
+ * cache breakpoint on the last system block covers everything before it, so
1208
+ * it is the one worth preserving when Studio flattens the array into one text.
1209
+ */
1210
+ mergeInstructionEnvelope(agent, stored) {
1211
+ const raw = agent.__getOverridableFields?.()?.instructions;
1212
+ const pickEnvelope = (value) => {
1213
+ const candidate = Array.isArray(value) ? value[value.length - 1] : value;
1214
+ return typeof candidate === "object" && candidate !== null && "content" in candidate ? candidate : void 0;
1215
+ };
1216
+ const wrap = (envelope, text) => ({
1217
+ ...envelope,
1218
+ content: text
1219
+ });
1220
+ if (raw == null || typeof raw === "string" || Array.isArray(raw) && raw.every((entry) => typeof entry === "string")) return stored;
1221
+ if (typeof raw !== "function") {
1222
+ const envelope = pickEnvelope(raw);
1223
+ if (!envelope) return stored;
1224
+ if (typeof stored === "string") return wrap(envelope, stored);
1225
+ return async (args) => wrap(envelope, await stored(args));
1226
+ }
1227
+ const getOriginal = agent.getInstructions.bind(agent);
1228
+ return async ({ requestContext, mastra }) => {
1229
+ const text = typeof stored === "string" ? stored : await stored({
1230
+ requestContext,
1231
+ mastra
1232
+ });
1233
+ let original;
1234
+ try {
1235
+ original = await getOriginal({ requestContext });
1236
+ } catch {
1237
+ return text;
1238
+ }
1239
+ const envelope = pickEnvelope(original);
1240
+ return envelope ? wrap(envelope, text) : text;
1241
+ };
1242
+ }
1195
1243
  applyStoredToolDescriptions(codeTools, storedTools) {
1196
1244
  if (!storedTools || Array.isArray(storedTools)) return codeTools;
1197
1245
  let nextTools;