@salesforce/sfdx-agent-harness-mastra 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,15 +46,15 @@ Linux and macOS release the handle eagerly; the retry options are no-ops on thos
46
46
 
47
47
  ### Core
48
48
 
49
- | Export | Kind | Description |
50
- | ------------------------------------- | --------- | ------------------------------------------------------------------------------------------- |
51
- | `MastraHarnessFactory` | class | `HarnessFactory` that produces a Mastra-backed `AgentHarness` bound to a storage root. |
52
- | `MastraHarnessFactoryConfig` | interface | Configuration for `MastraHarnessFactory` (`modelConfigFactory?`, `toolApprovalTimeoutMs?`). |
53
- | `MastraModelConfigFactory` | interface | Strategy for creating model configurations; injected into `MastraHarnessFactory`. |
54
- | `ResolvedModelConfig` | type | Return type of `MastraModelConfigFactory.create()` — wraps a `MastraModelConfig`. |
55
- | `DefaultMastraModelConfigFactory` | class | Default factory using the Salesforce LLM Gateway (`SalesforceMastraModelGateway`). |
56
- | `LLMGExpressMastraModelConfigFactory` | class | Factory for LLM Gateway Express (API-key-authenticated, OpenAI-compatible endpoint). |
57
- | `LLMGExpressConfig` | type | Configuration for `LLMGExpressMastraModelConfigFactory` (`apiKey`, `baseUrl`, `modelId`). |
49
+ | Export | Kind | Description |
50
+ | ------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
51
+ | `MastraHarnessFactory` | class | `HarnessFactory` that produces a Mastra-backed `AgentHarness` bound to a storage root. |
52
+ | `MastraHarnessFactoryConfig` | interface | Configuration for `MastraHarnessFactory` (`modelConfigFactory?`, `toolApprovalTimeoutMs?`). |
53
+ | `MastraModelConfigFactory` | interface | Strategy for creating model configurations; injected into `MastraHarnessFactory`. |
54
+ | `ResolvedModelConfig` | type | Return type of `MastraModelConfigFactory.create()` — a `MastraModelConfig` plus a `validateFiles(files)` hook the harness calls for pre-flight multimodal (`image`/`file`) validation. |
55
+ | `DefaultMastraModelConfigFactory` | class | Default factory using the Salesforce LLM Gateway (`SalesforceMastraModelGateway`). |
56
+ | `LLMGExpressMastraModelConfigFactory` | class | Factory for LLM Gateway Express (API-key-authenticated, OpenAI-compatible endpoint). |
57
+ | `LLMGExpressConfig` | type | Configuration for `LLMGExpressMastraModelConfigFactory` (`apiKey`, `baseUrl`, `modelId`). |
58
58
 
59
59
  ### Extension surface
60
60
 
@@ -62,14 +62,16 @@ These types let consumers reach Mastra-specific features through the SDK's typed
62
62
  `MastraAgentHarness` from `MastraHarnessFactory.create()`, so consumers usually don't reference these types explicitly —
63
63
  they show up via inference at the call site.
64
64
 
