@salesforce/sfdx-agent-harness-mastra 0.11.0 → 0.12.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 +28 -19
- package/dist/default-model-config-factory.d.ts +2 -1
- package/dist/default-model-config-factory.js +8 -1
- package/dist/gen-sink.d.ts +23 -0
- package/dist/gen-sink.js +56 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/llmg-express-model-config-factory.d.ts +7 -5
- package/dist/llmg-express-model-config-factory.js +12 -5
- package/dist/mastra-event-adapter.d.ts +1 -1
- package/dist/mastra-event-adapter.js +6 -3
- package/dist/mastra-harness.d.ts +61 -3
- package/dist/mastra-harness.js +174 -9
- package/dist/mastra-message-mapper.js +63 -1
- package/dist/mastra-stream-broker.d.ts +210 -0
- package/dist/mastra-stream-broker.js +563 -0
- package/dist/model-config-factory.d.ts +13 -1
- package/dist/salesforce-llm-gateway.d.ts +20 -1
- package/dist/salesforce-llm-gateway.js +59 -10
- package/dist/tool-search.d.ts +0 -41
- package/dist/tool-search.js +0 -43
- package/package.json +4 -4
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()` —
|
|
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
|
|
66
|
-
| ------------------------ |
|
|
67
|
-
| `MastraAgentHarness` | type
|
|
68
|
-
| `MastraAgentConfig` | type
|
|
69
|
-
| `MastraToolSearchConfig` | type
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
|
|
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
|
|
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: [
|
|
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
|
|
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
|
-
|
|
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
|
+
}
|
package/dist/gen-sink.js
ADDED
|
@@ -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,
|
|
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 {
|
|
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
|
|
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
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
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(
|
|
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
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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(
|
|
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
|
-
|
|
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 {
|
|
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:
|
|
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
|
package/dist/mastra-harness.d.ts
CHANGED
|
@@ -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
|
|
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,13 @@ interface McpServerState {
|
|
|
103
104
|
interface MastraAgentState {
|
|
104
105
|
/** Mastra Agent instance. */
|
|
105
106
|
agent: Agent;
|
|
107
|
+
/**
|
|
108
|
+
* Pre-flight multimodal validation for this agent's model configuration.
|
|
109
|
+
* Captured from {@link ResolvedModelConfig.validateFiles} at `createAgent`
|
|
110
|
+
* time. Called by `toMastraStreamInput` before every stream that carries
|
|
111
|
+
* `image` or `file` parts. Throws `LLMGClientError` on violation.
|
|
112
|
+
*/
|
|
113
|
+
validateFiles: (files: readonly MultimodalFile[]) => void;
|
|
106
114
|
/** Per-server MCP state, keyed by server name. Empty map when no MCP servers are configured. */
|
|
107
115
|
mcpServers: Map<string, McpServerState>;
|
|
108
116
|
/** Original MCP configuration, retained so getMcpServerInfo can report disabled servers. */
|
|
@@ -111,6 +119,16 @@ interface MastraAgentState {
|
|
|
111
119
|
mastraWorkspace?: Workspace;
|
|
112
120
|
/** Tracks the active workflow run per thread for tool approval. */
|
|
113
121
|
activeRuns: Map<string, ActiveRun>;
|
|
122
|
+
/**
|
|
123
|
+
* Per-thread MastraStreamBroker, allocated when a `stream()` call sets
|
|
124
|
+
* `requireToolApproval: true`. Owns the parallel-approval UX (#447):
|
|
125
|
+
* front-loaded `tool-approval-request` emission, decision buffering,
|
|
126
|
+
* Mastra suspend/resume coordination, per-tool sink routing, and the
|
|
127
|
+
* approval-timeout/abort lifecycle. When approval gating is off, the
|
|
128
|
+
* entry is absent and `stream()` falls through to `toChatStreamResult` /
|
|
129
|
+
* `createEventStream` (the pre-#447 path).
|
|
130
|
+
*/
|
|
131
|
+
streamBrokers: Map<string, MastraStreamBroker>;
|
|
114
132
|
/** Tool-search processor instance, when `toolSearch` is configured on the factory. */
|
|
115
133
|
toolSearchProcessor?: ToolSearchProcessor;
|
|
116
134
|
/** Skill-search processor instance, when both `skills` and `toolSearch` are configured. */
|
|
@@ -156,6 +174,25 @@ export type MastraAgentHarness = WithAgentConfig<AgentHarness & {
|
|
|
156
174
|
* Mastra falls back to eager skill loading).
|
|
157
175
|
*/
|
|
158
176
|
getSkillSearchProcessor(agentId: string): SkillSearchHandle | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* Build the namespaced tool name Mastra registers for an
|
|
179
|
+
* MCP-discovered tool: `${serverName}_${toolName}`. Reach for
|
|
180
|
+
* this when constructing `MastraAgentConfig.toolSearch.alwaysActive`
|
|
181
|
+
* entries that reference MCP tools at agent-creation time, before
|
|
182
|
+
* MCP discovery has settled — without it you'd have to hard-code
|
|
183
|
+
* the namespaced string (brittle if the server name changes) or
|
|
184
|
+
* wait for discovery (which defeats the point of `alwaysActive`).
|
|
185
|
+
*
|
|
186
|
+
* Custom tools listed in `alwaysActive` should use their declared
|
|
187
|
+
* name directly; do NOT wrap them with this helper.
|
|
188
|
+
*
|
|
189
|
+
* The output format is **Mastra-specific** — Claude uses a
|
|
190
|
+
* different namespacing shape (`mcp__${server}__${tool}`). For
|
|
191
|
+
* cross-harness tool identification, use {@link McpToolInfo.serverName}
|
|
192
|
+
* + {@link McpToolInfo.toolName} (both populated identically by
|
|
193
|
+
* every harness) instead.
|
|
194
|
+
*/
|
|
195
|
+
formatMcpToolName(serverName: string, toolName: string): string;
|
|
159
196
|
};
|
|
160
197
|
};
|
|
161
198
|
}, MastraAgentConfig>;
|
|
@@ -332,7 +369,28 @@ export declare class MastraHarness implements MastraAgentHarness {
|
|
|
332
369
|
* the thread's `ActiveRun` entry. See ARCHITECTURE.md → "Tool Approval Flow → Abort
|
|
333
370
|
* during pending approval (#409)".
|
|
334
371
|
*/
|
|
335
|
-
|
|
372
|
+
/**
|
|
373
|
+
* Maps an SDK `MessagePart[]` into the single AI SDK v5 user `ModelMessage` that
|
|
374
|
+
* `agent.stream()` accepts.
|
|
375
|
+
*
|
|
376
|
+
* `text` parts collapse into text content blocks; `image` / `file` parts become v5 `file`
|
|
377
|
+
* content blocks (`mediaType` + base64 `data` + optional `filename`) that Mastra forwards to the
|
|
378
|
+
* gateway bridge, which collects them into `ChatMessageIn.files[]`. Pre-stream validation and the
|
|
379
|
+
* input-part guard live in the SDK's {@link lowerStreamInput}, so file caps and the
|
|
380
|
+
* `MULTIMODAL_NOT_SUPPORTED` / `INVALID_MESSAGE_CONTENT` semantics are identical to the Claude
|
|
381
|
+
* harness; this method only supplies the Mastra-specific lowering of each part.
|
|
382
|
+
*/
|
|
383
|
+
private toMastraStreamInput;
|
|
384
|
+
stream(agentId: string, threadId: string, message: string | MessagePart[], options?: StreamOptions): Promise<ChatStreamResult>;
|
|
385
|
+
/**
|
|
386
|
+
* Allocate a `MastraStreamBroker` for the (agentId, threadId) pair,
|
|
387
|
+
* dispose any prior broker on the same thread, hand the initial Mastra
|
|
388
|
+
* `output` to it, and wire the consumer's `abortSignal` (if any) to
|
|
389
|
+
* `broker.abort()`. The returned `ChatStreamResult.eventStream` reads
|
|
390
|
+
* from the broker's initial sink, where parallel
|
|
391
|
+
* `tool-approval-request` events surface for batch-style consumer UI.
|
|
392
|
+
*/
|
|
393
|
+
private startBrokerStream;
|
|
336
394
|
/**
|
|
337
395
|
* @requirements
|
|
338
396
|
* - MUST throw an error if the specified `agentId` is not found in `activeAgents`.
|