@mastra/code-sdk 1.8.1-alpha.2 → 1.8.1-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/README.md CHANGED
@@ -24,6 +24,40 @@ const { mastra, controller } = await mountAgentControllerOnMastra({
24
24
  });
25
25
  ```
26
26
 
27
+ ### Plugin background execution
28
+
29
+ With the experimental `backgroundTools.enabled` setting on, plugin tools are eligible for native background execution only when they declare their own configuration:
30
+
31
+ ```ts
32
+ background: {
33
+ enabled: true,
34
+ defaultDisposition: 'foreground',
35
+ maxRetries: 0,
36
+ }
37
+ ```
38
+
39
+ The SDK doesn't infer support from tool names or serialize plugin calls. When the setting is off, it disables plugin-declared background execution without modifying the original tool.
40
+
41
+ Tools that already await their work need no separate execution path. For a tool that returns an acknowledgement while continuing independently, native execution exposes `context.background`. Adopt the existing operation before returning:
42
+
43
+ ```ts
44
+ const operation = startResearch(input, context.abortSignal);
45
+ if (context.background) {
46
+ context.background.adopt({
47
+ completion: operation.finished,
48
+ cancel: reason => operation.cancel(reason),
49
+ });
50
+ return { answer: 'Research started' };
51
+ }
52
+ return await operation.finished;
53
+ ```
54
+
55
+ Here, `startResearch` represents the plugin's own operation API. Its `finished` promise must resolve with the terminal tool result only after work and cleanup finish, or reject on failure. The native task tracks that promise instead of the acknowledgement. Adopt at most one operation, before `execute()` returns. Forward cancellation through the supplied signal or the operation's `cancel` callback. Without adoption, `execute()` must itself await the complete operation.
56
+
57
+ The handle stays in memory and isn't restart-safe. The plugin still owns its conversation-level queue and answer signals. Adoption doesn't suppress host completion notifications; keep progress rendering active until the adopted operation finishes.
58
+
59
+ `defaultDisposition: 'foreground'` preserves normal calls unless the caller explicitly requests `_background.disposition: 'deferred'` or `'awaited'`. Plugins without a declaration remain usable in the foreground, including older versions of `mastra_expert`.
60
+
27
61
  ## Documentation
28
62
 
29
63
  - [@mastra/code-sdk documentation](https://mastra.ai/reference/code-sdk/mount-agent-controller)
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/agents/tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAA+B,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC/F,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAWlD,4DAA4D;AAC5D,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAC1D,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAuCxB,qBAAa,wBAAyB,SAAQ,oBAAoB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,oBAAoB;YAI5C,uBAAuB;IAQ/B,kBAAkB,CAAC,KAAK,EAAE,uBAAuB;IAIjD,iBAAiB,CAAC,KAAK,EAAE,sBAAsB;IAI/C,oBAAoB,CAAC,KAAK,EAAE,yBAAyB;IAIrD,eAAe,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE;IAIvD,kBAAkB,CAAC,KAAK,EAAE,uBAAuB;IAIxC,yBAAyB,CAAC,KAAK,EAAE,8BAA8B;IAIxE,mBAAmB;CAG1B;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvF,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,SAAS,GAAG,SAAS,CAoCrH;AAED,KAAK,mBAAmB,GACpB,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,GACpC,CAAC,CAAC,GAAG,EAAE;IACL,cAAc,EAAE,cAAc,CAAC;CAChC,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;AAEhG,wBAAgB,kBAAkB,CAChC,UAAU,CAAC,EAAE,UAAU,EACvB,UAAU,CAAC,EAAE,mBAAmB,EAChC,aAAa,CAAC,EAAE,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtC,sBAAsB,UAAQ,IAEE,qBAE7B;IACD,cAAc,EAAE,cAAc,CAAC;CAChC,KAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CA6FrC"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/agents/tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAA+B,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAC/F,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAWlD,4DAA4D;AAC5D,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAC1D,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAOxB,qBAAa,wBAAyB,SAAQ,oBAAoB;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,oBAAoB;YAI5C,uBAAuB;IAQ/B,kBAAkB,CAAC,KAAK,EAAE,uBAAuB;IAIjD,iBAAiB,CAAC,KAAK,EAAE,sBAAsB;IAI/C,oBAAoB,CAAC,KAAK,EAAE,yBAAyB;IAIrD,eAAe,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE;IAIvD,kBAAkB,CAAC,KAAK,EAAE,uBAAuB;IAIxC,yBAAyB,CAAC,KAAK,EAAE,8BAA8B;IAIxE,mBAAmB;CAG1B;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvF,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,SAAS,GAAG,SAAS,CAoCrH;AAED,KAAK,mBAAmB,GACpB,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,GACpC,CAAC,CAAC,GAAG,EAAE;IACL,cAAc,EAAE,cAAc,CAAC;CAChC,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;AAEhG,wBAAgB,kBAAkB,CAChC,UAAU,CAAC,EAAE,UAAU,EACvB,UAAU,CAAC,EAAE,mBAAmB,EAChC,aAAa,CAAC,EAAE,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE,oBAAoB,EAC9B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtC,sBAAsB,UAAQ,IAEE,qBAE7B;IACD,cAAc,EAAE,cAAc,CAAC;CAChC,KAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CA6FrC"}
@@ -12,32 +12,14 @@ import { createOpenAI } from "@ai-sdk/openai";
12
12
  import { NotificationsStorage, createNotificationInboxTool } from "@mastra/core/notifications";
13
13
  import { createAnthropic } from "@ai-sdk/anthropic";
14
14
  //#region src/agents/tools.ts
15
- const BACKGROUND_ELIGIBLE_PLUGIN_TOOLS = /* @__PURE__ */ new Set(["mastra_expert"]);
16
- let alexandriaExecutionTail = Promise.resolve();
17
- async function executeAlexandriaSerially(tool, args) {
18
- const previous = alexandriaExecutionTail;
19
- let release;
20
- const current = new Promise((resolve) => {
21
- release = resolve;
22
- });
23
- alexandriaExecutionTail = previous.then(() => current, () => current);
24
- await previous.catch(() => void 0);
25
- try {
26
- (args[1]?.abortSignal)?.throwIfAborted();
27
- return await tool.execute?.apply(tool, args);
28
- } finally {
29
- release();
30
- }
31
- }
32
- function configurePluginTool(name, tool, backgroundToolsEnabled) {
33
- if (!backgroundToolsEnabled || !BACKGROUND_ELIGIBLE_PLUGIN_TOOLS.has(name)) return tool;
15
+ function configurePluginTool(tool, backgroundToolsEnabled) {
16
+ if (backgroundToolsEnabled || !tool.background) return tool;
34
17
  return {
35
18
  ...tool,
36
19
  background: {
37
- enabled: true,
38
- defaultDisposition: "foreground"
39
- },
40
- execute: (...args) => executeAlexandriaSerially(tool, args)
20
+ ...tool.background,
21
+ enabled: false
22
+ }
41
23
  };
42
24
  }
43
25
  var LazyNotificationsStorage = class extends NotificationsStorage {
@@ -125,7 +107,7 @@ function createDynamicTools(mcpManager, extraTools, disabledTools, storage, plug
125
107
  for (const [name, tool] of Object.entries(resolvedExtra)) if (tool && !(name in tools)) tools[name] = tool;
126
108
  }
127
109
  if (pluginTools) {
128
- for (const [name, tool] of Object.entries(pluginTools)) if (!(name in tools)) tools[name] = configurePluginTool(name, tool, backgroundToolsEnabled);
110
+ for (const [name, tool] of Object.entries(pluginTools)) if (!(name in tools)) tools[name] = configurePluginTool(tool, backgroundToolsEnabled);
129
111
  }
130
112
  if (disabledTools?.length) for (const toolName of disabledTools) delete tools[toolName];
131
113
  const permissionRules = state?.permissionRules;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","names":[],"sources":["../../src/agents/tools.ts"],"sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport { createNotificationInboxTool, NotificationsStorage } from '@mastra/core/notifications';\nimport type {\n CreateNotificationInput,\n ListDueNotificationsInput,\n ListNotificationsInput,\n UpdateNotificationInput,\n UpdateNotificationsStatusInput,\n} from '@mastra/core/notifications';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { MastraCompositeStore } from '@mastra/core/storage';\nimport type { ToolAfterHookContext, ToolHooks } from '@mastra/core/tools';\nimport type { HookManager } from '../hooks/index.js';\nimport type { McpManager } from '../mcp/index.js';\nimport type { MastraCodeComposedState } from '../schema.js';\nimport { MC_TOOLS } from '../tool-names.js';\nimport { createConfiguredWebTools, requestSandboxAccessTool } from '../tools/index.js';\nimport { createWorkflowTool } from '../tools/workflows/create-workflow.js';\nimport { deleteWorkflowTool } from '../tools/workflows/delete-workflow.js';\nimport { getWorkflowTool } from '../tools/workflows/get-workflow.js';\nimport { listWorkflowsTool } from '../tools/workflows/list-workflows.js';\nimport { runWorkflowTool } from '../tools/workflows/run-workflow.js';\nimport { WORKFLOW_MANAGEMENT_TOOL_IDS } from '../tools/workflows/tool-ids.js';\n\n/** Minimal shape for tools passed to createDynamicTools. */\nexport type ToolLike = {\n execute?: (...args: any[]) => Promise<unknown> | unknown;\n} & Record<string, any>;\n\nconst BACKGROUND_ELIGIBLE_PLUGIN_TOOLS = new Set(['mastra_expert']);\nlet alexandriaExecutionTail = Promise.resolve();\n\nasync function executeAlexandriaSerially(tool: ToolLike, args: any[]): Promise<unknown> {\n const previous = alexandriaExecutionTail;\n let release!: () => void;\n const current = new Promise<void>(resolve => {\n release = resolve;\n });\n alexandriaExecutionTail = previous.then(\n () => current,\n () => current,\n );\n\n await previous.catch(() => undefined);\n try {\n const abortSignal = args[1]?.abortSignal as AbortSignal | undefined;\n abortSignal?.throwIfAborted();\n return await tool.execute?.apply(tool, args);\n } finally {\n // The active tool receives the same abort signal and owns terminating its\n // nested execution. Never release this slot until that execution settles.\n release();\n }\n}\n\nfunction configurePluginTool(name: string, tool: ToolLike, backgroundToolsEnabled: boolean): ToolLike {\n if (!backgroundToolsEnabled || !BACKGROUND_ELIGIBLE_PLUGIN_TOOLS.has(name)) return tool;\n return {\n ...tool,\n // Eligible for backgrounding, but the agent must opt in per call — a plain\n // expert question should stay a normal awaited foreground call.\n background: { enabled: true, defaultDisposition: 'foreground' as const },\n execute: (...args: any[]) => executeAlexandriaSerially(tool, args),\n };\n}\n\nexport class LazyNotificationsStorage extends NotificationsStorage {\n constructor(private readonly storage: MastraCompositeStore) {\n super();\n }\n\n private async getNotificationsStorage(): Promise<NotificationsStorage> {\n const notifications = await this.storage.getStore('notifications');\n if (!notifications) {\n throw new Error('notification_inbox requires a notifications storage domain');\n }\n return notifications;\n }\n\n async createNotification(input: CreateNotificationInput) {\n return (await this.getNotificationsStorage()).createNotification(input);\n }\n\n async listNotifications(input: ListNotificationsInput) {\n return (await this.getNotificationsStorage()).listNotifications(input);\n }\n\n async listDueNotifications(input: ListDueNotificationsInput) {\n return (await this.getNotificationsStorage()).listDueNotifications(input);\n }\n\n async getNotification(input: { threadId: string; id: string }) {\n return (await this.getNotificationsStorage()).getNotification(input);\n }\n\n async updateNotification(input: UpdateNotificationInput) {\n return (await this.getNotificationsStorage()).updateNotification(input);\n }\n\n override async updateNotificationsStatus(input: UpdateNotificationsStatusInput) {\n return (await this.getNotificationsStorage()).updateNotificationsStatus(input);\n }\n\n async dangerouslyClearAll() {\n return (await this.getNotificationsStorage()).dangerouslyClearAll();\n }\n}\n\nexport type PostToolObserver = (context: ToolAfterHookContext) => void | Promise<void>;\n\nexport function createToolHooks(hookManager?: HookManager, postToolObserver?: PostToolObserver): ToolHooks | undefined {\n if (!hookManager && !postToolObserver) return undefined;\n\n return {\n beforeToolCall: async ({ toolName, input }) => {\n if (!hookManager) return;\n const preResult = await hookManager.runPreToolUse(toolName, input);\n if (!preResult.allowed) {\n return {\n proceed: false as const,\n output: {\n error: preResult.blockReason ?? `Blocked by PreToolUse hook for tool \"${toolName}\"`,\n },\n };\n }\n },\n afterToolCall: async context => {\n const { toolName, input, output, error } = context;\n if (hookManager) {\n const failed = error !== undefined;\n await hookManager\n .runPostToolUse(\n toolName,\n input,\n failed ? { error: error instanceof Error ? error.message : String(error) } : output,\n failed,\n )\n .catch(() => undefined);\n }\n await Promise.resolve()\n .then(() => postToolObserver?.(context))\n .catch(error => {\n console.warn(`[MastraCode] Post-tool observer failed for ${toolName}.`, error);\n });\n },\n };\n}\n\ntype DynamicToolProvider =\n | Record<string, ToolLike | undefined>\n | ((ctx: {\n requestContext: RequestContext;\n }) => Record<string, ToolLike | undefined> | Promise<Record<string, ToolLike | undefined>>);\n\nexport function createDynamicTools(\n mcpManager?: McpManager,\n extraTools?: DynamicToolProvider,\n disabledTools?: string[],\n storage?: MastraCompositeStore,\n pluginTools?: Record<string, ToolLike>,\n backgroundToolsEnabled = false,\n) {\n return function getDynamicTools({\n requestContext,\n }: {\n requestContext: RequestContext;\n }): ToolsInput | Promise<ToolsInput> {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeComposedState> | undefined;\n const state = ctx?.getState();\n\n const modelId = ctx?.session?.modelId;\n const isAnthropicModel = modelId?.startsWith('anthropic/');\n const isOpenAIModel = modelId?.startsWith('openai/');\n\n // Filesystem, grep, glob, edit, write, execute_command, and process\n // management tools are now provided by the workspace (see workspace.ts).\n // Only tools without a workspace equivalent remain here.\n const tools: Record<string, ToolLike> = {\n request_access: requestSandboxAccessTool,\n // Workflow surface. `create-workflow` delegates to the workflow-builder\n // sub-agent; the other four are Dynamic Workflow management operations.\n // Permission categories live in permissions.ts (TOOL_CATEGORY_MAP).\n [WORKFLOW_MANAGEMENT_TOOL_IDS.createWorkflow]: createWorkflowTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.listWorkflows]: listWorkflowsTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.getWorkflow]: getWorkflowTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.runWorkflow]: runWorkflowTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.deleteWorkflow]: deleteWorkflowTool,\n };\n\n if (storage) {\n tools[MC_TOOLS.NOTIFICATION_INBOX] = createNotificationInboxTool({\n storage: new LazyNotificationsStorage(storage),\n });\n }\n\n const configuredWebTools = createConfiguredWebTools();\n if (configuredWebTools) {\n Object.assign(tools, configuredWebTools);\n } else if (isAnthropicModel) {\n const anthropic = createAnthropic({});\n tools.web_search = anthropic.tools.webSearch_20250305();\n } else if (isOpenAIModel) {\n const openai = createOpenAI({});\n tools.web_search = openai.tools.webSearch();\n }\n\n if (mcpManager) {\n const mcpTools = mcpManager.getTools();\n Object.assign(tools, mcpTools);\n }\n\n const finish = (resolvedExtra: Record<string, ToolLike | undefined> | undefined) => {\n if (resolvedExtra) {\n for (const [name, tool] of Object.entries(resolvedExtra)) {\n if (tool && !(name in tools)) {\n tools[name] = tool;\n }\n }\n }\n\n if (pluginTools) {\n for (const [name, tool] of Object.entries(pluginTools)) {\n if (!(name in tools)) {\n tools[name] = configurePluginTool(name, tool, backgroundToolsEnabled);\n }\n }\n }\n\n // Remove tools explicitly disabled via config so the model never sees them.\n if (disabledTools?.length) {\n for (const toolName of disabledTools) {\n delete tools[toolName];\n }\n }\n\n // Remove tools that have a per-tool 'deny' policy so the model never sees them.\n const permissionRules = state?.permissionRules;\n if (permissionRules?.tools) {\n for (const [name, policy] of Object.entries(permissionRules.tools)) {\n if (policy === 'deny') {\n delete tools[name];\n }\n }\n }\n\n return tools as ToolsInput;\n };\n\n if (typeof extraTools === 'function') {\n const resolved = extraTools({ requestContext });\n // Stay synchronous for sync providers; only go async when the provider does.\n if (resolved && typeof (resolved as PromiseLike<unknown>).then === 'function') {\n return Promise.resolve(resolved).then(finish);\n }\n return finish(resolved as Record<string, ToolLike | undefined>);\n }\n\n return finish(extraTools);\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","names":[],"sources":["../../src/agents/tools.ts"],"sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport type { ToolsInput } from '@mastra/core/agent';\nimport type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport { createNotificationInboxTool, NotificationsStorage } from '@mastra/core/notifications';\nimport type {\n CreateNotificationInput,\n ListDueNotificationsInput,\n ListNotificationsInput,\n UpdateNotificationInput,\n UpdateNotificationsStatusInput,\n} from '@mastra/core/notifications';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { MastraCompositeStore } from '@mastra/core/storage';\nimport type { ToolAfterHookContext, ToolHooks } from '@mastra/core/tools';\nimport type { HookManager } from '../hooks/index.js';\nimport type { McpManager } from '../mcp/index.js';\nimport type { MastraCodeComposedState } from '../schema.js';\nimport { MC_TOOLS } from '../tool-names.js';\nimport { createConfiguredWebTools, requestSandboxAccessTool } from '../tools/index.js';\nimport { createWorkflowTool } from '../tools/workflows/create-workflow.js';\nimport { deleteWorkflowTool } from '../tools/workflows/delete-workflow.js';\nimport { getWorkflowTool } from '../tools/workflows/get-workflow.js';\nimport { listWorkflowsTool } from '../tools/workflows/list-workflows.js';\nimport { runWorkflowTool } from '../tools/workflows/run-workflow.js';\nimport { WORKFLOW_MANAGEMENT_TOOL_IDS } from '../tools/workflows/tool-ids.js';\n\n/** Minimal shape for tools passed to createDynamicTools. */\nexport type ToolLike = {\n execute?: (...args: any[]) => Promise<unknown> | unknown;\n} & Record<string, any>;\n\nfunction configurePluginTool(tool: ToolLike, backgroundToolsEnabled: boolean): ToolLike {\n if (backgroundToolsEnabled || !tool.background) return tool;\n return { ...tool, background: { ...tool.background, enabled: false } };\n}\n\nexport class LazyNotificationsStorage extends NotificationsStorage {\n constructor(private readonly storage: MastraCompositeStore) {\n super();\n }\n\n private async getNotificationsStorage(): Promise<NotificationsStorage> {\n const notifications = await this.storage.getStore('notifications');\n if (!notifications) {\n throw new Error('notification_inbox requires a notifications storage domain');\n }\n return notifications;\n }\n\n async createNotification(input: CreateNotificationInput) {\n return (await this.getNotificationsStorage()).createNotification(input);\n }\n\n async listNotifications(input: ListNotificationsInput) {\n return (await this.getNotificationsStorage()).listNotifications(input);\n }\n\n async listDueNotifications(input: ListDueNotificationsInput) {\n return (await this.getNotificationsStorage()).listDueNotifications(input);\n }\n\n async getNotification(input: { threadId: string; id: string }) {\n return (await this.getNotificationsStorage()).getNotification(input);\n }\n\n async updateNotification(input: UpdateNotificationInput) {\n return (await this.getNotificationsStorage()).updateNotification(input);\n }\n\n override async updateNotificationsStatus(input: UpdateNotificationsStatusInput) {\n return (await this.getNotificationsStorage()).updateNotificationsStatus(input);\n }\n\n async dangerouslyClearAll() {\n return (await this.getNotificationsStorage()).dangerouslyClearAll();\n }\n}\n\nexport type PostToolObserver = (context: ToolAfterHookContext) => void | Promise<void>;\n\nexport function createToolHooks(hookManager?: HookManager, postToolObserver?: PostToolObserver): ToolHooks | undefined {\n if (!hookManager && !postToolObserver) return undefined;\n\n return {\n beforeToolCall: async ({ toolName, input }) => {\n if (!hookManager) return;\n const preResult = await hookManager.runPreToolUse(toolName, input);\n if (!preResult.allowed) {\n return {\n proceed: false as const,\n output: {\n error: preResult.blockReason ?? `Blocked by PreToolUse hook for tool \"${toolName}\"`,\n },\n };\n }\n },\n afterToolCall: async context => {\n const { toolName, input, output, error } = context;\n if (hookManager) {\n const failed = error !== undefined;\n await hookManager\n .runPostToolUse(\n toolName,\n input,\n failed ? { error: error instanceof Error ? error.message : String(error) } : output,\n failed,\n )\n .catch(() => undefined);\n }\n await Promise.resolve()\n .then(() => postToolObserver?.(context))\n .catch(error => {\n console.warn(`[MastraCode] Post-tool observer failed for ${toolName}.`, error);\n });\n },\n };\n}\n\ntype DynamicToolProvider =\n | Record<string, ToolLike | undefined>\n | ((ctx: {\n requestContext: RequestContext;\n }) => Record<string, ToolLike | undefined> | Promise<Record<string, ToolLike | undefined>>);\n\nexport function createDynamicTools(\n mcpManager?: McpManager,\n extraTools?: DynamicToolProvider,\n disabledTools?: string[],\n storage?: MastraCompositeStore,\n pluginTools?: Record<string, ToolLike>,\n backgroundToolsEnabled = false,\n) {\n return function getDynamicTools({\n requestContext,\n }: {\n requestContext: RequestContext;\n }): ToolsInput | Promise<ToolsInput> {\n const ctx = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeComposedState> | undefined;\n const state = ctx?.getState();\n\n const modelId = ctx?.session?.modelId;\n const isAnthropicModel = modelId?.startsWith('anthropic/');\n const isOpenAIModel = modelId?.startsWith('openai/');\n\n // Filesystem, grep, glob, edit, write, execute_command, and process\n // management tools are now provided by the workspace (see workspace.ts).\n // Only tools without a workspace equivalent remain here.\n const tools: Record<string, ToolLike> = {\n request_access: requestSandboxAccessTool,\n // Workflow surface. `create-workflow` delegates to the workflow-builder\n // sub-agent; the other four are Dynamic Workflow management operations.\n // Permission categories live in permissions.ts (TOOL_CATEGORY_MAP).\n [WORKFLOW_MANAGEMENT_TOOL_IDS.createWorkflow]: createWorkflowTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.listWorkflows]: listWorkflowsTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.getWorkflow]: getWorkflowTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.runWorkflow]: runWorkflowTool,\n [WORKFLOW_MANAGEMENT_TOOL_IDS.deleteWorkflow]: deleteWorkflowTool,\n };\n\n if (storage) {\n tools[MC_TOOLS.NOTIFICATION_INBOX] = createNotificationInboxTool({\n storage: new LazyNotificationsStorage(storage),\n });\n }\n\n const configuredWebTools = createConfiguredWebTools();\n if (configuredWebTools) {\n Object.assign(tools, configuredWebTools);\n } else if (isAnthropicModel) {\n const anthropic = createAnthropic({});\n tools.web_search = anthropic.tools.webSearch_20250305();\n } else if (isOpenAIModel) {\n const openai = createOpenAI({});\n tools.web_search = openai.tools.webSearch();\n }\n\n if (mcpManager) {\n const mcpTools = mcpManager.getTools();\n Object.assign(tools, mcpTools);\n }\n\n const finish = (resolvedExtra: Record<string, ToolLike | undefined> | undefined) => {\n if (resolvedExtra) {\n for (const [name, tool] of Object.entries(resolvedExtra)) {\n if (tool && !(name in tools)) {\n tools[name] = tool;\n }\n }\n }\n\n if (pluginTools) {\n for (const [name, tool] of Object.entries(pluginTools)) {\n if (!(name in tools)) {\n tools[name] = configurePluginTool(tool, backgroundToolsEnabled);\n }\n }\n }\n\n // Remove tools explicitly disabled via config so the model never sees them.\n if (disabledTools?.length) {\n for (const toolName of disabledTools) {\n delete tools[toolName];\n }\n }\n\n // Remove tools that have a per-tool 'deny' policy so the model never sees them.\n const permissionRules = state?.permissionRules;\n if (permissionRules?.tools) {\n for (const [name, policy] of Object.entries(permissionRules.tools)) {\n if (policy === 'deny') {\n delete tools[name];\n }\n }\n }\n\n return tools as ToolsInput;\n };\n\n if (typeof extraTools === 'function') {\n const resolved = extraTools({ requestContext });\n // Stay synchronous for sync providers; only go async when the provider does.\n if (resolved && typeof (resolved as PromiseLike<unknown>).then === 'function') {\n return Promise.resolve(resolved).then(finish);\n }\n return finish(resolved as Record<string, ToolLike | undefined>);\n }\n\n return finish(extraTools);\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-builder-agent.d.ts","sourceRoot":"","sources":["../../src/agents/workflow-builder-agent.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,oBAAoB,6KA2D/B,CAAC"}