65
- | Export | Kind | Description |
66
- | ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
67
- | `MastraAgentHarness` | type | Branded `AgentHarness` subtype; carries the Mastra-specific `extensions` namespace and the inferred config type. |
68
- | `MastraAgentConfig` | type | `AgentConfig` extended with Mastra-only fields (currently `toolSearch`). Inferred at `manager.createAgent` automatically — annotation rarely needed. |
69
- | `MastraToolSearchConfig` | type | Shape of `MastraAgentConfig.toolSearch` (`pool`, `alwaysActive`, `topK`, `ttl`). |
70
- | `formatMcpToolName` | function | `(serverName: string, toolName: string) => string` — builds the namespaced MCP tool name (`${serverName}_${toolName}`) used in `toolSearch.alwaysActive`. |
71
- | `ToolSearchHandle` | type | Stable interface for the tool-search runtime: `id`, `getStateStats`, `clearState`, `clearAllState`, `cleanupNow`. Wraps Mastra's internal processor. |
72
- | `SkillSearchHandle` | type | Stable interface for the skill-search runtime: `id` (Mastra's processor has no other public methods today; the harness owns lifecycle). |
65
+ | Export | Kind | Description |
66
+ | ------------------------ | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
67
+ | `MastraAgentHarness` | type | Branded `AgentHarness` subtype; carries the Mastra-specific `extensions` namespace and the inferred config type. |
68
+ | `MastraAgentConfig` | type | `AgentConfig` extended with Mastra-only fields (currently `toolSearch`). Inferred at `manager.createAgent` automatically — annotation rarely needed. |
69
+ | `MastraToolSearchConfig` | type | Shape of `MastraAgentConfig.toolSearch` (`pool`, `alwaysActive`, `topK`, `ttl`). |
70
+ | `ToolSearchHandle` | type | Stable interface for the tool-search runtime: `id`, `getStateStats`, `clearState`, `clearAllState`, `cleanupNow`. Wraps Mastra's internal processor. |
71
+ | `SkillSearchHandle` | type | Stable interface for the skill-search runtime: `id` (Mastra's processor has no other public methods today; the harness owns lifecycle). |
72
+
73
+ The Mastra-specific accessors live on `manager.extensions.mastra` (`getToolSearchProcessor(agentId)`,
74
+ `getSkillSearchProcessor(agentId)`, `formatMcpToolName(serverName, toolName)`) and require no separate import.
73
75
 
74
76
  #### Tool search
75
77
 
@@ -77,7 +79,7 @@ Hide a large tool catalog behind Mastra's `search_tools` / `load_tool` meta-tool
77
79
 
78
80
  ```ts
79
81
  import { createAgentManager } from '@salesforce/sfdx-agent-sdk';
80
- import { MastraHarnessFactory, formatMcpToolName } from '@salesforce/sfdx-agent-harness-mastra';
82
+ import { MastraHarnessFactory } from '@salesforce/sfdx-agent-harness-mastra';
81
83
 
82
84
  const manager = await createAgentManager(storageRoot, new MastraHarnessFactory());
83
85
 
@@ -87,7 +89,14 @@ const agent = await manager.createAgent(projectRoot, {
87
89
  mcpServers: { sfdx: { type: 'stdio', command: 'npx', args: ['@salesforce/mcp'] } },
88
90
  toolSearch: {
89
91
  pool: '*', // or an explicit name list
90
- alwaysActive: ['lookup_account', formatMcpToolName('sfdx', 'deploy_metadata')],
92
+ alwaysActive: [
93
+ 'lookup_account',
94
+ // Build the Mastra-specific namespaced name for an MCP tool that hasn't
95
+ // been discovered yet. The output format is harness-specific
96
+ // (Mastra: `${server}_${tool}`); for cross-harness tool identification
97
+ // anywhere else, prefer the `(serverName, toolName)` pair on `McpToolInfo`.
98
+ manager.extensions.mastra.formatMcpToolName('sfdx', 'deploy_metadata'),
99
+ ],
91
100
  topK: 5, // advisory; defaults to Mastra's 5
92
101
  ttl: 3_600_000, // ms; advisory; defaults to Mastra's 1h
93
102
  },
@@ -1,10 +1,11 @@
1
- import type { LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
1
+ import { type LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
2
2
  import type { MastraModelConfigFactory, ResolvedModelConfig } from './model-config-factory.js';
3
3
  /**
4
4
  * Default model configuration factory that uses the Salesforce LLM Gateway.
5
5
  *
6
6
  * Wraps the LLMGatewayClient in a SalesforceMastraModelGateway and calls
7
7
  * resolveLanguageModel() to produce the LanguageModelV2 that Mastra consumes.
8
+ * Captures the gateway model at creation time to provide multimodal validation.
8
9
  */
9
10
  export declare class DefaultMastraModelConfigFactory implements MastraModelConfigFactory {
10
11
  create(llmGatewayClient: LLMGatewayClient): ResolvedModelConfig;
@@ -2,17 +2,24 @@
2
2
  * Copyright 2026, Salesforce, Inc. All rights reserved.
3
3
  * See LICENSE.txt for license terms.
4
4
  */
5
+ import { validateMultimodalFiles } from '@salesforce/llm-gateway-sdk';
5
6
  import { SalesforceMastraModelGateway } from './salesforce-llm-gateway.js';
6
7
  /**
7
8
  * Default model configuration factory that uses the Salesforce LLM Gateway.
8
9
  *
9
10
  * Wraps the LLMGatewayClient in a SalesforceMastraModelGateway and calls
10
11
  * resolveLanguageModel() to produce the LanguageModelV2 that Mastra consumes.
12
+ * Captures the gateway model at creation time to provide multimodal validation.
11
13
  */
12
14
  export class DefaultMastraModelConfigFactory {
13
15
  create(llmGatewayClient) {
14
16
  const agentGateway = new SalesforceMastraModelGateway(llmGatewayClient);
15
- return { model: agentGateway.resolveLanguageModel() };
17
+ const model = agentGateway.resolveLanguageModel();
18
+ const gatewayModel = llmGatewayClient.getModel();
19
+ return {
20
+ model,
21
+ validateFiles: (files) => validateMultimodalFiles(files, gatewayModel),
22
+ };
16
23
  }
17
24
  }
18
25
  //# sourceMappingURL=default-model-config-factory.js.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Buffered async generator wrapper used by `MastraStreamBroker` to deliver
3
+ * `ChatEvent`s to a consumer's `ChatStreamResult.eventStream`.
4
+ *
5
+ * The buffer holds events pushed before the consumer starts iterating, so the
6
+ * broker can begin populating the sink eagerly without coordinating with the
7
+ * consumer's `for await` loop. Events pushed after iteration starts unblock
8
+ * the awaiting consumer via an internal Promise waiter.
9
+ *
10
+ * Internal to `@salesforce/sfdx-agent-harness-mastra`; not part of the public
11
+ * harness surface. Mirrors the same primitive in `@salesforce/sfdx-agent-harness-claude`
12
+ * to keep each harness's broker self-contained without forcing a shared
13
+ * cross-package surface.
14
+ */
15
+ export declare class GenSink<T> {
16
+ private readonly buffered;
17
+ private ended;
18
+ private waiter;
19
+ push(event: T): void;
20
+ end(): void;
21
+ generator(): AsyncGenerator<T, void>;
22
+ private wake;
23
+ }
@@ -0,0 +1,56 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc. All rights reserved.
3
+ * See LICENSE.txt for license terms.
4
+ */
5
+ /**
6
+ * Buffered async generator wrapper used by `MastraStreamBroker` to deliver
7
+ * `ChatEvent`s to a consumer's `ChatStreamResult.eventStream`.
8
+ *
9
+ * The buffer holds events pushed before the consumer starts iterating, so the
10
+ * broker can begin populating the sink eagerly without coordinating with the
11
+ * consumer's `for await` loop. Events pushed after iteration starts unblock
12
+ * the awaiting consumer via an internal Promise waiter.
13
+ *
14
+ * Internal to `@salesforce/sfdx-agent-harness-mastra`; not part of the public
15
+ * harness surface. Mirrors the same primitive in `@salesforce/sfdx-agent-harness-claude`
16
+ * to keep each harness's broker self-contained without forcing a shared
17
+ * cross-package surface.
18
+ */
19
+ export class GenSink {
20
+ buffered = [];
21
+ ended = false;
22
+ waiter = null;
23
+ push(event) {
24
+ if (this.ended)
25
+ return;
26
+ this.buffered.push(event);
27
+ this.wake();
28
+ }
29
+ end() {
30
+ if (this.ended)
31
+ return;
32
+ this.ended = true;
33
+ this.wake();
34
+ }
35
+ async *generator() {
36
+ while (true) {
37
+ if (this.buffered.length > 0) {
38
+ yield this.buffered.shift();
39
+ continue;
40
+ }
41
+ if (this.ended)
42
+ return;
43
+ await new Promise((resolve) => {
44
+ this.waiter = { resolve };
45
+ });
46
+ }
47
+ }
48
+ wake() {
49
+ const w = this.waiter;
50
+ if (w) {
51
+ this.waiter = null;
52
+ w.resolve();
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=gen-sink.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { MastraHarnessFactory, type MastraHarnessFactoryConfig } from './mastra-harness-factory.js';
2
2
  export type { MastraAgentHarness } from './mastra-harness.js';
3
- export { type MastraAgentConfig, type MastraToolSearchConfig, type SkillSearchHandle, type ToolSearchHandle, formatMcpToolName, } from './tool-search.js';
3
+ export { type MastraAgentConfig, type MastraToolSearchConfig, type SkillSearchHandle, type ToolSearchHandle, } from './tool-search.js';
4
4
  export type { MastraModelConfigFactory, ResolvedModelConfig } from './model-config-factory.js';
5
5
  export { DefaultMastraModelConfigFactory } from './default-model-config-factory.js';
6
6
  export { LLMGExpressMastraModelConfigFactory, type LLMGExpressConfig } from './llmg-express-model-config-factory.js';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * See LICENSE.txt for license terms.
4
4
  */
5
5
  export { MastraHarnessFactory } from './mastra-harness-factory.js';
6
- export { formatMcpToolName, } from './tool-search.js';
6
+ export {} from './tool-search.js';
7
7
  export { DefaultMastraModelConfigFactory } from './default-model-config-factory.js';
8
8
  export { LLMGExpressMastraModelConfigFactory } from './llmg-express-model-config-factory.js';
9
9
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import type { LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
1
+ import { type LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
2
2
  import type { MastraModelConfigFactory, ResolvedModelConfig } from './model-config-factory.js';
3
3
  export interface LLMGExpressConfig {
4
4
  /** API key for authenticating with LLM Gateway Express. */
@@ -12,12 +12,14 @@ export interface LLMGExpressConfig {
12
12
  * Model configuration factory for LLM Gateway Express (non-production,
13
13
  * API-key-authenticated, OpenAI-compatible endpoint).
14
14
  *
15
- * This factory ignores the LLMGatewayClient parameter entirely and produces
16
- * a Mastra OpenAICompatibleConfig that Mastra resolves internally using its
17
- * built-in OpenAI-compatible provider support.
15
+ * Routing is via a Mastra OpenAICompatibleConfig that Mastra resolves
16
+ * internally using its built-in OpenAI-compatible provider support.
17
+ * Multimodal validation uses the gateway client's model as a proxy for
18
+ * the express endpoint's capabilities (the express endpoint does not
19
+ * publish its own file-format caps).
18
20
  */
19
21
  export declare class LLMGExpressMastraModelConfigFactory implements MastraModelConfigFactory {
20
22
  private readonly config;
21
23
  constructor(config: LLMGExpressConfig);
22
- create(_llmGatewayClient: LLMGatewayClient): ResolvedModelConfig;
24
+ create(llmGatewayClient: LLMGatewayClient): ResolvedModelConfig;
23
25
  }
@@ -2,27 +2,34 @@
2
2
  * Copyright 2026, Salesforce, Inc. All rights reserved.
3
3
  * See LICENSE.txt for license terms.
4
4
  */
5
+ import { validateMultimodalFiles } from '@salesforce/llm-gateway-sdk';
5
6
  /**
6
7
  * Model configuration factory for LLM Gateway Express (non-production,
7
8
  * API-key-authenticated, OpenAI-compatible endpoint).
8
9
  *
9
- * This factory ignores the LLMGatewayClient parameter entirely and produces
10
- * a Mastra OpenAICompatibleConfig that Mastra resolves internally using its
11
- * built-in OpenAI-compatible provider support.
10
+ * Routing is via a Mastra OpenAICompatibleConfig that Mastra resolves
11
+ * internally using its built-in OpenAI-compatible provider support.
12
+ * Multimodal validation uses the gateway client's model as a proxy for
13
+ * the express endpoint's capabilities (the express endpoint does not
14
+ * publish its own file-format caps).
12
15
  */
13
16
  export class LLMGExpressMastraModelConfigFactory {
14
17
  config;
15
18
  constructor(config) {
16
19
  this.config = config;
17
20
  }
18
- create(_llmGatewayClient) {
21
+ create(llmGatewayClient) {
19
22
  const model = {
20
23
  providerId: 'llmg-express',
21
24
  modelId: this.config.modelId,
22
25
  url: this.config.baseUrl,
23
26
  apiKey: this.config.apiKey,
24
27
  };
25
- return { model };
28
+ const gatewayModel = llmGatewayClient.getModel();
29
+ return {
30
+ model,
31
+ validateFiles: (files) => validateMultimodalFiles(files, gatewayModel),
32
+ };
26
33
  }
27
34
  }
28
35
  //# sourceMappingURL=llmg-express-model-config-factory.js.map
@@ -1,5 +1,5 @@
1
1
  import type { ChunkType } from '@mastra/core/stream';
2
- import { type LogBus } from '@salesforce/agentic-common';
2
+ import type { LogBus } from '@salesforce/agentic-common';
3
3
  import type { ChatEvent } from '@salesforce/sfdx-agent-sdk';
4
4
  /**
5
5
  * Adapts Mastra `ChunkType` stream events to our {@link ChatEvent} discriminated union.
@@ -2,7 +2,6 @@
2
2
  * Copyright 2026, Salesforce, Inc. All rights reserved.
3
3
  * See LICENSE.txt for license terms.
4
4
  */
5
- import { getErrorMessage } from '@salesforce/agentic-common';
6
5
  /**
7
6
  * Adapts Mastra `ChunkType` stream events to our {@link ChatEvent} discriminated union.
8
7
  *
@@ -103,14 +102,17 @@ export class MastraEventAdapter {
103
102
  result: chunk.payload.result,
104
103
  isError: false,
105
104
  };
106
- case 'tool-error':
105
+ case 'tool-error': {
106
+ const error = chunk.payload.error instanceof Error ? chunk.payload.error : new Error(String(chunk.payload.error));
107
107
  return {
108
108
  type: 'tool-result',
109
109
  toolCallId: chunk.payload.toolCallId,
110
110
  toolName: chunk.payload.toolName,
111
- result: getErrorMessage(chunk.payload.error),
111
+ result: error.message,
112
112
  isError: true,
113
+ error,
113
114
  };
115
+ }
114
116
  case 'step-start':
115
117
  return { type: 'step-start', stepIndex: this.stepIndex++ };
116
118
  case 'step-finish':
@@ -199,6 +201,7 @@ function mapUsage(usage) {
199
201
  totalTokens: usage.totalTokens ?? undefined,
200
202
  reasoningTokens: usage.reasoningTokens,
201
203
  cachedInputTokens: usage.cachedInputTokens,
204
+ cacheWriteInputTokens: usage.cacheCreationInputTokens ? usage.cacheCreationInputTokens : undefined,
202
205
  };
203
206
  }
204
207
  //# sourceMappingURL=mastra-event-adapter.js.map
@@ -2,10 +2,11 @@ import { Agent } from '@mastra/core/agent';
2
2
  import { SkillSearchProcessor, ToolSearchProcessor } from '@mastra/core/processors';
3
3
  import type { ChunkType } from '@mastra/core/stream';
4
4
  import { MCPClient } from '@mastra/mcp';
5
- import { McpServerStatus, type AgentHarness, type WithAgentConfig, type ChatStreamResult, type HarnessAgentConfig, type MCPConfiguration, type McpServerErrorDetail, type McpServerInfo, type Message, type StreamOptions, type TelemetryEventCallback, type ToolResultInfo } from '@salesforce/sfdx-agent-sdk';
5
+ import { McpServerStatus, type AgentHarness, type WithAgentConfig, type ChatStreamResult, type HarnessAgentConfig, type MCPConfiguration, type McpServerErrorDetail, type McpServerInfo, type Message, type MessagePart, type StreamOptions, type TelemetryEventCallback, type ToolResultInfo } from '@salesforce/sfdx-agent-sdk';
6
+ import { MastraStreamBroker } from './mastra-stream-broker.js';
6
7
  import type { MastraModelConfigFactory } from './model-config-factory.js';
7
8
  import { type MastraAgentConfig, type SkillSearchHandle, type ToolSearchHandle } from './tool-search.js';
8
- import type { LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
9
+ import { type LLMGatewayClient, type MultimodalFile } from '@salesforce/llm-gateway-sdk';
9
10
  import { Clock, type LogRecord, type UniqueIDGenerator, type Unsubscribe } from '@salesforce/agentic-common';
10
11
  import { type ToolsInput } from './utils.js';
11
12
  import { Workspace } from '@mastra/core/workspace';
@@ -103,6 +104,21 @@ interface McpServerState {
103
104
  interface MastraAgentState {
104
105
  /** Mastra Agent instance. */
105
106
  agent: Agent;
107
+ /**
108
+ * The instructions string passed to the Mastra `Agent`'s constructor —
109
+ * `config.instructions` after rule bodies have been composed in (see
110
+ * `composeInstructionsWithRules`). Retained so `stream()` can surface
111
+ * it on the harness's debug log without re-deriving from the live
112
+ * Mastra `Agent`.
113
+ */
114
+ composedInstructions: string;
115
+ /**
116
+ * Pre-flight multimodal validation for this agent's model configuration.
117
+ * Captured from {@link ResolvedModelConfig.validateFiles} at `createAgent`
118
+ * time. Called by `toMastraStreamInput` before every stream that carries
119
+ * `image` or `file` parts. Throws `LLMGClientError` on violation.
120
+ */
121
+ validateFiles: (files: readonly MultimodalFile[]) => void;
106
122
  /** Per-server MCP state, keyed by server name. Empty map when no MCP servers are configured. */
107
123
  mcpServers: Map<string, McpServerState>;
108
124
  /** Original MCP configuration, retained so getMcpServerInfo can report disabled servers. */
@@ -111,6 +127,16 @@ interface MastraAgentState {
111
127
  mastraWorkspace?: Workspace;
112
128
  /** Tracks the active workflow run per thread for tool approval. */
113
129
  activeRuns: Map<string, ActiveRun>;
130
+ /**
131
+ * Per-thread MastraStreamBroker, allocated when a `stream()` call sets
132
+ * `requireToolApproval: true`. Owns the parallel-approval UX (#447):
133
+ * front-loaded `tool-approval-request` emission, decision buffering,
134
+ * Mastra suspend/resume coordination, per-tool sink routing, and the
135
+ * approval-timeout/abort lifecycle. When approval gating is off, the
136
+ * entry is absent and `stream()` falls through to `toChatStreamResult` /
137
+ * `createEventStream` (the pre-#447 path).
138
+ */
139
+ streamBrokers: Map<string, MastraStreamBroker>;
114
140
  /** Tool-search processor instance, when `toolSearch` is configured on the factory. */
115
141
  toolSearchProcessor?: ToolSearchProcessor;
116
142
  /** Skill-search processor instance, when both `skills` and `toolSearch` are configured. */
@@ -156,6 +182,25 @@ export type MastraAgentHarness = WithAgentConfig<AgentHarness & {
156
182
  * Mastra falls back to eager skill loading).
157
183
  */
158
184
  getSkillSearchProcessor(agentId: string): SkillSearchHandle | undefined;
185
+ /**
186
+ * Build the namespaced tool name Mastra registers for an
187
+ * MCP-discovered tool: `${serverName}_${toolName}`. Reach for
188
+ * this when constructing `MastraAgentConfig.toolSearch.alwaysActive`
189
+ * entries that reference MCP tools at agent-creation time, before
190
+ * MCP discovery has settled — without it you'd have to hard-code
191
+ * the namespaced string (brittle if the server name changes) or
192
+ * wait for discovery (which defeats the point of `alwaysActive`).
193
+ *
194
+ * Custom tools listed in `alwaysActive` should use their declared
195
+ * name directly; do NOT wrap them with this helper.
196
+ *
197
+ * The output format is **Mastra-specific** — Claude uses a
198
+ * different namespacing shape (`mcp__${server}__${tool}`). For
199
+ * cross-harness tool identification, use {@link McpToolInfo.serverName}
200
+ * + {@link McpToolInfo.toolName} (both populated identically by
201
+ * every harness) instead.
202
+ */
203
+ formatMcpToolName(serverName: string, toolName: string): string;
159
204
  };
160
205
  };
161
206
  }, MastraAgentConfig>;
@@ -332,7 +377,28 @@ export declare class MastraHarness implements MastraAgentHarness {
332
377
  * the thread's `ActiveRun` entry. See ARCHITECTURE.md → "Tool Approval Flow → Abort
333
378
  * during pending approval (#409)".
334
379
  */
335
- stream(agentId: string, threadId: string, message: string, options?: StreamOptions): Promise<ChatStreamResult>;
380
+ /**
381
+ * Maps an SDK `MessagePart[]` into the single AI SDK v5 user `ModelMessage` that
382
+ * `agent.stream()` accepts.
383
+ *
384
+ * `text` parts collapse into text content blocks; `image` / `file` parts become v5 `file`
385
+ * content blocks (`mediaType` + base64 `data` + optional `filename`) that Mastra forwards to the
386
+ * gateway bridge, which collects them into `ChatMessageIn.files[]`. Pre-stream validation and the
387
+ * input-part guard live in the SDK's {@link lowerStreamInput}, so file caps and the
388
+ * `MULTIMODAL_NOT_SUPPORTED` / `INVALID_MESSAGE_CONTENT` semantics are identical to the Claude
389
+ * harness; this method only supplies the Mastra-specific lowering of each part.
390
+ */
391
+ private toMastraStreamInput;
392
+ stream(agentId: string, threadId: string, message: string | MessagePart[], options?: StreamOptions): Promise<ChatStreamResult>;
393
+ /**
394
+ * Allocate a `MastraStreamBroker` for the (agentId, threadId) pair,
395
+ * dispose any prior broker on the same thread, hand the initial Mastra
396
+ * `output` to it, and wire the consumer's `abortSignal` (if any) to
397
+ * `broker.abort()`. The returned `ChatStreamResult.eventStream` reads
398
+ * from the broker's initial sink, where parallel
399
+ * `tool-approval-request` events surface for batch-style consumer UI.
400
+ */
401
+ private startBrokerStream;
336
402
  /**
337
403
  * @requirements
338
404
  * - MUST throw an error if the specified `agentId` is not found in `activeAgents`.