1
+ {"version":3,"file":"workflow-builder-agent.d.ts","sourceRoot":"","sources":["../../src/agents/workflow-builder-agent.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,oBAAoB,6KA4D/B,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { getDynamicModel } from "./model.js";
2
2
  import { WORKFLOW_AUTHORING_TOOL_IDS } from "../tools/workflows/tool-ids.js";
3
3
  import { listAvailableAgentsTool } from "../tools/workflows/list-available-agents.js";
4
+ import { listAvailableClassifiersTool } from "../tools/workflows/list-available-classifiers.js";
4
5
  import { listAvailableToolsTool } from "../tools/workflows/list-available-tools.js";
5
6
  import { listAvailableWorkflowsTool } from "../tools/workflows/list-available-workflows.js";
6
7
  import { saveWorkflowTool } from "../tools/workflows/save-workflow.js";
@@ -24,6 +25,7 @@ const workflowBuilderAgent = createWorkflowBuilderAgent({
24
25
  description: "Turns plain-language workflow descriptions into runnable, persisted workflow definitions.",
25
26
  tools: {
26
27
  [WORKFLOW_AUTHORING_TOOL_IDS.listAgents]: listAvailableAgentsTool,
28
+ [WORKFLOW_AUTHORING_TOOL_IDS.listClassifiers]: listAvailableClassifiersTool,
27
29
  [WORKFLOW_AUTHORING_TOOL_IDS.listTools]: listAvailableToolsTool,
28
30
  [WORKFLOW_AUTHORING_TOOL_IDS.listWorkflows]: listAvailableWorkflowsTool,
29
31
  [WORKFLOW_AUTHORING_TOOL_IDS.saveWorkflow]: saveWorkflowTool
@@ -59,9 +61,9 @@ Always confirm these shapes against \`list-available-tools\` rather than trustin
59
61
 
60
62
  # Mastra Code discovery notes
61
63
 
62
- The three shared listing tools behave here exactly as the shared playbook describes; each row's \`id\` is the value you copy into \`agentId\` / \`toolId\` / \`workflowId\`. \`list-available-workflows\` includes both code-defined and Dynamic Workflows, and its catalog is always available on this surface.
64
+ The four shared listing tools behave here exactly as the shared playbook describes; each row's \`id\` is the value you copy into \`agentId\` / \`classifierId\` / \`toolId\` / \`workflowId\`. \`list-available-classifiers\` includes configured question metadata and stable \`values.<question>\` paths for conditional routing. \`list-available-workflows\` includes both code-defined and Dynamic Workflows, and its catalog is always available on this surface.
63
65
 
64
- Your fourth tool is \`save-workflow\`, which persists and live-registers a definition. Make one sequential complete call per attempt, only after composition and the shared pre-action check.
66
+ Your fifth tool is \`save-workflow\`, which persists and live-registers a definition. Make one sequential complete call per attempt, only after composition and the shared pre-action check.
65
67
 
66
68
  # Mastra Code execution and response protocol
67
69
 
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-builder-agent.js","names":[],"sources":["../../src/agents/workflow-builder-agent.ts"],"sourcesContent":["/**\n * Workflow Builder sub-agent.\n *\n * The parent code-agent (build/plan/explore modes) delegates to this agent\n * via the `create-workflow` tool. Keeping the long workflow-authoring system\n * prompt here — instead of inlining it into every parent mode — keeps the\n * parent modes lean and lets the same author logic ship to Studio later.\n *\n * The sub-agent's tool set is intentionally tiny: discover what's available,\n * construct the entire definition in one thought, save it. No setter loop,\n * no per-step mutations.\n */\nimport { createWorkflowBuilderAgent } from '@mastra/core/workflows/builder';\nimport { listAvailableAgentsTool } from '../tools/workflows/list-available-agents.js';\nimport { listAvailableToolsTool } from '../tools/workflows/list-available-tools.js';\nimport { listAvailableWorkflowsTool } from '../tools/workflows/list-available-workflows.js';\nimport { saveWorkflowTool } from '../tools/workflows/save-workflow.js';\nimport { WORKFLOW_AUTHORING_TOOL_IDS } from '../tools/workflows/tool-ids.js';\nimport { getDynamicModel } from './model.js';\n\nexport const workflowBuilderAgent = createWorkflowBuilderAgent({\n id: 'workflow-builder',\n name: 'Workflow Builder',\n description: 'Turns plain-language workflow descriptions into runnable, persisted workflow definitions.',\n tools: {\n [WORKFLOW_AUTHORING_TOOL_IDS.listAgents]: listAvailableAgentsTool,\n [WORKFLOW_AUTHORING_TOOL_IDS.listTools]: listAvailableToolsTool,\n [WORKFLOW_AUTHORING_TOOL_IDS.listWorkflows]: listAvailableWorkflowsTool,\n [WORKFLOW_AUTHORING_TOOL_IDS.saveWorkflow]: saveWorkflowTool,\n },\n surfaceInstructions: `# Mastra Code authoring policy\n\nYour job: turn the user's verbatim plain-language request into a complete Dynamic Workflow definition and persist it with save-workflow. Success means save-workflow returned \\`{ ok: true, id }\\` for the workflow the user asked for; do not claim success before that result.\n\nSave each definition successfully **exactly once**: after \\`save-workflow\\` returns \\`{ ok: true, id }\\`, never save that workflow again. The workflow the user asked for is always saved LAST. You may save other workflows before it **only** when they are helper workflows the requested workflow references as \\`{ type: \"workflow\" }\\` entries — never to probe the schema or split one workflow into pieces the user did not ask for. A rejected save is not a successful save; correct the reported issues and make the one sequential corrected attempt permitted by the protocol below.\n\n# \\`code-agent\\` — when to use it as an agent step\n\nThe Mastra instance registers \\`code-agent\\` (mastracode's coding agent) alongside the workflow-builder. When discovery surfaces it in \\`list-available-agents\\`, know that under the hood it has full access to workspace tools (view / edit / run commands), MCP tools, and web search — and it *reasons* over a prompt to pick the right ones.\n\nUse it as an \\`agent\\` step when the workflow needs judgment or open-ended tool orchestration you can't hardcode — e.g. \"read these files and figure out what changed\", \"review these logs and summarise the failures\", \"call the right MCP tool to open a Linear issue based on this content\".\n\nWhen the workflow needs a **specific, deterministic** operation (like \\`execute_command wc -l file.ts\\` or a single fixed web-search call), prefer a plain \\`tool\\` step — cheaper, no LLM in the middle, and reproducible.\n\n# Workspace tool output shapes — read this before wiring a file-oriented workflow\n\nThe workspace tools you are most likely to compose with return **strings, not objects**, and the shared bridge-agent and \\`initData\\` re-threading guidance applies to them directly:\n\n- \\`find_files\\` returns a formatted \\`string\\` listing, and the entries are **bare basenames with no path prefix** (e.g. \\`app-tools.ts\\\\nserver.ts\\`). A downstream step told only \"summarise each file\" therefore has no idea which folder they live in.\n- \\`find_files\\` — inputSchema \\`{ path?: string, ... }\\`, outputSchema tree-formatted text (string).\n- \\`view\\` — inputSchema \\`{ path: string, ... }\\`, outputSchema \\`string | { __workspaceMedia: true, text: string, mediaType: string, data: string }\\`.\n\nTwo consequences, both covered by the shared playbook's worked examples:\n\n1. A string listing is not iterable, so \\`foreach\\` needs a bridge \\`agent\\` step with a top-level array \\`outputSchema\\` between the listing tool and the loop.\n2. Because the listing strips the folder path, the mapping that builds the bridge agent's prompt MUST re-thread the original path with \\`\\${initData.<pathField>}\\` alongside \\`\\${stepResults.<listing-step>}\\`. Skipping this is the most common cause of downstream \"file not found\" failures.\n\nAlways confirm these shapes against \\`list-available-tools\\` rather than trusting the summary above.\n\n# Mastra Code discovery notes\n\nThe three shared listing tools behave here exactly as the shared playbook describes; each row's \\`id\\` is the value you copy into \\`agentId\\` / \\`toolId\\` / \\`workflowId\\`. \\`list-available-workflows\\` includes both code-defined and Dynamic Workflows, and its catalog is always available on this surface.\n\nYour fourth tool is \\`save-workflow\\`, which persists and live-registers a definition. Make one sequential complete call per attempt, only after composition and the shared pre-action check.\n\n# Mastra Code execution and response protocol\n\n1. Complete discovery, composition, and the shared pre-action check before calling \\`save-workflow\\`.\n2. If the design needs helper workflows (for example, per-branch wrappers so \\`parallel\\` branches can consume different fields — see the shared nested-workflow guidance), save each helper FIRST, one complete definition per call, in dependency order. Each \\`save-workflow\\` success live-registers that helper, which makes it a valid \\`workflowId\\` for the next definition. Confirm with \\`list-available-workflows\\` before referencing it, and give each helper a real \\`id\\` and \\`description\\` — helpers are permanent, user-visible registry entries, not scratch space.\n3. Call \\`save-workflow\\` with one complete \\`{ id, description, inputSchema, outputSchema, graph }\\` definition for the requested workflow. There are no incremental setter tools and no parallel save attempts.\n4. Wait for the tool result. Success means exactly that \\`save-workflow\\` returned \\`{ ok: true, id }\\`; at that point the workflow is persisted and live-registered.\n5. If the tool rejects the definition, do not claim success. Use the returned diagnostics and authoritative discovery to correct every named issue, rerun the shared pre-action check, and make one sequential corrected complete save attempt. Do not rationalize a registry mismatch as a missing engine feature.\n6. After success, follow the shared summary rules and end with the concrete run command \\`/workflows run <id> {…}\\` for the requested workflow. If you saved helper workflows, name them so the user knows they now exist in the registry.\n`,\n // Same dynamic model resolver mastracode's main code-agent uses — picks up\n // the user's configured provider/model from session state. When the parent\n // code-agent delegates to this sub-agent (via `create-workflow`), the\n // request context propagates so the same model resolves.\n model: getDynamicModel,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,uBAAuB,2BAA2B;CAC7D,IAAI;CACJ,MAAM;CACN,aAAa;CACb,OAAO;GACJ,4BAA4B,aAAa;GACzC,4BAA4B,YAAY;GACxC,4BAA4B,gBAAgB;GAC5C,4BAA4B,eAAe;CAC9C;CACA,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDrB,OAAO;AACT,CAAC"}
1
+ {"version":3,"file":"workflow-builder-agent.js","names":[],"sources":["../../src/agents/workflow-builder-agent.ts"],"sourcesContent":["/**\n * Workflow Builder sub-agent.\n *\n * The parent code-agent (build/plan/explore modes) delegates to this agent\n * via the `create-workflow` tool. Keeping the long workflow-authoring system\n * prompt here — instead of inlining it into every parent mode — keeps the\n * parent modes lean and lets the same author logic ship to Studio later.\n *\n * The sub-agent's tool set is intentionally tiny: discover what's available,\n * construct the entire definition in one thought, save it. No setter loop,\n * no per-step mutations.\n */\nimport { createWorkflowBuilderAgent } from '@mastra/core/workflows/builder';\nimport { listAvailableAgentsTool } from '../tools/workflows/list-available-agents.js';\nimport { listAvailableClassifiersTool } from '../tools/workflows/list-available-classifiers.js';\nimport { listAvailableToolsTool } from '../tools/workflows/list-available-tools.js';\nimport { listAvailableWorkflowsTool } from '../tools/workflows/list-available-workflows.js';\nimport { saveWorkflowTool } from '../tools/workflows/save-workflow.js';\nimport { WORKFLOW_AUTHORING_TOOL_IDS } from '../tools/workflows/tool-ids.js';\nimport { getDynamicModel } from './model.js';\n\nexport const workflowBuilderAgent = createWorkflowBuilderAgent({\n id: 'workflow-builder',\n name: 'Workflow Builder',\n description: 'Turns plain-language workflow descriptions into runnable, persisted workflow definitions.',\n tools: {\n [WORKFLOW_AUTHORING_TOOL_IDS.listAgents]: listAvailableAgentsTool,\n [WORKFLOW_AUTHORING_TOOL_IDS.listClassifiers]: listAvailableClassifiersTool,\n [WORKFLOW_AUTHORING_TOOL_IDS.listTools]: listAvailableToolsTool,\n [WORKFLOW_AUTHORING_TOOL_IDS.listWorkflows]: listAvailableWorkflowsTool,\n [WORKFLOW_AUTHORING_TOOL_IDS.saveWorkflow]: saveWorkflowTool,\n },\n surfaceInstructions: `# Mastra Code authoring policy\n\nYour job: turn the user's verbatim plain-language request into a complete Dynamic Workflow definition and persist it with save-workflow. Success means save-workflow returned \\`{ ok: true, id }\\` for the workflow the user asked for; do not claim success before that result.\n\nSave each definition successfully **exactly once**: after \\`save-workflow\\` returns \\`{ ok: true, id }\\`, never save that workflow again. The workflow the user asked for is always saved LAST. You may save other workflows before it **only** when they are helper workflows the requested workflow references as \\`{ type: \"workflow\" }\\` entries — never to probe the schema or split one workflow into pieces the user did not ask for. A rejected save is not a successful save; correct the reported issues and make the one sequential corrected attempt permitted by the protocol below.\n\n# \\`code-agent\\` — when to use it as an agent step\n\nThe Mastra instance registers \\`code-agent\\` (mastracode's coding agent) alongside the workflow-builder. When discovery surfaces it in \\`list-available-agents\\`, know that under the hood it has full access to workspace tools (view / edit / run commands), MCP tools, and web search — and it *reasons* over a prompt to pick the right ones.\n\nUse it as an \\`agent\\` step when the workflow needs judgment or open-ended tool orchestration you can't hardcode — e.g. \"read these files and figure out what changed\", \"review these logs and summarise the failures\", \"call the right MCP tool to open a Linear issue based on this content\".\n\nWhen the workflow needs a **specific, deterministic** operation (like \\`execute_command wc -l file.ts\\` or a single fixed web-search call), prefer a plain \\`tool\\` step — cheaper, no LLM in the middle, and reproducible.\n\n# Workspace tool output shapes — read this before wiring a file-oriented workflow\n\nThe workspace tools you are most likely to compose with return **strings, not objects**, and the shared bridge-agent and \\`initData\\` re-threading guidance applies to them directly:\n\n- \\`find_files\\` returns a formatted \\`string\\` listing, and the entries are **bare basenames with no path prefix** (e.g. \\`app-tools.ts\\\\nserver.ts\\`). A downstream step told only \"summarise each file\" therefore has no idea which folder they live in.\n- \\`find_files\\` — inputSchema \\`{ path?: string, ... }\\`, outputSchema tree-formatted text (string).\n- \\`view\\` — inputSchema \\`{ path: string, ... }\\`, outputSchema \\`string | { __workspaceMedia: true, text: string, mediaType: string, data: string }\\`.\n\nTwo consequences, both covered by the shared playbook's worked examples:\n\n1. A string listing is not iterable, so \\`foreach\\` needs a bridge \\`agent\\` step with a top-level array \\`outputSchema\\` between the listing tool and the loop.\n2. Because the listing strips the folder path, the mapping that builds the bridge agent's prompt MUST re-thread the original path with \\`\\${initData.<pathField>}\\` alongside \\`\\${stepResults.<listing-step>}\\`. Skipping this is the most common cause of downstream \"file not found\" failures.\n\nAlways confirm these shapes against \\`list-available-tools\\` rather than trusting the summary above.\n\n# Mastra Code discovery notes\n\nThe four shared listing tools behave here exactly as the shared playbook describes; each row's \\`id\\` is the value you copy into \\`agentId\\` / \\`classifierId\\` / \\`toolId\\` / \\`workflowId\\`. \\`list-available-classifiers\\` includes configured question metadata and stable \\`values.<question>\\` paths for conditional routing. \\`list-available-workflows\\` includes both code-defined and Dynamic Workflows, and its catalog is always available on this surface.\n\nYour fifth tool is \\`save-workflow\\`, which persists and live-registers a definition. Make one sequential complete call per attempt, only after composition and the shared pre-action check.\n\n# Mastra Code execution and response protocol\n\n1. Complete discovery, composition, and the shared pre-action check before calling \\`save-workflow\\`.\n2. If the design needs helper workflows (for example, per-branch wrappers so \\`parallel\\` branches can consume different fields — see the shared nested-workflow guidance), save each helper FIRST, one complete definition per call, in dependency order. Each \\`save-workflow\\` success live-registers that helper, which makes it a valid \\`workflowId\\` for the next definition. Confirm with \\`list-available-workflows\\` before referencing it, and give each helper a real \\`id\\` and \\`description\\` — helpers are permanent, user-visible registry entries, not scratch space.\n3. Call \\`save-workflow\\` with one complete \\`{ id, description, inputSchema, outputSchema, graph }\\` definition for the requested workflow. There are no incremental setter tools and no parallel save attempts.\n4. Wait for the tool result. Success means exactly that \\`save-workflow\\` returned \\`{ ok: true, id }\\`; at that point the workflow is persisted and live-registered.\n5. If the tool rejects the definition, do not claim success. Use the returned diagnostics and authoritative discovery to correct every named issue, rerun the shared pre-action check, and make one sequential corrected complete save attempt. Do not rationalize a registry mismatch as a missing engine feature.\n6. After success, follow the shared summary rules and end with the concrete run command \\`/workflows run <id> {…}\\` for the requested workflow. If you saved helper workflows, name them so the user knows they now exist in the registry.\n`,\n // Same dynamic model resolver mastracode's main code-agent uses — picks up\n // the user's configured provider/model from session state. When the parent\n // code-agent delegates to this sub-agent (via `create-workflow`), the\n // request context propagates so the same model resolves.\n model: getDynamicModel,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,uBAAuB,2BAA2B;CAC7D,IAAI;CACJ,MAAM;CACN,aAAa;CACb,OAAO;GACJ,4BAA4B,aAAa;GACzC,4BAA4B,kBAAkB;GAC9C,4BAA4B,YAAY;GACxC,4BAA4B,gBAAgB;GAC5C,4BAA4B,eAAe;CAC9C;CACA,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDrB,OAAO;AACT,CAAC"}
@@ -64,7 +64,7 @@ export declare class GoalManager {
64
64
  * Load the objective from ThreadState (called on thread switch). Falls back to
65
65
  * the legacy thread-metadata goal for threads created before this migration.
66
66
  */
67
- loadFromThread(state: GoalManagerState): Promise<void>;
67
+ loadFromThread(state: GoalManagerState, isCurrent?: () => boolean): Promise<void>;
68
68
  /**
69
69
  * Legacy entry point retained for thread-switch call sites that only have the
70
70
  * thread metadata available. Hydrates from a previously-persisted GoalState.
@@ -1 +1 @@
1
- {"version":3,"file":"goal-manager.d.ts","sourceRoot":"","sources":["../src/goal-manager.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAI9E,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChG,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B;AAMD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtD;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAMD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAWpC,qBAAa,WAAW;IACtB,kGAAkG;IAClG,OAAO,CAAC,MAAM,CAAuD;IACrE,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,6BAA6B,CAAS;IAM9C,OAAO,IAAI,SAAS,GAAG,IAAI;IAuB3B,QAAQ,IAAI,OAAO;IAInB,yBAAyB,IAAI,IAAI;IAIjC,gCAAgC,IAAI,OAAO;IAU3C;;;;OAIG;IACG,OAAO,CACX,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,MAA0B,GACnC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA0B5B;;;OAGG;IACG,mBAAmB,CACvB,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAsB5B,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAOxC,MAAM,IAAI,SAAS,GAAG,IAAI;IAO1B,QAAQ,IAAI,IAAI;IAMhB,KAAK,IAAI,IAAI;IAOb;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;IAUnF;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD1D;;;OAGG;IACG,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB5D;;;OAGG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI;IA0B3E,OAAO,CAAC,QAAQ;IAQhB,kFAAkF;IAClF,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,WAAW;CAmBpB"}
1
+ {"version":3,"file":"goal-manager.d.ts","sourceRoot":"","sources":["../src/goal-manager.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAI9E,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChG,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B;AAMD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtD;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAMD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAWpC,qBAAa,WAAW;IACtB,kGAAkG;IAClG,OAAO,CAAC,MAAM,CAAuD;IACrE,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,6BAA6B,CAAS;IAM9C,OAAO,IAAI,SAAS,GAAG,IAAI;IAuB3B,QAAQ,IAAI,OAAO;IAInB,yBAAyB,IAAI,IAAI;IAIjC,gCAAgC,IAAI,OAAO;IAU3C;;;;OAIG;IACG,OAAO,CACX,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,MAA0B,GACnC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA0B5B;;;OAGG;IACG,mBAAmB,CACvB,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAsB5B,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAOxC,MAAM,IAAI,SAAS,GAAG,IAAI;IAO1B,QAAQ,IAAI,IAAI;IAMhB,KAAK,IAAI,IAAI;IAOb;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,GAAG,IAAI;IAUnF;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD1D;;;OAGG;IACG,cAAc,CAAC,KAAK,EAAE,gBAAgB,EAAE,SAAS,GAAE,MAAM,OAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBnG;;;OAGG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI;IA0B3E,OAAO,CAAC,QAAQ;IAQhB,kFAAkF;IAClF,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,WAAW;CAmBpB"}
@@ -197,24 +197,23 @@ var GoalManager = class {
197
197
  * Load the objective from ThreadState (called on thread switch). Falls back to
198
198
  * the legacy thread-metadata goal for threads created before this migration.
199
199
  */
200
- async loadFromThread(state) {
201
- this.persistGoalOnNextThreadCreate = false;
200
+ async loadFromThread(state, isCurrent = () => true) {
202
201
  const threadId = state.session.thread.getId();
203
202
  const agent = this.getAgent(state);
204
- this.threadId = threadId ?? void 0;
205
- this.agentId = agent?.id;
203
+ let nextRecord = null;
206
204
  if (agent && threadId) try {
207
205
  const record = await agent.getObjective({ threadId });
208
- if (record) {
209
- this.record = {
210
- ...record,
211
- id: record.id ?? randomUUID(),
212
- activeDurationMs: normalizeActiveDurationMs(record.activeDurationMs)
213
- };
214
- return;
215
- }
206
+ if (record) nextRecord = {
207
+ ...record,
208
+ id: record.id ?? randomUUID(),
209
+ activeDurationMs: normalizeActiveDurationMs(record.activeDurationMs)
210
+ };
216
211
  } catch {}
217
- this.record = null;
212
+ if (!isCurrent()) return;
213
+ this.persistGoalOnNextThreadCreate = false;
214
+ this.threadId = threadId ?? void 0;
215
+ this.agentId = agent?.id;
216
+ this.record = nextRecord;
218
217
  }
219
218
  /**
220
219
  * Legacy entry point retained for thread-switch call sites that only have the
@@ -1 +1 @@
1
- {"version":3,"file":"goal-manager.js","names":[],"sources":["../src/goal-manager.ts"],"sourcesContent":["/**\n * GoalManager — persistent cross-turn goals, backed by the Agent's native goal\n * mechanism.\n *\n * The objective lives in the durable `threadState` `'goal'` slot (via\n * `agent.setObjective`/`getObjective`/`clearObjective`/`updateObjectiveOptions`)\n * and is judged in-loop by the core goal step. This manager is a thin adapter:\n * it keeps a synchronous in-memory view of the current objective for the TUI\n * (status line, modal, keyboard shortcuts) and delegates persistence to the\n * agent. There is no standalone judge agent and no between-turn re-invocation —\n * the core goal step drives continuation and surfaces progress via `goal` stream\n * chunks.\n */\nimport { randomUUID } from 'node:crypto';\nimport { getGoalActivityDurationMs } from '@mastra/core/agent';\nimport type { Agent } from '@mastra/core/agent';\nimport type { AgentController, Session } from '@mastra/core/agent-controller';\nimport type { GoalObjectiveRecord } from '@mastra/core/storage';\nimport { loadSettings } from './onboarding/settings.js';\n\nexport interface GoalManagerState<TState extends Record<string, unknown> = Record<string, unknown>> {\n controller: AgentController<TState>;\n session: Session<TState>;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type GoalStatus = 'active' | 'paused' | 'done';\n\n/**\n * TUI-facing view of a goal. Derived from the durable {@link GoalObjectiveRecord}\n * plus the effective judge/max-runs settings, with display-only timer fields and\n * a stable `id` used to match plan-started goals.\n */\nexport interface GoalState {\n id: string;\n objective: string;\n status: GoalStatus;\n turnsUsed: number;\n maxTurns: number;\n judgeModelId: string;\n startedAt: string;\n activeStartedAt?: string;\n activeDurationMs?: number;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nexport const DEFAULT_MAX_TURNS = 50;\nconst THREAD_GOAL_KEY = 'goal';\n\nfunction normalizeActiveDurationMs(value: number | undefined): number {\n return value !== undefined && Number.isFinite(value) && value >= 0 ? value : 0;\n}\n\n// =============================================================================\n// GoalManager\n// =============================================================================\n\nexport class GoalManager {\n /** Synchronous in-memory view of the active objective record (source of truth is ThreadState). */\n private record: (GoalObjectiveRecord & { id: string }) | null = null;\n private threadId: string | undefined;\n private agentId: string | undefined;\n private persistGoalOnNextThreadCreate = false;\n\n // ---------------------------------------------------------------------------\n // Synchronous TUI surface\n // ---------------------------------------------------------------------------\n\n getGoal(): GoalState | null {\n if (!this.record) return null;\n const { judgeModelId, maxTurns } = this.effectiveSettings(this.record);\n return {\n id: this.record.id,\n objective: this.record.objective,\n status: this.record.status,\n turnsUsed: this.record.runsUsed,\n maxTurns,\n judgeModelId,\n startedAt: new Date(this.record.startedAt).toISOString(),\n activeDurationMs:\n this.agentId && this.threadId\n ? getGoalActivityDurationMs({\n agentId: this.agentId,\n threadId: this.threadId,\n objectiveId: this.record.id,\n activeDurationMs: this.record.activeDurationMs,\n })\n : normalizeActiveDurationMs(this.record.activeDurationMs),\n };\n }\n\n isActive(): boolean {\n return this.record?.status === 'active';\n }\n\n persistOnNextThreadCreate(): void {\n this.persistGoalOnNextThreadCreate = true;\n }\n\n consumePersistOnNextThreadCreate(): boolean {\n if (!this.persistGoalOnNextThreadCreate) return false;\n this.persistGoalOnNextThreadCreate = false;\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Objective lifecycle (ThreadState-backed via the agent)\n // ---------------------------------------------------------------------------\n\n /**\n * Set a new objective. Persists to ThreadState via `agent.setObjective` and\n * updates the in-memory view. Only the provided settings are persisted into\n * the record; unset ones fall back to the agent's `goal` config at read time.\n */\n async setGoal(\n state: GoalManagerState,\n objective: string,\n judgeModelId: string,\n maxTurns: number = DEFAULT_MAX_TURNS,\n ): Promise<GoalState | null> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n const now = Date.now();\n const id = randomUUID();\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n\n if (agent && threadId) {\n const persisted = await agent.setObjective(objective, {\n id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n this.record = persisted\n ? { ...persisted, id: persisted.id ?? id }\n : this.localRecord(objective, judgeModelId, maxTurns, now, id);\n } else {\n this.record = this.localRecord(objective, judgeModelId, maxTurns, now, id);\n }\n\n return this.getGoal();\n }\n\n /**\n * Update the judge model / max-runs defaults. Persists into the active record\n * (so the override is remembered in thread state) when a goal is set.\n */\n async updateJudgeDefaults(\n state: GoalManagerState,\n judgeModelId: string,\n maxTurns: number,\n ): Promise<GoalState | null> {\n if (!this.record) return null;\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n if (agent && threadId) {\n const updated = await agent.updateObjectiveOptions({\n threadId,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n if (updated) this.record = { ...updated, id: this.record.id };\n } else {\n this.record = {\n ...this.record,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n updatedAt: Date.now(),\n };\n }\n return this.getGoal();\n }\n\n pause(reason?: string): GoalState | null {\n if (this.record && this.record.status === 'active') {\n this.record = { ...this.record, status: 'paused', pausedReason: reason, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n resume(): GoalState | null {\n if (this.record && this.record.status === 'paused') {\n this.record = { ...this.record, status: 'active', pausedReason: undefined, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n markDone(): void {\n if (this.record) {\n this.record = { ...this.record, status: 'done', updatedAt: Date.now() };\n }\n }\n\n clear(): void {\n this.record = null;\n this.threadId = undefined;\n this.agentId = undefined;\n this.persistGoalOnNextThreadCreate = false;\n }\n\n /**\n * Sync the latest objective record from ThreadState into the in-memory view.\n * Called from the `goal` stream-chunk handler after each evaluation.\n */\n applyEvaluation(update: { runsUsed: number; status: GoalStatus }): GoalState | null {\n if (!this.record) return null;\n this.record = { ...this.record, runsUsed: update.runsUsed, status: update.status, updatedAt: Date.now() };\n return this.getGoal();\n }\n\n // ---------------------------------------------------------------------------\n // Persistence\n // ---------------------------------------------------------------------------\n\n /**\n * Persist the active objective to ThreadState via the agent. The objective\n * record is the source of truth; the legacy thread-metadata key is cleared so\n * stale state from older sessions does not resurface.\n */\n async saveToThread(state: GoalManagerState): Promise<void> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n try {\n if (agent && threadId) {\n if (this.record) {\n // Push the current status/options into the existing record. If no\n // record is persisted yet (e.g. first save), create one.\n const updated = await agent.updateObjectiveOptions({\n threadId,\n status: this.record.status,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n if (!updated) {\n // No persisted record yet: create one. `setObjective` always writes\n // `status: 'active'`, so re-apply the in-memory status afterwards if\n // the local goal was already paused/done — otherwise the resumed\n // thread state would no longer match the in-memory state.\n const desiredStatus = this.record.status;\n await agent.setObjective(this.record.objective, {\n id: this.record.id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n activeDurationMs: normalizeActiveDurationMs(this.record.activeDurationMs),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n if (desiredStatus !== 'active') {\n await agent.updateObjectiveOptions({\n threadId,\n status: desiredStatus,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n });\n }\n }\n } else {\n await agent.clearObjective({ threadId });\n }\n }\n // Clear any legacy thread-metadata goal so it can't shadow the record.\n await state.session.thread.setSetting({ key: THREAD_GOAL_KEY, value: undefined });\n } catch {\n // Persistence is not critical.\n }\n }\n\n /**\n * Load the objective from ThreadState (called on thread switch). Falls back to\n * the legacy thread-metadata goal for threads created before this migration.\n */\n async loadFromThread(state: GoalManagerState): Promise<void> {\n this.persistGoalOnNextThreadCreate = false;\n\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n if (agent && threadId) {\n try {\n const record = await agent.getObjective({ threadId });\n if (record) {\n this.record = {\n ...record,\n id: record.id ?? randomUUID(),\n activeDurationMs: normalizeActiveDurationMs(record.activeDurationMs),\n };\n return;\n }\n } catch {\n // fall through to legacy metadata\n }\n }\n this.record = null;\n }\n\n /**\n * Legacy entry point retained for thread-switch call sites that only have the\n * thread metadata available. Hydrates from a previously-persisted GoalState.\n */\n loadFromThreadMetadata(metadata: Record<string, unknown> | undefined): void {\n const saved = metadata?.[THREAD_GOAL_KEY] as Partial<GoalState> | undefined;\n this.persistGoalOnNextThreadCreate = false;\n this.threadId = undefined;\n this.agentId = undefined;\n if (saved && saved.objective && saved.status) {\n this.record = {\n objective: saved.objective,\n status: saved.status,\n runsUsed: saved.turnsUsed ?? 0,\n activeDurationMs: normalizeActiveDurationMs(saved.activeDurationMs),\n maxRuns: saved.maxTurns ?? DEFAULT_MAX_TURNS,\n judgeModelId: saved.judgeModelId ?? '',\n startedAt: saved.startedAt ? Date.parse(saved.startedAt) || Date.now() : Date.now(),\n updatedAt: Date.now(),\n id: saved.id ?? randomUUID(),\n };\n } else {\n this.record = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private\n // ---------------------------------------------------------------------------\n\n private getAgent(state: GoalManagerState): Agent | undefined {\n try {\n return state.controller.getCurrentAgent(state.session);\n } catch {\n return undefined;\n }\n }\n\n /** Resolve effective judge model + max runs (record value → settings default). */\n private effectiveSettings(record: GoalObjectiveRecord): { judgeModelId: string; maxTurns: number } {\n const settings = loadSettings();\n return {\n judgeModelId: record.judgeModelId ?? settings.models.goalJudgeModel ?? '',\n maxTurns: record.maxRuns ?? settings.models.goalMaxTurns ?? DEFAULT_MAX_TURNS,\n };\n }\n\n private localRecord(\n objective: string,\n judgeModelId: string,\n maxTurns: number,\n now: number,\n id: string,\n ): GoalObjectiveRecord & { id: string } {\n return {\n objective,\n status: 'active',\n runsUsed: 0,\n activeDurationMs: 0,\n maxRuns: maxTurns,\n ...(judgeModelId ? { judgeModelId } : {}),\n startedAt: now,\n updatedAt: now,\n id,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"goal-manager.js","names":[],"sources":["../src/goal-manager.ts"],"sourcesContent":["/**\n * GoalManager — persistent cross-turn goals, backed by the Agent's native goal\n * mechanism.\n *\n * The objective lives in the durable `threadState` `'goal'` slot (via\n * `agent.setObjective`/`getObjective`/`clearObjective`/`updateObjectiveOptions`)\n * and is judged in-loop by the core goal step. This manager is a thin adapter:\n * it keeps a synchronous in-memory view of the current objective for the TUI\n * (status line, modal, keyboard shortcuts) and delegates persistence to the\n * agent. There is no standalone judge agent and no between-turn re-invocation —\n * the core goal step drives continuation and surfaces progress via `goal` stream\n * chunks.\n */\nimport { randomUUID } from 'node:crypto';\nimport { getGoalActivityDurationMs } from '@mastra/core/agent';\nimport type { Agent } from '@mastra/core/agent';\nimport type { AgentController, Session } from '@mastra/core/agent-controller';\nimport type { GoalObjectiveRecord } from '@mastra/core/storage';\nimport { loadSettings } from './onboarding/settings.js';\n\nexport interface GoalManagerState<TState extends Record<string, unknown> = Record<string, unknown>> {\n controller: AgentController<TState>;\n session: Session<TState>;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type GoalStatus = 'active' | 'paused' | 'done';\n\n/**\n * TUI-facing view of a goal. Derived from the durable {@link GoalObjectiveRecord}\n * plus the effective judge/max-runs settings, with display-only timer fields and\n * a stable `id` used to match plan-started goals.\n */\nexport interface GoalState {\n id: string;\n objective: string;\n status: GoalStatus;\n turnsUsed: number;\n maxTurns: number;\n judgeModelId: string;\n startedAt: string;\n activeStartedAt?: string;\n activeDurationMs?: number;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nexport const DEFAULT_MAX_TURNS = 50;\nconst THREAD_GOAL_KEY = 'goal';\n\nfunction normalizeActiveDurationMs(value: number | undefined): number {\n return value !== undefined && Number.isFinite(value) && value >= 0 ? value : 0;\n}\n\n// =============================================================================\n// GoalManager\n// =============================================================================\n\nexport class GoalManager {\n /** Synchronous in-memory view of the active objective record (source of truth is ThreadState). */\n private record: (GoalObjectiveRecord & { id: string }) | null = null;\n private threadId: string | undefined;\n private agentId: string | undefined;\n private persistGoalOnNextThreadCreate = false;\n\n // ---------------------------------------------------------------------------\n // Synchronous TUI surface\n // ---------------------------------------------------------------------------\n\n getGoal(): GoalState | null {\n if (!this.record) return null;\n const { judgeModelId, maxTurns } = this.effectiveSettings(this.record);\n return {\n id: this.record.id,\n objective: this.record.objective,\n status: this.record.status,\n turnsUsed: this.record.runsUsed,\n maxTurns,\n judgeModelId,\n startedAt: new Date(this.record.startedAt).toISOString(),\n activeDurationMs:\n this.agentId && this.threadId\n ? getGoalActivityDurationMs({\n agentId: this.agentId,\n threadId: this.threadId,\n objectiveId: this.record.id,\n activeDurationMs: this.record.activeDurationMs,\n })\n : normalizeActiveDurationMs(this.record.activeDurationMs),\n };\n }\n\n isActive(): boolean {\n return this.record?.status === 'active';\n }\n\n persistOnNextThreadCreate(): void {\n this.persistGoalOnNextThreadCreate = true;\n }\n\n consumePersistOnNextThreadCreate(): boolean {\n if (!this.persistGoalOnNextThreadCreate) return false;\n this.persistGoalOnNextThreadCreate = false;\n return true;\n }\n\n // ---------------------------------------------------------------------------\n // Objective lifecycle (ThreadState-backed via the agent)\n // ---------------------------------------------------------------------------\n\n /**\n * Set a new objective. Persists to ThreadState via `agent.setObjective` and\n * updates the in-memory view. Only the provided settings are persisted into\n * the record; unset ones fall back to the agent's `goal` config at read time.\n */\n async setGoal(\n state: GoalManagerState,\n objective: string,\n judgeModelId: string,\n maxTurns: number = DEFAULT_MAX_TURNS,\n ): Promise<GoalState | null> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n const now = Date.now();\n const id = randomUUID();\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n\n if (agent && threadId) {\n const persisted = await agent.setObjective(objective, {\n id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n this.record = persisted\n ? { ...persisted, id: persisted.id ?? id }\n : this.localRecord(objective, judgeModelId, maxTurns, now, id);\n } else {\n this.record = this.localRecord(objective, judgeModelId, maxTurns, now, id);\n }\n\n return this.getGoal();\n }\n\n /**\n * Update the judge model / max-runs defaults. Persists into the active record\n * (so the override is remembered in thread state) when a goal is set.\n */\n async updateJudgeDefaults(\n state: GoalManagerState,\n judgeModelId: string,\n maxTurns: number,\n ): Promise<GoalState | null> {\n if (!this.record) return null;\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n if (agent && threadId) {\n const updated = await agent.updateObjectiveOptions({\n threadId,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n });\n if (updated) this.record = { ...updated, id: this.record.id };\n } else {\n this.record = {\n ...this.record,\n ...(judgeModelId ? { judgeModelId } : {}),\n maxRuns: maxTurns,\n updatedAt: Date.now(),\n };\n }\n return this.getGoal();\n }\n\n pause(reason?: string): GoalState | null {\n if (this.record && this.record.status === 'active') {\n this.record = { ...this.record, status: 'paused', pausedReason: reason, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n resume(): GoalState | null {\n if (this.record && this.record.status === 'paused') {\n this.record = { ...this.record, status: 'active', pausedReason: undefined, updatedAt: Date.now() };\n }\n return this.getGoal();\n }\n\n markDone(): void {\n if (this.record) {\n this.record = { ...this.record, status: 'done', updatedAt: Date.now() };\n }\n }\n\n clear(): void {\n this.record = null;\n this.threadId = undefined;\n this.agentId = undefined;\n this.persistGoalOnNextThreadCreate = false;\n }\n\n /**\n * Sync the latest objective record from ThreadState into the in-memory view.\n * Called from the `goal` stream-chunk handler after each evaluation.\n */\n applyEvaluation(update: { runsUsed: number; status: GoalStatus }): GoalState | null {\n if (!this.record) return null;\n this.record = { ...this.record, runsUsed: update.runsUsed, status: update.status, updatedAt: Date.now() };\n return this.getGoal();\n }\n\n // ---------------------------------------------------------------------------\n // Persistence\n // ---------------------------------------------------------------------------\n\n /**\n * Persist the active objective to ThreadState via the agent. The objective\n * record is the source of truth; the legacy thread-metadata key is cleared so\n * stale state from older sessions does not resurface.\n */\n async saveToThread(state: GoalManagerState): Promise<void> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n try {\n if (agent && threadId) {\n if (this.record) {\n // Push the current status/options into the existing record. If no\n // record is persisted yet (e.g. first save), create one.\n const updated = await agent.updateObjectiveOptions({\n threadId,\n status: this.record.status,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n if (!updated) {\n // No persisted record yet: create one. `setObjective` always writes\n // `status: 'active'`, so re-apply the in-memory status afterwards if\n // the local goal was already paused/done — otherwise the resumed\n // thread state would no longer match the in-memory state.\n const desiredStatus = this.record.status;\n await agent.setObjective(this.record.objective, {\n id: this.record.id,\n threadId,\n resourceId: state.session.identity.getResourceId(),\n activeDurationMs: normalizeActiveDurationMs(this.record.activeDurationMs),\n ...(this.record.judgeModelId ? { judgeModelId: this.record.judgeModelId } : {}),\n ...(this.record.maxRuns !== undefined ? { maxRuns: this.record.maxRuns } : {}),\n });\n if (desiredStatus !== 'active') {\n await agent.updateObjectiveOptions({\n threadId,\n status: desiredStatus,\n ...(this.record.pausedReason ? { pausedReason: this.record.pausedReason } : {}),\n });\n }\n }\n } else {\n await agent.clearObjective({ threadId });\n }\n }\n // Clear any legacy thread-metadata goal so it can't shadow the record.\n await state.session.thread.setSetting({ key: THREAD_GOAL_KEY, value: undefined });\n } catch {\n // Persistence is not critical.\n }\n }\n\n /**\n * Load the objective from ThreadState (called on thread switch). Falls back to\n * the legacy thread-metadata goal for threads created before this migration.\n */\n async loadFromThread(state: GoalManagerState, isCurrent: () => boolean = () => true): Promise<void> {\n const threadId = state.session.thread.getId();\n const agent = this.getAgent(state);\n let nextRecord: typeof this.record = null;\n if (agent && threadId) {\n try {\n const record = await agent.getObjective({ threadId });\n if (record) {\n nextRecord = {\n ...record,\n id: record.id ?? randomUUID(),\n activeDurationMs: normalizeActiveDurationMs(record.activeDurationMs),\n };\n }\n } catch {\n // fall through to legacy metadata\n }\n }\n if (!isCurrent()) return;\n this.persistGoalOnNextThreadCreate = false;\n this.threadId = threadId ?? undefined;\n this.agentId = agent?.id;\n this.record = nextRecord;\n }\n\n /**\n * Legacy entry point retained for thread-switch call sites that only have the\n * thread metadata available. Hydrates from a previously-persisted GoalState.\n */\n loadFromThreadMetadata(metadata: Record<string, unknown> | undefined): void {\n const saved = metadata?.[THREAD_GOAL_KEY] as Partial<GoalState> | undefined;\n this.persistGoalOnNextThreadCreate = false;\n this.threadId = undefined;\n this.agentId = undefined;\n if (saved && saved.objective && saved.status) {\n this.record = {\n objective: saved.objective,\n status: saved.status,\n runsUsed: saved.turnsUsed ?? 0,\n activeDurationMs: normalizeActiveDurationMs(saved.activeDurationMs),\n maxRuns: saved.maxTurns ?? DEFAULT_MAX_TURNS,\n judgeModelId: saved.judgeModelId ?? '',\n startedAt: saved.startedAt ? Date.parse(saved.startedAt) || Date.now() : Date.now(),\n updatedAt: Date.now(),\n id: saved.id ?? randomUUID(),\n };\n } else {\n this.record = null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private\n // ---------------------------------------------------------------------------\n\n private getAgent(state: GoalManagerState): Agent | undefined {\n try {\n return state.controller.getCurrentAgent(state.session);\n } catch {\n return undefined;\n }\n }\n\n /** Resolve effective judge model + max runs (record value → settings default). */\n private effectiveSettings(record: GoalObjectiveRecord): { judgeModelId: string; maxTurns: number } {\n const settings = loadSettings();\n return {\n judgeModelId: record.judgeModelId ?? settings.models.goalJudgeModel ?? '',\n maxTurns: record.maxRuns ?? settings.models.goalMaxTurns ?? DEFAULT_MAX_TURNS,\n };\n }\n\n private localRecord(\n objective: string,\n judgeModelId: string,\n maxTurns: number,\n now: number,\n id: string,\n ): GoalObjectiveRecord & { id: string } {\n return {\n objective,\n status: 'active',\n runsUsed: 0,\n activeDurationMs: 0,\n maxRuns: maxTurns,\n ...(judgeModelId ? { judgeModelId } : {}),\n startedAt: now,\n updatedAt: now,\n id,\n };\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/hooks/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E,eAAO,MAAM,YAAY,EAAE,aAAa,EAevC,CAAC;AAEF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,SAAqB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAQrH;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,SAAqB,GAAG,MAAM,CAElG;AAED,wBAAgB,kBAAkB,CAAC,aAAa,SAAqB,EAAE,OAAO,SAAe,GAAG,MAAM,CAErG"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/hooks/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E,eAAO,MAAM,YAAY,EAAE,aAAa,EAevC,CAAC;AAEF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,SAAqB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAUrH;AAUD,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,SAAqB,GAAG,MAAM,CAElG;AAED,wBAAgB,kBAAkB,CAAC,aAAa,SAAqB,EAAE,OAAO,SAAe,GAAG,MAAM,CAErG"}
@@ -27,7 +27,14 @@ const VALID_EVENTS = [
27
27
  function loadHooksConfig(projectDir, configDirName = DEFAULT_CONFIG_DIR, homeDir) {
28
28
  const globalPath = getGlobalHooksPath(configDirName, homeDir);
29
29
  const projectPath = getProjectHooksPath(projectDir, configDirName);
30
- return mergeConfigs(loadSingleConfig(globalPath), loadSingleConfig(projectPath));
30
+ return mergeConfigs(loadSingleConfig(globalPath), isSameFile(globalPath, projectPath) ? {} : loadSingleConfig(projectPath));
31
+ }
32
+ function isSameFile(a, b) {
33
+ try {
34
+ return fs$1.realpathSync(a) === fs$1.realpathSync(b);
35
+ } catch {
36
+ return path$1.resolve(a) === path$1.resolve(b);
37
+ }
31
38
  }
32
39
  function getProjectHooksPath(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
33
40
  return path$1.join(projectDir, configDirName, "hooks.json");
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["path","os","fs"],"sources":["../../src/hooks/config.ts"],"sourcesContent":["/**\n * Hook configuration loading from filesystem.\n * Loads from global (~/.mastracode/hooks.json) and project (.mastracode/hooks.json).\n * Global hooks run first, project hooks append.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport type { HooksConfig, HookDefinition, HookEventName } from './types.js';\n\nexport const VALID_EVENTS: HookEventName[] = [\n 'PreToolUse',\n 'PostToolUse',\n 'Stop',\n 'UserPromptSubmit',\n 'SessionStart',\n 'SessionEnd',\n 'Notification',\n 'AgentStart',\n 'AgentEnd',\n 'PermissionRequest',\n 'PermissionResult',\n 'Interrupt',\n 'SubagentStart',\n 'SubagentEnd',\n];\n\nexport function loadHooksConfig(projectDir: string, configDirName = DEFAULT_CONFIG_DIR, homeDir?: string): HooksConfig {\n const globalPath = getGlobalHooksPath(configDirName, homeDir);\n const projectPath = getProjectHooksPath(projectDir, configDirName);\n\n const globalConfig = loadSingleConfig(globalPath);\n const projectConfig = loadSingleConfig(projectPath);\n\n return mergeConfigs(globalConfig, projectConfig);\n}\n\nexport function getProjectHooksPath(projectDir: string, configDirName = DEFAULT_CONFIG_DIR): string {\n return path.join(projectDir, configDirName, 'hooks.json');\n}\n\nexport function getGlobalHooksPath(configDirName = DEFAULT_CONFIG_DIR, homeDir = os.homedir()): string {\n return path.join(homeDir, configDirName, 'hooks.json');\n}\n\nfunction loadSingleConfig(filePath: string): HooksConfig {\n try {\n if (!fs.existsSync(filePath)) return {};\n const raw = fs.readFileSync(filePath, 'utf-8');\n return validateConfig(JSON.parse(raw));\n } catch {\n return {};\n }\n}\n\nfunction validateConfig(raw: unknown): HooksConfig {\n if (!raw || typeof raw !== 'object') return {};\n\n const config: HooksConfig = {};\n const obj = raw as Record<string, unknown>;\n\n for (const event of VALID_EVENTS) {\n if (Array.isArray(obj[event])) {\n const hooks = (obj[event] as unknown[]).filter(isValidHook);\n if (hooks.length > 0) {\n config[event] = hooks;\n }\n }\n }\n\n return config;\n}\n\nfunction isValidHook(raw: unknown): raw is HookDefinition {\n if (!raw || typeof raw !== 'object') return false;\n const obj = raw as Record<string, unknown>;\n return obj.type === 'command' && typeof obj.command === 'string';\n}\n\nfunction mergeConfigs(global: HooksConfig, project: HooksConfig): HooksConfig {\n const merged: HooksConfig = {};\n\n for (const event of VALID_EVENTS) {\n const combined = [...(global[event] ?? []), ...(project[event] ?? [])];\n if (combined.length > 0) {\n merged[event] = combined;\n }\n }\n\n return merged;\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAa,eAAgC;CAC3C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,gBAAgB,YAAoB,gBAAgB,oBAAoB,SAA+B;CACrH,MAAM,aAAa,mBAAmB,eAAe,OAAO;CAC5D,MAAM,cAAc,oBAAoB,YAAY,aAAa;CAKjE,OAAO,aAHc,iBAAiB,UAGP,GAFT,iBAAiB,WAEO,CAAC;AACjD;AAEA,SAAgB,oBAAoB,YAAoB,gBAAgB,oBAA4B;CAClG,OAAOA,OAAK,KAAK,YAAY,eAAe,YAAY;AAC1D;AAEA,SAAgB,mBAAmB,gBAAgB,oBAAoB,UAAUC,KAAG,QAAQ,GAAW;CACrG,OAAOD,OAAK,KAAK,SAAS,eAAe,YAAY;AACvD;AAEA,SAAS,iBAAiB,UAA+B;CACvD,IAAI;EACF,IAAI,CAACE,KAAG,WAAW,QAAQ,GAAG,OAAO,CAAC;EACtC,MAAM,MAAMA,KAAG,aAAa,UAAU,OAAO;EAC7C,OAAO,eAAe,KAAK,MAAM,GAAG,CAAC;CACvC,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,SAAS,eAAe,KAA2B;CACjD,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO,CAAC;CAE7C,MAAM,SAAsB,CAAC;CAC7B,MAAM,MAAM;CAEZ,KAAK,MAAM,SAAS,cAClB,IAAI,MAAM,QAAQ,IAAI,MAAM,GAAG;EAC7B,MAAM,QAAS,IAAI,MAAM,CAAe,OAAO,WAAW;EAC1D,IAAI,MAAM,SAAS,GACjB,OAAO,SAAS;CAEpB;CAGF,OAAO;AACT;AAEA,SAAS,YAAY,KAAqC;CACxD,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO;CAC5C,MAAM,MAAM;CACZ,OAAO,IAAI,SAAS,aAAa,OAAO,IAAI,YAAY;AAC1D;AAEA,SAAS,aAAa,QAAqB,SAAmC;CAC5E,MAAM,SAAsB,CAAC;CAE7B,KAAK,MAAM,SAAS,cAAc;EAChC,MAAM,WAAW,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,GAAI,QAAQ,UAAU,CAAC,CAAE;EACrE,IAAI,SAAS,SAAS,GACpB,OAAO,SAAS;CAEpB;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"config.js","names":["fs","path","os"],"sources":["../../src/hooks/config.ts"],"sourcesContent":["/**\n * Hook configuration loading from filesystem.\n * Loads from global (~/.mastracode/hooks.json) and project (.mastracode/hooks.json).\n * Global hooks run first, project hooks append.\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nimport type { HooksConfig, HookDefinition, HookEventName } from './types.js';\n\nexport const VALID_EVENTS: HookEventName[] = [\n 'PreToolUse',\n 'PostToolUse',\n 'Stop',\n 'UserPromptSubmit',\n 'SessionStart',\n 'SessionEnd',\n 'Notification',\n 'AgentStart',\n 'AgentEnd',\n 'PermissionRequest',\n 'PermissionResult',\n 'Interrupt',\n 'SubagentStart',\n 'SubagentEnd',\n];\n\nexport function loadHooksConfig(projectDir: string, configDirName = DEFAULT_CONFIG_DIR, homeDir?: string): HooksConfig {\n const globalPath = getGlobalHooksPath(configDirName, homeDir);\n const projectPath = getProjectHooksPath(projectDir, configDirName);\n\n const globalConfig = loadSingleConfig(globalPath);\n // A session started in the home directory resolves both paths to the same\n // file; loading it twice would register (and run) every hook twice.\n const projectConfig = isSameFile(globalPath, projectPath) ? {} : loadSingleConfig(projectPath);\n\n return mergeConfigs(globalConfig, projectConfig);\n}\n\nfunction isSameFile(a: string, b: string): boolean {\n try {\n return fs.realpathSync(a) === fs.realpathSync(b);\n } catch {\n return path.resolve(a) === path.resolve(b);\n }\n}\n\nexport function getProjectHooksPath(projectDir: string, configDirName = DEFAULT_CONFIG_DIR): string {\n return path.join(projectDir, configDirName, 'hooks.json');\n}\n\nexport function getGlobalHooksPath(configDirName = DEFAULT_CONFIG_DIR, homeDir = os.homedir()): string {\n return path.join(homeDir, configDirName, 'hooks.json');\n}\n\nfunction loadSingleConfig(filePath: string): HooksConfig {\n try {\n if (!fs.existsSync(filePath)) return {};\n const raw = fs.readFileSync(filePath, 'utf-8');\n return validateConfig(JSON.parse(raw));\n } catch {\n return {};\n }\n}\n\nfunction validateConfig(raw: unknown): HooksConfig {\n if (!raw || typeof raw !== 'object') return {};\n\n const config: HooksConfig = {};\n const obj = raw as Record<string, unknown>;\n\n for (const event of VALID_EVENTS) {\n if (Array.isArray(obj[event])) {\n const hooks = (obj[event] as unknown[]).filter(isValidHook);\n if (hooks.length > 0) {\n config[event] = hooks;\n }\n }\n }\n\n return config;\n}\n\nfunction isValidHook(raw: unknown): raw is HookDefinition {\n if (!raw || typeof raw !== 'object') return false;\n const obj = raw as Record<string, unknown>;\n return obj.type === 'command' && typeof obj.command === 'string';\n}\n\nfunction mergeConfigs(global: HooksConfig, project: HooksConfig): HooksConfig {\n const merged: HooksConfig = {};\n\n for (const event of VALID_EVENTS) {\n const combined = [...(global[event] ?? []), ...(project[event] ?? [])];\n if (combined.length > 0) {\n merged[event] = combined;\n }\n }\n\n return merged;\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAa,eAAgC;CAC3C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,gBAAgB,YAAoB,gBAAgB,oBAAoB,SAA+B;CACrH,MAAM,aAAa,mBAAmB,eAAe,OAAO;CAC5D,MAAM,cAAc,oBAAoB,YAAY,aAAa;CAOjE,OAAO,aALc,iBAAiB,UAKP,GAFT,WAAW,YAAY,WAAW,IAAI,CAAC,IAAI,iBAAiB,WAAW,CAE9C;AACjD;AAEA,SAAS,WAAW,GAAW,GAAoB;CACjD,IAAI;EACF,OAAOA,KAAG,aAAa,CAAC,MAAMA,KAAG,aAAa,CAAC;CACjD,QAAQ;EACN,OAAOC,OAAK,QAAQ,CAAC,MAAMA,OAAK,QAAQ,CAAC;CAC3C;AACF;AAEA,SAAgB,oBAAoB,YAAoB,gBAAgB,oBAA4B;CAClG,OAAOA,OAAK,KAAK,YAAY,eAAe,YAAY;AAC1D;AAEA,SAAgB,mBAAmB,gBAAgB,oBAAoB,UAAUC,KAAG,QAAQ,GAAW;CACrG,OAAOD,OAAK,KAAK,SAAS,eAAe,YAAY;AACvD;AAEA,SAAS,iBAAiB,UAA+B;CACvD,IAAI;EACF,IAAI,CAACD,KAAG,WAAW,QAAQ,GAAG,OAAO,CAAC;EACtC,MAAM,MAAMA,KAAG,aAAa,UAAU,OAAO;EAC7C,OAAO,eAAe,KAAK,MAAM,GAAG,CAAC;CACvC,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,SAAS,eAAe,KAA2B;CACjD,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO,CAAC;CAE7C,MAAM,SAAsB,CAAC;CAC7B,MAAM,MAAM;CAEZ,KAAK,MAAM,SAAS,cAClB,IAAI,MAAM,QAAQ,IAAI,MAAM,GAAG;EAC7B,MAAM,QAAS,IAAI,MAAM,CAAe,OAAO,WAAW;EAC1D,IAAI,MAAM,SAAS,GACjB,OAAO,SAAS;CAEpB;CAGF,OAAO;AACT;AAEA,SAAS,YAAY,KAAqC;CACxD,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO;CAC5C,MAAM,MAAM;CACZ,OAAO,IAAI,SAAS,aAAa,OAAO,IAAI,YAAY;AAC1D;AAEA,SAAS,aAAa,QAAqB,SAAmC;CAC5E,MAAM,SAAsB,CAAC;CAE7B,KAAK,MAAM,SAAS,cAAc;EAChC,MAAM,WAAW,CAAC,GAAI,OAAO,UAAU,CAAC,GAAI,GAAI,QAAQ,UAAU,CAAC,CAAE;EACrE,IAAI,SAAS,SAAS,GACpB,OAAO,SAAS;CAEpB;CAEA,OAAO;AACT"}
@@ -0,0 +1,19 @@
1
+ export declare const listAvailableClassifiersTool: import("@mastra/core/tools").Tool<Record<string, never>, {
2
+ classifiers: {
3
+ id: string;
4
+ outputPaths: {
5
+ answers: string;
6
+ usage: string;
7
+ };
8
+ questions?: {
9
+ id: string;
10
+ type: "boolean" | "score" | "choice";
11
+ answerPath: string;
12
+ routingPath: string;
13
+ instructions?: any;
14
+ choices?: string[] | undefined;
15
+ criteria?: any;
16
+ }[] | undefined;
17
+ }[];
18
+ }, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "list-available-classifiers", unknown>;
19
+ //# sourceMappingURL=list-available-classifiers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-available-classifiers.d.ts","sourceRoot":"","sources":["../../../src/tools/workflows/list-available-classifiers.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;yIAiDvC,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { createTool } from "@mastra/core/tools";
2
+ import { z } from "zod";
3
+ //#region src/tools/workflows/list-available-classifiers.ts
4
+ function describeQuestions(questions) {
5
+ if (!questions) return void 0;
6
+ return Object.entries(questions).map(([id, question]) => ({
7
+ id,
8
+ type: question.type,
9
+ instructions: question.instructions,
10
+ choices: question.type === "choice" ? Object.keys(question.criteria) : void 0,
11
+ criteria: question.criteria,
12
+ answerPath: `inputData.answers.${id}`,
13
+ routingPath: `inputData.answers.${id}.${question.type === "choice" ? "choice" : question.type === "score" ? "score" : "probability"}`
14
+ }));
15
+ }
16
+ const listAvailableClassifiersTool = createTool({
17
+ id: "list-available-classifiers",
18
+ description: "Returns configured classifiers registered on the Mastra instance. The ids returned here are the only valid values for `{ type: \"classifier\", classifierId }`. Each row includes question metadata and stable output paths for routing with conditional entries.",
19
+ inputSchema: z.object({}),
20
+ outputSchema: z.object({ classifiers: z.array(z.object({
21
+ id: z.string(),
22
+ questions: z.array(z.object({
23
+ id: z.string(),
24
+ type: z.enum([
25
+ "choice",
26
+ "score",
27
+ "boolean"
28
+ ]),
29
+ instructions: z.any().optional(),
30
+ choices: z.array(z.string()).optional(),
31
+ criteria: z.any().optional(),
32
+ answerPath: z.string(),
33
+ routingPath: z.string()
34
+ })).optional(),
35
+ outputPaths: z.object({
36
+ answers: z.string(),
37
+ usage: z.string()
38
+ })
39
+ })) }),
40
+ execute: async (_input, { mastra }) => {
41
+ if (!mastra) throw new Error("list-available-classifiers requires a Mastra context.");
42
+ const all = mastra.listClassifiers?.() ?? {};
43
+ return { classifiers: Object.entries(all).filter(([, classifier]) => classifier.questions !== void 0).map(([id, classifier]) => ({
44
+ id,
45
+ questions: describeQuestions(classifier.questions),
46
+ outputPaths: {
47
+ answers: "inputData.answers.<question>",
48
+ usage: "inputData.usage"
49
+ }
50
+ })) };
51
+ }
52
+ });
53
+ //#endregion
54
+ export { listAvailableClassifiersTool };
55
+
56
+ //# sourceMappingURL=list-available-classifiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-available-classifiers.js","names":[],"sources":["../../../src/tools/workflows/list-available-classifiers.ts"],"sourcesContent":["/**\n * Sub-agent tool: list classifiers the workflow-builder can reference in\n * classifier entries of a Dynamic Workflow graph. Read-only.\n */\nimport type { ClassifierQuestions } from '@mastra/core/classifier';\nimport { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nfunction describeQuestions(questions: ClassifierQuestions | undefined) {\n if (!questions) return undefined;\n\n return Object.entries(questions).map(([id, question]) => ({\n id,\n type: question.type,\n instructions: question.instructions,\n choices: question.type === 'choice' ? Object.keys(question.criteria) : undefined,\n criteria: question.criteria,\n answerPath: `inputData.answers.${id}`,\n routingPath: `inputData.answers.${id}.${\n question.type === 'choice' ? 'choice' : question.type === 'score' ? 'score' : 'probability'\n }`,\n }));\n}\n\nexport const listAvailableClassifiersTool = createTool({\n id: 'list-available-classifiers',\n description:\n 'Returns configured classifiers registered on the Mastra instance. The ids returned here are the only valid values for `{ type: \"classifier\", classifierId }`. Each row includes question metadata and stable output paths for routing with conditional entries.',\n inputSchema: z.object({}),\n outputSchema: z.object({\n classifiers: z.array(\n z.object({\n id: z.string(),\n questions: z\n .array(\n z.object({\n id: z.string(),\n type: z.enum(['choice', 'score', 'boolean']),\n instructions: z.any().optional(),\n choices: z.array(z.string()).optional(),\n criteria: z.any().optional(),\n answerPath: z.string(),\n routingPath: z.string(),\n }),\n )\n .optional(),\n outputPaths: z.object({\n answers: z.string(),\n usage: z.string(),\n }),\n }),\n ),\n }),\n execute: async (_input, { mastra }) => {\n if (!mastra) throw new Error('list-available-classifiers requires a Mastra context.');\n const all =\n (\n mastra as { listClassifiers?: () => Record<string, { questions?: ClassifierQuestions }> | undefined }\n ).listClassifiers?.() ?? {};\n\n return {\n classifiers: Object.entries(all)\n .filter(([, classifier]) => classifier.questions !== undefined)\n .map(([id, classifier]) => ({\n id,\n questions: describeQuestions(classifier.questions),\n outputPaths: {\n answers: 'inputData.answers.<question>',\n usage: 'inputData.usage',\n },\n })),\n };\n },\n});\n"],"mappings":";;;AAQA,SAAS,kBAAkB,WAA4C;CACrE,IAAI,CAAC,WAAW,OAAO,KAAA;CAEvB,OAAO,OAAO,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,eAAe;EACxD;EACA,MAAM,SAAS;EACf,cAAc,SAAS;EACvB,SAAS,SAAS,SAAS,WAAW,OAAO,KAAK,SAAS,QAAQ,IAAI,KAAA;EACvE,UAAU,SAAS;EACnB,YAAY,qBAAqB;EACjC,aAAa,qBAAqB,GAAG,GACnC,SAAS,SAAS,WAAW,WAAW,SAAS,SAAS,UAAU,UAAU;CAElF,EAAE;AACJ;AAEA,MAAa,+BAA+B,WAAW;CACrD,IAAI;CACJ,aACE;CACF,aAAa,EAAE,OAAO,CAAC,CAAC;CACxB,cAAc,EAAE,OAAO,EACrB,aAAa,EAAE,MACb,EAAE,OAAO;EACP,IAAI,EAAE,OAAO;EACb,WAAW,EACR,MACC,EAAE,OAAO;GACP,IAAI,EAAE,OAAO;GACb,MAAM,EAAE,KAAK;IAAC;IAAU;IAAS;GAAS,CAAC;GAC3C,cAAc,EAAE,IAAI,CAAC,CAAC,SAAS;GAC/B,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS;GACtC,UAAU,EAAE,IAAI,CAAC,CAAC,SAAS;GAC3B,YAAY,EAAE,OAAO;GACrB,aAAa,EAAE,OAAO;EACxB,CAAC,CACH,CAAC,CACA,SAAS;EACZ,aAAa,EAAE,OAAO;GACpB,SAAS,EAAE,OAAO;GAClB,OAAO,EAAE,OAAO;EAClB,CAAC;CACH,CAAC,CACH,EACF,CAAC;CACD,SAAS,OAAO,QAAQ,EAAE,aAAa;EACrC,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,uDAAuD;EACpF,MAAM,MAEF,OACA,kBAAkB,KAAK,CAAC;EAE5B,OAAO,EACL,aAAa,OAAO,QAAQ,GAAG,CAAC,CAC7B,QAAQ,GAAG,gBAAgB,WAAW,cAAc,KAAA,CAAS,CAAC,CAC9D,KAAK,CAAC,IAAI,iBAAiB;GAC1B;GACA,WAAW,kBAAkB,WAAW,SAAS;GACjD,aAAa;IACX,SAAS;IACT,OAAO;GACT;EACF,EAAE,EACN;CACF;AACF,CAAC"}
@@ -16,7 +16,7 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
16
16
  outputSchema: z.ZodOptional<z.ZodUnknown>;
17
17
  options: z.ZodOptional<z.ZodObject<{
18
18
  retries: z.ZodOptional<z.ZodNumber>;
19
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
19
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
20
20
  }, z.core.$strip>>;
21
21
  }, z.core.$strict>, z.ZodObject<{
22
22
  type: z.ZodLiteral<"tool">;
@@ -25,11 +25,22 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
25
25
  description: z.ZodOptional<z.ZodString>;
26
26
  options: z.ZodOptional<z.ZodObject<{
27
27
  retries: z.ZodOptional<z.ZodNumber>;
28
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
28
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
29
29
  }, z.core.$strip>>;
30
30
  }, z.core.$strict>, z.ZodObject<{
31
+ type: z.ZodLiteral<"classifier">;
32
+ id: z.ZodString;
33
+ classifierId: z.ZodString;
31
34
  description: z.ZodOptional<z.ZodString>;
32
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
35
+ options: z.ZodOptional<z.ZodObject<{
36
+ maxRetries: z.ZodOptional<z.ZodNumber>;
37
+ providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
38
+ retries: z.ZodOptional<z.ZodNumber>;
39
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
40
+ }, z.core.$strip>>;
41
+ }, z.core.$strict>, z.ZodObject<{
42
+ description: z.ZodOptional<z.ZodString>;
43
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
33
44
  type: z.ZodLiteral<"mapping">;
34
45
  id: z.ZodString;
35
46
  mapConfig: z.ZodString;
@@ -40,11 +51,11 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
40
51
  description: z.ZodOptional<z.ZodString>;
41
52
  options: z.ZodOptional<z.ZodObject<{
42
53
  retries: z.ZodOptional<z.ZodNumber>;
43
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
54
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
44
55
  }, z.core.$strip>>;
45
56
  }, z.core.$strict>, z.ZodObject<{
46
57
  description: z.ZodOptional<z.ZodString>;
47
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
58
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
48
59
  id: z.ZodOptional<z.ZodString>;
49
60
  type: z.ZodLiteral<"parallel">;
50
61
  steps: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
@@ -55,7 +66,7 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
55
66
  outputSchema: z.ZodOptional<z.ZodUnknown>;
56
67
  options: z.ZodOptional<z.ZodObject<{
57
68
  retries: z.ZodOptional<z.ZodNumber>;
58
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
69
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
59
70
  }, z.core.$strip>>;
60
71
  }, z.core.$strict>, z.ZodObject<{
61
72
  type: z.ZodLiteral<"tool">;
@@ -64,7 +75,18 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
64
75
  description: z.ZodOptional<z.ZodString>;
65
76
  options: z.ZodOptional<z.ZodObject<{
66
77
  retries: z.ZodOptional<z.ZodNumber>;
67
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
78
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
79
+ }, z.core.$strip>>;
80
+ }, z.core.$strict>, z.ZodObject<{
81
+ type: z.ZodLiteral<"classifier">;
82
+ id: z.ZodString;
83
+ classifierId: z.ZodString;
84
+ description: z.ZodOptional<z.ZodString>;
85
+ options: z.ZodOptional<z.ZodObject<{
86
+ maxRetries: z.ZodOptional<z.ZodNumber>;
87
+ providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
88
+ retries: z.ZodOptional<z.ZodNumber>;
89
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
68
90
  }, z.core.$strip>>;
69
91
  }, z.core.$strict>, z.ZodObject<{
70
92
  type: z.ZodLiteral<"workflow">;
@@ -73,12 +95,12 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
73
95
  description: z.ZodOptional<z.ZodString>;
74
96
  options: z.ZodOptional<z.ZodObject<{
75
97
  retries: z.ZodOptional<z.ZodNumber>;
76
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
98
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
77
99
  }, z.core.$strip>>;
78
100
  }, z.core.$strict>]>>;
79
101
  }, z.core.$strict>, z.ZodObject<{
80
102
  description: z.ZodOptional<z.ZodString>;
81
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
103
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
82
104
  id: z.ZodOptional<z.ZodString>;
83
105
  type: z.ZodLiteral<"foreach">;
84
106
  step: z.ZodUnion<readonly [z.ZodObject<{
@@ -89,7 +111,7 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
89
111
  outputSchema: z.ZodOptional<z.ZodUnknown>;
90
112
  options: z.ZodOptional<z.ZodObject<{
91
113
  retries: z.ZodOptional<z.ZodNumber>;
92
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
114
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
93
115
  }, z.core.$strip>>;
94
116
  }, z.core.$strict>, z.ZodObject<{
95
117
  type: z.ZodLiteral<"tool">;
@@ -98,7 +120,18 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
98
120
  description: z.ZodOptional<z.ZodString>;
99
121
  options: z.ZodOptional<z.ZodObject<{
100
122
  retries: z.ZodOptional<z.ZodNumber>;
101
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
123
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
124
+ }, z.core.$strip>>;
125
+ }, z.core.$strict>, z.ZodObject<{
126
+ type: z.ZodLiteral<"classifier">;
127
+ id: z.ZodString;
128
+ classifierId: z.ZodString;
129
+ description: z.ZodOptional<z.ZodString>;
130
+ options: z.ZodOptional<z.ZodObject<{
131
+ maxRetries: z.ZodOptional<z.ZodNumber>;
132
+ providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
133
+ retries: z.ZodOptional<z.ZodNumber>;
134
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
102
135
  }, z.core.$strip>>;
103
136
  }, z.core.$strict>, z.ZodObject<{
104
137
  type: z.ZodLiteral<"workflow">;
@@ -107,7 +140,7 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
107
140
  description: z.ZodOptional<z.ZodString>;
108
141
  options: z.ZodOptional<z.ZodObject<{
109
142
  retries: z.ZodOptional<z.ZodNumber>;
110
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
143
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
111
144
  }, z.core.$strip>>;
112
145
  }, z.core.$strict>]>;
113
146
  opts: z.ZodOptional<z.ZodObject<{
@@ -115,19 +148,19 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
115
148
  }, z.core.$strip>>;
116
149
  }, z.core.$strict>, z.ZodObject<{
117
150
  description: z.ZodOptional<z.ZodString>;
118
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
151
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
119
152
  type: z.ZodLiteral<"sleep">;
120
153
  id: z.ZodString;
121
154
  duration: z.ZodNumber;
122
155
  }, z.core.$strict>, z.ZodObject<{
123
156
  description: z.ZodOptional<z.ZodString>;
124
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
157
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
125
158
  type: z.ZodLiteral<"sleepUntil">;
126
159
  id: z.ZodString;
127
160
  date: z.ZodString;
128
161
  }, z.core.$strict>, z.ZodObject<{
129
162
  description: z.ZodOptional<z.ZodString>;
130
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
163
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
131
164
  id: z.ZodOptional<z.ZodString>;
132
165
  type: z.ZodLiteral<"conditional">;
133
166
  steps: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
@@ -138,7 +171,7 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
138
171
  outputSchema: z.ZodOptional<z.ZodUnknown>;
139
172
  options: z.ZodOptional<z.ZodObject<{
140
173
  retries: z.ZodOptional<z.ZodNumber>;
141
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
174
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
142
175
  }, z.core.$strip>>;
143
176
  }, z.core.$strict>, z.ZodObject<{
144
177
  type: z.ZodLiteral<"tool">;
@@ -147,7 +180,18 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
147
180
  description: z.ZodOptional<z.ZodString>;
148
181
  options: z.ZodOptional<z.ZodObject<{
149
182
  retries: z.ZodOptional<z.ZodNumber>;
150
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
183
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
184
+ }, z.core.$strip>>;
185
+ }, z.core.$strict>, z.ZodObject<{
186
+ type: z.ZodLiteral<"classifier">;
187
+ id: z.ZodString;
188
+ classifierId: z.ZodString;
189
+ description: z.ZodOptional<z.ZodString>;
190
+ options: z.ZodOptional<z.ZodObject<{
191
+ maxRetries: z.ZodOptional<z.ZodNumber>;
192
+ providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
193
+ retries: z.ZodOptional<z.ZodNumber>;
194
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
151
195
  }, z.core.$strip>>;
152
196
  }, z.core.$strict>, z.ZodObject<{
153
197
  type: z.ZodLiteral<"workflow">;
@@ -156,13 +200,13 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
156
200
  description: z.ZodOptional<z.ZodString>;
157
201
  options: z.ZodOptional<z.ZodObject<{
158
202
  retries: z.ZodOptional<z.ZodNumber>;
159
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
203
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
160
204
  }, z.core.$strip>>;
161
205
  }, z.core.$strict>]>>;
162
206
  predicates: z.ZodArray<z.ZodType<import("@mastra/core/predicate").Predicate, unknown, z.core.$ZodTypeInternals<import("@mastra/core/predicate").Predicate, unknown>>>;
163
207
  }, z.core.$strict>, z.ZodObject<{
164
208
  description: z.ZodOptional<z.ZodString>;
165
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
209
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
166
210
  id: z.ZodOptional<z.ZodString>;
167
211
  type: z.ZodLiteral<"loop">;
168
212
  step: z.ZodUnion<readonly [z.ZodObject<{
@@ -173,7 +217,7 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
173
217
  outputSchema: z.ZodOptional<z.ZodUnknown>;
174
218
  options: z.ZodOptional<z.ZodObject<{
175
219
  retries: z.ZodOptional<z.ZodNumber>;
176
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
220
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
177
221
  }, z.core.$strip>>;
178
222
  }, z.core.$strict>, z.ZodObject<{
179
223
  type: z.ZodLiteral<"tool">;
@@ -182,7 +226,18 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
182
226
  description: z.ZodOptional<z.ZodString>;
183
227
  options: z.ZodOptional<z.ZodObject<{
184
228
  retries: z.ZodOptional<z.ZodNumber>;
185
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
229
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
230
+ }, z.core.$strip>>;
231
+ }, z.core.$strict>, z.ZodObject<{
232
+ type: z.ZodLiteral<"classifier">;
233
+ id: z.ZodString;
234
+ classifierId: z.ZodString;
235
+ description: z.ZodOptional<z.ZodString>;
236
+ options: z.ZodOptional<z.ZodObject<{
237
+ maxRetries: z.ZodOptional<z.ZodNumber>;
238
+ providerOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
239
+ retries: z.ZodOptional<z.ZodNumber>;
240
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
186
241
  }, z.core.$strip>>;
187
242
  }, z.core.$strict>, z.ZodObject<{
188
243
  type: z.ZodLiteral<"workflow">;
@@ -191,7 +246,7 @@ export declare const workflowDefinitionInputSchema: z.ZodPreprocess<z.ZodObject<
191
246
  description: z.ZodOptional<z.ZodString>;
192
247
  options: z.ZodOptional<z.ZodObject<{
193
248
  retries: z.ZodOptional<z.ZodNumber>;
194
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
249
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
195
250
  }, z.core.$strip>>;
196
251
  }, z.core.$strict>]>;
197
252
  loopType: z.ZodEnum<{
@@ -625,6 +680,17 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
625
680
  retries?: number | undefined;
626
681
  metadata?: Record<string, unknown> | undefined;
627
682
  } | undefined;
683
+ } | {
684
+ type: "classifier";
685
+ id: string;
686
+ classifierId: string;
687
+ description?: string | undefined;
688
+ options?: {
689
+ maxRetries?: number | undefined;
690
+ providerOptions?: Record<string, unknown> | undefined;
691
+ retries?: number | undefined;
692
+ metadata?: Record<string, unknown> | undefined;
693
+ } | undefined;
628
694
  } | {
629
695
  type: "mapping";
630
696
  id: string;
@@ -661,6 +727,17 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
661
727
  retries?: number | undefined;
662
728
  metadata?: Record<string, unknown> | undefined;
663
729
  } | undefined;
730
+ } | {
731
+ type: "classifier";
732
+ id: string;
733
+ classifierId: string;
734
+ description?: string | undefined;
735
+ options?: {
736
+ maxRetries?: number | undefined;
737
+ providerOptions?: Record<string, unknown> | undefined;
738
+ retries?: number | undefined;
739
+ metadata?: Record<string, unknown> | undefined;
740
+ } | undefined;
664
741
  } | {
665
742
  type: "workflow";
666
743
  id: string;
@@ -695,6 +772,17 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
695
772
  retries?: number | undefined;
696
773
  metadata?: Record<string, unknown> | undefined;
697
774
  } | undefined;
775
+ } | {
776
+ type: "classifier";
777
+ id: string;
778
+ classifierId: string;
779
+ description?: string | undefined;
780
+ options?: {
781
+ maxRetries?: number | undefined;
782
+ providerOptions?: Record<string, unknown> | undefined;
783
+ retries?: number | undefined;
784
+ metadata?: Record<string, unknown> | undefined;
785
+ } | undefined;
698
786
  } | {
699
787
  type: "workflow";
700
788
  id: string;
@@ -744,6 +832,17 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
744
832
  retries?: number | undefined;
745
833
  metadata?: Record<string, unknown> | undefined;
746
834
  } | undefined;
835
+ } | {
836
+ type: "classifier";
837
+ id: string;
838
+ classifierId: string;
839
+ description?: string | undefined;
840
+ options?: {
841
+ maxRetries?: number | undefined;
842
+ providerOptions?: Record<string, unknown> | undefined;
843
+ retries?: number | undefined;
844
+ metadata?: Record<string, unknown> | undefined;
845
+ } | undefined;
747
846
  } | {
748
847
  type: "workflow";
749
848
  id: string;
@@ -779,6 +878,17 @@ export declare const saveWorkflowTool: import("@mastra/core/tools").Tool<{
779
878
  retries?: number | undefined;
780
879
  metadata?: Record<string, unknown> | undefined;
781
880
  } | undefined;
881
+ } | {
882
+ type: "classifier";
883
+ id: string;
884
+ classifierId: string;
885
+ description?: string | undefined;
886
+ options?: {
887
+ maxRetries?: number | undefined;
888
+ providerOptions?: Record<string, unknown> | undefined;
889
+ retries?: number | undefined;
890
+ metadata?: Record<string, unknown> | undefined;
891
+ } | undefined;
782
892
  } | {
783
893
  type: "workflow";
784
894
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"save-workflow.d.ts","sourceRoot":"","sources":["../../../src/tools/workflows/save-workflow.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,2CAA2C,IAAI,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE3H,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAGzC,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4HAsB3B,CAAC"}
1
+ {"version":3,"file":"save-workflow.d.ts","sourceRoot":"","sources":["../../../src/tools/workflows/save-workflow.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,2CAA2C,IAAI,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE3H,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAGzC,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4HAsB3B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export declare const WORKFLOW_AUTHORING_TOOL_IDS: {
2
2
  readonly listAgents: "list-available-agents";
3
+ readonly listClassifiers: "list-available-classifiers";
3
4
  readonly listTools: "list-available-tools";
4
5
  readonly listWorkflows: "list-available-workflows";
5
6
  readonly saveWorkflow: "save-workflow";
@@ -11,5 +12,5 @@ export declare const WORKFLOW_MANAGEMENT_TOOL_IDS: {
11
12
  readonly runWorkflow: "run-workflow";
12
13
  readonly deleteWorkflow: "delete-workflow";
13
14
  };
14
- export declare const WORKFLOW_BUILDER_NOISE_TOOL_IDS: readonly ("create-workflow" | "delete-workflow" | "get-workflow" | "list-workflows" | "run-workflow" | "list-available-agents" | "list-available-tools" | "list-available-workflows" | "save-workflow")[];
15
+ export declare const WORKFLOW_BUILDER_NOISE_TOOL_IDS: readonly ("create-workflow" | "delete-workflow" | "get-workflow" | "list-workflows" | "run-workflow" | "list-available-agents" | "list-available-classifiers" | "list-available-tools" | "list-available-workflows" | "save-workflow")[];
15
16
  //# sourceMappingURL=tool-ids.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-ids.d.ts","sourceRoot":"","sources":["../../../src/tools/workflows/tool-ids.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B;;;;;CAK9B,CAAC;AAEX,eAAO,MAAM,4BAA4B;;;;;;CAM/B,CAAC;AAEX,eAAO,MAAM,+BAA+B,2MAGlC,CAAC"}
1
+ {"version":3,"file":"tool-ids.d.ts","sourceRoot":"","sources":["../../../src/tools/workflows/tool-ids.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B;;;;;;CAM9B,CAAC;AAEX,eAAO,MAAM,4BAA4B;;;;;;CAM/B,CAAC;AAEX,eAAO,MAAM,+BAA+B,0OAGlC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  //#region src/tools/workflows/tool-ids.ts
2
2
  const WORKFLOW_AUTHORING_TOOL_IDS = {
3
3
  listAgents: "list-available-agents",
4
+ listClassifiers: "list-available-classifiers",
4
5
  listTools: "list-available-tools",
5
6
  listWorkflows: "list-available-workflows",
6
7
  saveWorkflow: "save-workflow"
@@ -1 +1 @@
1
- {"version":3,"file":"tool-ids.js","names":[],"sources":["../../../src/tools/workflows/tool-ids.ts"],"sourcesContent":["export const WORKFLOW_AUTHORING_TOOL_IDS = {\n listAgents: 'list-available-agents',\n listTools: 'list-available-tools',\n listWorkflows: 'list-available-workflows',\n saveWorkflow: 'save-workflow',\n} as const;\n\nexport const WORKFLOW_MANAGEMENT_TOOL_IDS = {\n createWorkflow: 'create-workflow',\n listWorkflows: 'list-workflows',\n getWorkflow: 'get-workflow',\n runWorkflow: 'run-workflow',\n deleteWorkflow: 'delete-workflow',\n} as const;\n\nexport const WORKFLOW_BUILDER_NOISE_TOOL_IDS = [\n ...Object.values(WORKFLOW_AUTHORING_TOOL_IDS),\n ...Object.values(WORKFLOW_MANAGEMENT_TOOL_IDS),\n] as const;\n"],"mappings":";AAAA,MAAa,8BAA8B;CACzC,YAAY;CACZ,WAAW;CACX,eAAe;CACf,cAAc;AAChB;AAEA,MAAa,+BAA+B;CAC1C,gBAAgB;CAChB,eAAe;CACf,aAAa;CACb,aAAa;CACb,gBAAgB;AAClB;AAEA,MAAa,kCAAkC,CAC7C,GAAG,OAAO,OAAO,2BAA2B,GAC5C,GAAG,OAAO,OAAO,4BAA4B,CAC/C"}
1
+ {"version":3,"file":"tool-ids.js","names":[],"sources":["../../../src/tools/workflows/tool-ids.ts"],"sourcesContent":["export const WORKFLOW_AUTHORING_TOOL_IDS = {\n listAgents: 'list-available-agents',\n listClassifiers: 'list-available-classifiers',\n listTools: 'list-available-tools',\n listWorkflows: 'list-available-workflows',\n saveWorkflow: 'save-workflow',\n} as const;\n\nexport const WORKFLOW_MANAGEMENT_TOOL_IDS = {\n createWorkflow: 'create-workflow',\n listWorkflows: 'list-workflows',\n getWorkflow: 'get-workflow',\n runWorkflow: 'run-workflow',\n deleteWorkflow: 'delete-workflow',\n} as const;\n\nexport const WORKFLOW_BUILDER_NOISE_TOOL_IDS = [\n ...Object.values(WORKFLOW_AUTHORING_TOOL_IDS),\n ...Object.values(WORKFLOW_MANAGEMENT_TOOL_IDS),\n] as const;\n"],"mappings":";AAAA,MAAa,8BAA8B;CACzC,YAAY;CACZ,iBAAiB;CACjB,WAAW;CACX,eAAe;CACf,cAAc;AAChB;AAEA,MAAa,+BAA+B;CAC1C,gBAAgB;CAChB,eAAe;CACf,aAAa;CACb,aAAa;CACb,gBAAgB;AAClB;AAEA,MAAa,kCAAkC,CAC7C,GAAG,OAAO,OAAO,2BAA2B,GAC5C,GAAG,OAAO,OAAO,4BAA4B,CAC/C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/code-sdk",
3
- "version": "1.8.1-alpha.2",
3
+ "version": "1.8.1-alpha.4",
4
4
  "description": "Mastra Code SDK: the agent core behind Mastra Code (everything except the TUI) — build your own UIs and surfaces on top of it",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -56,15 +56,15 @@
56
56
  "vscode-languageserver-protocol": "^3.17.5",
57
57
  "yaml": "^2.7.1",
58
58
  "zod": "^4.6.4",
59
- "@mastra/agent-browser": "0.5.3",
60
- "@mastra/core": "1.69.0-alpha.2",
59
+ "@mastra/core": "1.69.0-alpha.4",
60
+ "@mastra/duckdb": "1.10.0",
61
61
  "@mastra/fastembed": "1.3.1",
62
62
  "@mastra/github-signals": "0.5.0",
63
- "@mastra/duckdb": "1.10.0",
64
- "@mastra/mcp": "2.0.0",
65
63
  "@mastra/libsql": "1.23.1",
66
- "@mastra/observability": "1.17.9",
67
64
  "@mastra/memory": "1.31.0",
65
+ "@mastra/agent-browser": "0.5.3",
66
+ "@mastra/mcp": "2.0.0",
67
+ "@mastra/observability": "1.18.0-alpha.0",
68
68
  "@mastra/parallel": "0.1.2",
69
69
  "@mastra/pg": "1.26.0",
70
70
  "@mastra/schema-compat": "1.3.11",