@salesforce/sfdx-agent-harness-mastra 0.13.0 → 0.15.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 +7 -6
- package/dist/default-model-config-factory.d.ts +5 -1
- package/dist/default-model-config-factory.js +5 -2
- package/dist/gen-sink.d.ts +6 -21
- package/dist/gen-sink.js +6 -49
- package/dist/llmg-express-model-config-factory.d.ts +2 -1
- package/dist/llmg-express-model-config-factory.js +3 -1
- package/dist/mastra-approval-coordinator.d.ts +273 -0
- package/dist/mastra-approval-coordinator.js +640 -0
- package/dist/mastra-event-adapter.d.ts +9 -7
- package/dist/mastra-event-adapter.js +36 -18
- package/dist/mastra-harness.d.ts +42 -211
- package/dist/mastra-harness.js +112 -585
- package/dist/mastra-message-mapper.d.ts +2 -6
- package/dist/mastra-message-mapper.js +12 -7
- package/dist/mastra-tool-mapper.d.ts +36 -22
- package/dist/mastra-tool-mapper.js +74 -30
- package/dist/mcp-config-mapper.d.ts +4 -0
- package/dist/mcp-config-mapper.js +24 -0
- package/dist/model-config-factory.d.ts +7 -2
- package/dist/salesforce-llm-gateway.d.ts +6 -2
- package/dist/salesforce-llm-gateway.js +16 -3
- package/package.json +5 -5
- package/dist/mastra-stream-broker.d.ts +0 -210
- package/dist/mastra-stream-broker.js +0 -563
package/README.md
CHANGED
|
@@ -175,18 +175,19 @@ const harnessFactory = new MastraHarnessFactory({
|
|
|
175
175
|
});
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
When the timer fires, the harness aborts the suspended Mastra run
|
|
179
|
-
yields a synthetic terminal pair on the
|
|
178
|
+
When the timer fires, the harness aborts the suspended Mastra run via the per-`(agentId, threadId)`
|
|
179
|
+
`MastraApprovalCoordinator`, marks every emitted approval as auto-resolved, and yields a synthetic terminal pair on the
|
|
180
|
+
active `eventStream`:
|
|
180
181
|
|
|
181
182
|
```ts
|
|
182
183
|
{ type: 'error', error: Error('Tool approval timed out after 60000ms.'), code: 'tool-approval-timeout' }
|
|
183
184
|
{ type: 'finish', finishReason: 'error' }
|
|
184
185
|
```
|
|
185
186
|
|
|
186
|
-
Subsequent `approveToolCall` / `declineToolCall` / `submitToolResult` calls for the timed-out tool
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
Subsequent `approveToolCall` / `declineToolCall` / `submitToolResult` calls for the timed-out tool throw because the
|
|
188
|
+
coordinator has already auto-resolved them. The granularity is per `toolCallId` — each emitted approval arms its own
|
|
189
|
+
timer; the first one to fire tears down the whole turn (since Mastra can't continue the suspended run after timeout
|
|
190
|
+
anyway). To observe the timeout, keep iterating the `eventStream` past the `tool-approval-request` event so the
|
|
190
191
|
synthetic terminal pair lands in your loop:
|
|
191
192
|
|
|
192
193
|
```ts
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LogBus } from '@salesforce/agentic-common';
|
|
1
2
|
import { type LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
|
|
2
3
|
import type { MastraModelConfigFactory, ResolvedModelConfig } from './model-config-factory.js';
|
|
3
4
|
/**
|
|
@@ -6,7 +7,10 @@ import type { MastraModelConfigFactory, ResolvedModelConfig } from './model-conf
|
|
|
6
7
|
* Wraps the LLMGatewayClient in a SalesforceMastraModelGateway and calls
|
|
7
8
|
* resolveLanguageModel() to produce the LanguageModelV2 that Mastra consumes.
|
|
8
9
|
* Captures the gateway model at creation time to provide multimodal validation.
|
|
10
|
+
* Forwards the harness's `logBus` into the bridge so streaming anomalies
|
|
11
|
+
* (e.g. a Bedrock-Anthropic stream that ends without a usage chunk) surface as
|
|
12
|
+
* structured logs.
|
|
9
13
|
*/
|
|
10
14
|
export declare class DefaultMastraModelConfigFactory implements MastraModelConfigFactory {
|
|
11
|
-
create(llmGatewayClient: LLMGatewayClient): ResolvedModelConfig;
|
|
15
|
+
create(llmGatewayClient: LLMGatewayClient, logBus?: LogBus): ResolvedModelConfig;
|
|
12
16
|
}
|
|
@@ -10,10 +10,13 @@ import { SalesforceMastraModelGateway } from './salesforce-llm-gateway.js';
|
|
|
10
10
|
* Wraps the LLMGatewayClient in a SalesforceMastraModelGateway and calls
|
|
11
11
|
* resolveLanguageModel() to produce the LanguageModelV2 that Mastra consumes.
|
|
12
12
|
* Captures the gateway model at creation time to provide multimodal validation.
|
|
13
|
+
* Forwards the harness's `logBus` into the bridge so streaming anomalies
|
|
14
|
+
* (e.g. a Bedrock-Anthropic stream that ends without a usage chunk) surface as
|
|
15
|
+
* structured logs.
|
|
13
16
|
*/
|
|
14
17
|
export class DefaultMastraModelConfigFactory {
|
|
15
|
-
create(llmGatewayClient) {
|
|
16
|
-
const agentGateway = new SalesforceMastraModelGateway(llmGatewayClient);
|
|
18
|
+
create(llmGatewayClient, logBus) {
|
|
19
|
+
const agentGateway = new SalesforceMastraModelGateway(llmGatewayClient, undefined, logBus);
|
|
17
20
|
const model = agentGateway.resolveLanguageModel();
|
|
18
21
|
const gatewayModel = llmGatewayClient.getModel();
|
|
19
22
|
return {
|
package/dist/gen-sink.d.ts
CHANGED
|
@@ -1,23 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* `
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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.
|
|
2
|
+
* Re-export of the `GenSink` primitive from the SDK's harness-implementation
|
|
3
|
+
* subpath (`@salesforce/sfdx-agent-sdk/harness`). See that surface for the
|
|
4
|
+
* single-iteration invariant; issue #529 is the rationale for the
|
|
5
|
+
* cross-harness lift and for the subpath split (consumer applications can no
|
|
6
|
+
* longer import `GenSink` from the bare specifier — they have no use for it).
|
|
14
7
|
*/
|
|
15
|
-
export
|
|
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
|
-
}
|
|
8
|
+
export { GenSink } from '@salesforce/sfdx-agent-sdk/harness';
|
package/dist/gen-sink.js
CHANGED
|
@@ -3,54 +3,11 @@
|
|
|
3
3
|
* See LICENSE.txt for license terms.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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.
|
|
6
|
+
* Re-export of the `GenSink` primitive from the SDK's harness-implementation
|
|
7
|
+
* subpath (`@salesforce/sfdx-agent-sdk/harness`). See that surface for the
|
|
8
|
+
* single-iteration invariant; issue #529 is the rationale for the
|
|
9
|
+
* cross-harness lift and for the subpath split (consumer applications can no
|
|
10
|
+
* longer import `GenSink` from the bare specifier — they have no use for it).
|
|
18
11
|
*/
|
|
19
|
-
export
|
|
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
|
-
}
|
|
12
|
+
export { GenSink } from '@salesforce/sfdx-agent-sdk/harness';
|
|
56
13
|
//# sourceMappingURL=gen-sink.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LogBus } from '@salesforce/agentic-common';
|
|
1
2
|
import { type LLMGatewayClient } from '@salesforce/llm-gateway-sdk';
|
|
2
3
|
import type { MastraModelConfigFactory, ResolvedModelConfig } from './model-config-factory.js';
|
|
3
4
|
export interface LLMGExpressConfig {
|
|
@@ -21,5 +22,5 @@ export interface LLMGExpressConfig {
|
|
|
21
22
|
export declare class LLMGExpressMastraModelConfigFactory implements MastraModelConfigFactory {
|
|
22
23
|
private readonly config;
|
|
23
24
|
constructor(config: LLMGExpressConfig);
|
|
24
|
-
create(llmGatewayClient: LLMGatewayClient): ResolvedModelConfig;
|
|
25
|
+
create(llmGatewayClient: LLMGatewayClient, _logBus?: LogBus): ResolvedModelConfig;
|
|
25
26
|
}
|
|
@@ -18,7 +18,9 @@ export class LLMGExpressMastraModelConfigFactory {
|
|
|
18
18
|
constructor(config) {
|
|
19
19
|
this.config = config;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
// _logBus is unused: the express path resolves through Mastra's built-in OpenAI-compatible
|
|
22
|
+
// provider, not SalesforceMastraModelGateway, so the missing-usage warn from W-22692131 doesn't apply.
|
|
23
|
+
create(llmGatewayClient, _logBus) {
|
|
22
24
|
const model = {
|
|
23
25
|
providerId: 'llmg-express',
|
|
24
26
|
modelId: this.config.modelId,
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type { Agent } from '@mastra/core/agent';
|
|
2
|
+
import type { RequestContext } from '@mastra/core/request-context';
|
|
3
|
+
import type { ChunkType } from '@mastra/core/stream';
|
|
4
|
+
import { type ChatEvent, type McpToolAnnotations } from '@salesforce/sfdx-agent-sdk';
|
|
5
|
+
import { GenSink } from '@salesforce/sfdx-agent-sdk/harness';
|
|
6
|
+
import type { LogBus } from '@salesforce/agentic-common';
|
|
7
|
+
/**
|
|
8
|
+
* Output shape from `agent.stream()` / `agent.approveToolCall()` /
|
|
9
|
+
* `agent.declineToolCall()`. Captured as a structural type so the
|
|
10
|
+
* coordinator doesn't depend on Mastra's exact `StreamOutput` generic.
|
|
11
|
+
*
|
|
12
|
+
* Mastra's actual output also carries `textStream`; the coordinator doesn't
|
|
13
|
+
* need it (it derives text deltas from `fullStream` via the event adapter)
|
|
14
|
+
* and structural typing accepts the wider value at the call site.
|
|
15
|
+
*/
|
|
16
|
+
export interface MastraStreamOutput {
|
|
17
|
+
runId: string;
|
|
18
|
+
fullStream: ReadableStream<ChunkType>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Looks up MCP-server enrichment (`serverName` / `annotations`) for a given
|
|
22
|
+
* Mastra-namespaced tool name (`${serverName}_${toolName}`). Returns
|
|
23
|
+
* `undefined` for non-MCP tools (consumer-declared, workspace, built-in).
|
|
24
|
+
*/
|
|
25
|
+
export type MastraMcpToolMetadataLookup = (namespacedToolName: string) => {
|
|
26
|
+
serverName: string;
|
|
27
|
+
annotations?: McpToolAnnotations;
|
|
28
|
+
} | undefined;
|
|
29
|
+
export interface MastraApprovalCoordinatorOptions {
|
|
30
|
+
agent: Agent;
|
|
31
|
+
threadId: string;
|
|
32
|
+
memory: {
|
|
33
|
+
thread: string;
|
|
34
|
+
resource: string;
|
|
35
|
+
};
|
|
36
|
+
requestContext: RequestContext;
|
|
37
|
+
toolApprovalTimeoutMs: number;
|
|
38
|
+
/**
|
|
39
|
+
* Approval-emission mode (#447). Defaults to `undefined` (no gating).
|
|
40
|
+
*
|
|
41
|
+
* - `undefined`: stream is run without `requireToolApproval`. Mastra
|
|
42
|
+
* suspends only on tools whose per-tool `requireApproval` is `true`
|
|
43
|
+
* (consumer tools post-2c are `false` so they don't suspend; the
|
|
44
|
+
* bridge's parker `execute` handles their lifecycle natively).
|
|
45
|
+
* - `'serial'`: stream runs with `requireToolApproval: true`. The
|
|
46
|
+
* coordinator emits one `tool-approval-request` per natural
|
|
47
|
+
* `tool-call-approval` chunk — Mastra serializes one approval per
|
|
48
|
+
* suspension.
|
|
49
|
+
* - `'batch'`: same as serial except `tool-approval-request` is
|
|
50
|
+
* front-loaded off the adapter's `tool-call` events so parallel
|
|
51
|
+
* `tool_use` batches all surface their approval-requests on the
|
|
52
|
+
* single per-turn stream.
|
|
53
|
+
*
|
|
54
|
+
* Note: in approval mode, consumer-executed tools still bypass the
|
|
55
|
+
* approval gate (per the `StreamOptions.requireToolApproval` JSDoc) —
|
|
56
|
+
* the coordinator silently calls `agent.approveToolCall(id)` for them
|
|
57
|
+
* without surfacing a `tool-approval-request` ChatEvent.
|
|
58
|
+
*/
|
|
59
|
+
mode?: 'serial' | 'batch';
|
|
60
|
+
/**
|
|
61
|
+
* Set of tool names registered via `AgentConfig.tools`. The coordinator
|
|
62
|
+
* uses this to route `tool-call-approval` chunks: if the toolName is in
|
|
63
|
+
* the set, auto-approve silently (consumer tools bypass the gate); else
|
|
64
|
+
* surface a `tool-approval-request` ChatEvent and park.
|
|
65
|
+
*
|
|
66
|
+
* Empty set when no consumer tools are configured — every approval
|
|
67
|
+
* chunk surfaces to the consumer in approval mode.
|
|
68
|
+
*/
|
|
69
|
+
consumerToolNames: ReadonlySet<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Resolves MCP enrichment for a Mastra-namespaced tool name. Wired to
|
|
72
|
+
* `lookupMcpToolMetadata` in {@link MastraHarness} so the same lookup
|
|
73
|
+
* the legacy `createEventStream` used post-enriches `tool-call` /
|
|
74
|
+
* `tool-result` / `tool-approval-request` events.
|
|
75
|
+
*/
|
|
76
|
+
lookupMcpToolMetadata?: MastraMcpToolMetadataLookup;
|
|
77
|
+
logBus?: LogBus;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Per-`(agentId, threadId)` coordinator that subsumes the pre-#529
|
|
81
|
+
* `MastraStreamBroker` + `activeRuns` pair into one object owning a single
|
|
82
|
+
* sink, single multi-source pump loop, and single set of teardown paths.
|
|
83
|
+
*
|
|
84
|
+
* Responsibilities:
|
|
85
|
+
* - Approval gating in `'serial'` / `'batch'` mode: emit
|
|
86
|
+
* `tool-approval-request` for non-consumer tools, drive
|
|
87
|
+
* `agent.approveToolCall(...)` / `declineToolCall(...)` when the
|
|
88
|
+
* consumer settles.
|
|
89
|
+
* - Consumer-tool plumbing: every `AgentConfig.tools` entry has
|
|
90
|
+
* `requireApproval: false` and a Promise-returning `execute` that parks
|
|
91
|
+
* on the coordinator's `parkConsumerToolCall(...)`. Mastra natively
|
|
92
|
+
* suspends the agentic loop while the Promise pends, so consumer tools
|
|
93
|
+
* don't go through `agent.approveToolCall(...)` in non-approval mode.
|
|
94
|
+
* In approval mode the coordinator auto-approves them silently so the
|
|
95
|
+
* bridge `execute` parker still runs on the resumed stream.
|
|
96
|
+
* - Multi-source pump: Mastra returns a fresh `fullStream` per resume
|
|
97
|
+
* call; the coordinator pumps each one into the same `initial` sink so
|
|
98
|
+
* the consumer iterates one stream per turn.
|
|
99
|
+
* - Snapshot-drain before each resume call (Mastra-specific: workflow
|
|
100
|
+
* snapshots persist asynchronously after `tool-call-approval`).
|
|
101
|
+
* - Approval-timeout / abort / dispose teardown — single helper drains
|
|
102
|
+
* timers, rejects pending parkers, marks emitted approvals as
|
|
103
|
+
* coordinator-settled, and pushes the synthetic terminal pair on the
|
|
104
|
+
* sink.
|
|
105
|
+
*
|
|
106
|
+
* Issue #529 contract: settle calls (`approveToolCall` / `declineToolCall` /
|
|
107
|
+
* `submitToolResult`) are control messages on the chat() turn's existing
|
|
108
|
+
* eventStream. There is exactly one sink (`initial`) per turn; post-resume
|
|
109
|
+
* events flow through the same sink the consumer is iterating from
|
|
110
|
+
* `chat()`. There are no per-tool sinks and no `lastGenSinkStale` flag.
|
|
111
|
+
*/
|
|
112
|
+
export declare class MastraApprovalCoordinator {
|
|
113
|
+
private readonly agent;
|
|
114
|
+
private readonly memory;
|
|
115
|
+
private readonly requestContext;
|
|
116
|
+
private readonly toolApprovalTimeoutMs;
|
|
117
|
+
private readonly mode;
|
|
118
|
+
private readonly consumerToolNames;
|
|
119
|
+
private readonly lookupMcpToolMetadata?;
|
|
120
|
+
private readonly adapter;
|
|
121
|
+
/** Single per-turn sink. Issue #529 contract: one stream per turn. */
|
|
122
|
+
private readonly initial;
|
|
123
|
+
/** Buffered consumer decisions keyed by `toolCallId`. */
|
|
124
|
+
private readonly decisions;
|
|
125
|
+
/** ToolCallIds for which a `tool-approval-request` ChatEvent has been emitted. */
|
|
126
|
+
private readonly emittedApprovals;
|
|
127
|
+
/** ToolCallIds the consumer has settled. Rejects double-settle. */
|
|
128
|
+
private readonly consumerSettled;
|
|
129
|
+
/**
|
|
130
|
+
* ToolCallIds the coordinator auto-resolved (timeout / abort / dispose
|
|
131
|
+
* / consumer-tool auto-approve). A subsequent settle for these ids
|
|
132
|
+
* rejects with "already auto-resolved by the coordinator".
|
|
133
|
+
*/
|
|
134
|
+
private readonly settledByCoordinator;
|
|
135
|
+
/** Per-toolCallId approval-timeout timers (armed when an approval is emitted). */
|
|
136
|
+
private readonly approvalTimers;
|
|
137
|
+
/** Args from the adapter's `tool-call` ChatEvent keyed by `toolCallId`. */
|
|
138
|
+
private readonly toolCallArgs;
|
|
139
|
+
/**
|
|
140
|
+
* Mastra's current `runId` after the latest stream/resume. Updated on
|
|
141
|
+
* each successful pump entry. Needed for the next
|
|
142
|
+
* `agent.approveToolCall(...)` / `declineToolCall(...)`.
|
|
143
|
+
*/
|
|
144
|
+
private currentRunId;
|
|
145
|
+
/**
|
|
146
|
+
* The toolCallId Mastra is currently suspended on (after the natural
|
|
147
|
+
* `tool-call-approval` chunk). `null` when no suspension. The
|
|
148
|
+
* coordinator's pump loop reads this when the current `fullStream`
|
|
149
|
+
* closes to decide whether to drive a resume.
|
|
150
|
+
*/
|
|
151
|
+
private currentSuspendId;
|
|
152
|
+
/** Consumer-tool: bound parkers, keyed by `toolCallId`. `submitToolResult` resolves these. */
|
|
153
|
+
private readonly pendingByToolCallId;
|
|
154
|
+
/**
|
|
155
|
+
* Consumer-tool: results submitted before the bridge `execute` handler
|
|
156
|
+
* parked. Keyed by `toolCallId`. Used when `submitToolResult` arrives
|
|
157
|
+
* during the gap between the `tool-call` ChatEvent and the bridge
|
|
158
|
+
* handler's actual invocation — the staged result resolves the next
|
|
159
|
+
* parker invocation for the same id.
|
|
160
|
+
*/
|
|
161
|
+
private readonly preSubmittedByToolCallId;
|
|
162
|
+
/**
|
|
163
|
+
* Callbacks invoked exactly once during teardown (`abort` or `dispose`,
|
|
164
|
+
* whichever fires first, or natural pump exit).
|
|
165
|
+
*/
|
|
166
|
+
private readonly teardownCallbacks;
|
|
167
|
+
/**
|
|
168
|
+
* Resolved by `recordDecision` (consumer settled) or `teardown`. The
|
|
169
|
+
* outer pump loop awaits this when it sees a suspension chunk before
|
|
170
|
+
* the consumer has settled. `'continued'` means a decision is now in
|
|
171
|
+
* `decisions`; `'done'` means the pump should exit (teardown fired).
|
|
172
|
+
*/
|
|
173
|
+
private continuationResolver?;
|
|
174
|
+
private aborted;
|
|
175
|
+
private disposed;
|
|
176
|
+
private timedOut;
|
|
177
|
+
constructor(opts: MastraApprovalCoordinatorOptions);
|
|
178
|
+
initialSink(): GenSink<ChatEvent>;
|
|
179
|
+
onTeardown(callback: () => void): void;
|
|
180
|
+
private runTeardownCallbacks;
|
|
181
|
+
/**
|
|
182
|
+
* Begin pumping the initial Mastra `fullStream`. Stores `runId` and
|
|
183
|
+
* spawns the multi-source pump loop. The consumer iterates
|
|
184
|
+
* `initialSink().generator()` to observe events.
|
|
185
|
+
*/
|
|
186
|
+
start(output: MastraStreamOutput): void;
|
|
187
|
+
abort(): void;
|
|
188
|
+
dispose(): void;
|
|
189
|
+
/**
|
|
190
|
+
* Single teardown path for abort / dispose / approval-timeout / pump-
|
|
191
|
+
* error. Drains timers, rejects pending consumer-tool parkers, marks
|
|
192
|
+
* every emitted approval as coordinator-settled, releases Mastra's
|
|
193
|
+
* suspended run, pushes the synthetic terminal pair on the sink, and
|
|
194
|
+
* fires teardown callbacks.
|
|
195
|
+
*
|
|
196
|
+
* The `reason` parameter only changes the sink's terminal shape:
|
|
197
|
+
* `'dispose'` pushes error-only (matches Claude's dispose contract);
|
|
198
|
+
* everything else pushes error+finish.
|
|
199
|
+
*/
|
|
200
|
+
private teardown;
|
|
201
|
+
approve(toolCallId: string): void;
|
|
202
|
+
decline(toolCallId: string): void;
|
|
203
|
+
private recordDecision;
|
|
204
|
+
/**
|
|
205
|
+
* Parker callback the consumer-tool bridge `execute` handler invokes
|
|
206
|
+
* when Mastra calls the tool. Returns a Promise the consumer settles
|
|
207
|
+
* via {@link submitToolResult}.
|
|
208
|
+
*
|
|
209
|
+
* Mastra's bridge `execute` knows the `toolCallId` from its execution
|
|
210
|
+
* context, so binding is direct (no FIFO match by name). The
|
|
211
|
+
* pre-submit ladder handles the rare case where `submitToolResult`
|
|
212
|
+
* lands before the bridge handler's `execute` actually runs:
|
|
213
|
+
*
|
|
214
|
+
* 1. A pre-submitted result is staged for this `toolCallId` →
|
|
215
|
+
* resolve immediately.
|
|
216
|
+
* 2. Otherwise → bind under `toolCallId`; the eventual
|
|
217
|
+
* `submitToolResult` resolves us.
|
|
218
|
+
*/
|
|
219
|
+
readonly parkConsumerToolCall: (toolCallId: string) => Promise<{
|
|
220
|
+
result: unknown;
|
|
221
|
+
isError?: boolean;
|
|
222
|
+
}>;
|
|
223
|
+
/**
|
|
224
|
+
* Settle a parked consumer-tool call. Issue #529 contract: returns
|
|
225
|
+
* `void`; post-resume events flow through the same `initial` sink the
|
|
226
|
+
* consumer is iterating from `chat()`. Mastra natively continues the
|
|
227
|
+
* agentic loop on the same `fullStream` once the parker Promise
|
|
228
|
+
* resolves (probe-validated, see #529 step 2c).
|
|
229
|
+
*/
|
|
230
|
+
submitToolResult(toolCallId: string, result: unknown, isError?: boolean): void;
|
|
231
|
+
/**
|
|
232
|
+
* Multi-source pump loop. Drains the initial Mastra `fullStream` plus
|
|
233
|
+
* every continuation stream returned by `agent.approveToolCall(...)` /
|
|
234
|
+
* `declineToolCall(...)` into the same `initial` sink.
|
|
235
|
+
*
|
|
236
|
+
* Termination conditions:
|
|
237
|
+
* - Saw `finish` chunk on a stream and no further suspension awaits a
|
|
238
|
+
* decision.
|
|
239
|
+
* - Saw an `error` chunk (terminal under SDK contract).
|
|
240
|
+
* - `abort()` / `dispose()` / approval-timeout fired.
|
|
241
|
+
*/
|
|
242
|
+
private runPumpLoop;
|
|
243
|
+
/**
|
|
244
|
+
* Pump one `ReadableStream<ChunkType>` into the sink until one of:
|
|
245
|
+
* - `'terminal'`: saw `finish` chunk; sink ended.
|
|
246
|
+
* - `'suspended'`: saw `tool-call-approval` chunk on a non-consumer
|
|
247
|
+
* tool (or auto-approved consumer tool didn't suspend on it). The
|
|
248
|
+
* stream may still be pumping — drain remaining chunks for the
|
|
249
|
+
* Mastra-snapshot-persistence guarantee, then return.
|
|
250
|
+
* - `'pump-error'`: stream threw; sink ended with error+finish.
|
|
251
|
+
*/
|
|
252
|
+
private pumpUntilSuspendOrTerminal;
|
|
253
|
+
/**
|
|
254
|
+
* Drive a resume call and set up the next stream for the pump loop.
|
|
255
|
+
* Returns `'done'` if the resume rejected (turn over, error already
|
|
256
|
+
* pushed) or the new `fullStream` to pump next.
|
|
257
|
+
*/
|
|
258
|
+
private driveResumeReturning;
|
|
259
|
+
private awaitContinuation;
|
|
260
|
+
/**
|
|
261
|
+
* Push an event onto the sink with MCP-server enrichment applied (when
|
|
262
|
+
* the toolName resolves to a known MCP catalog entry). Mirrors the
|
|
263
|
+
* pre-#529 `createEventStream`'s post-enrichment of `tool-call` /
|
|
264
|
+
* `tool-result` / `tool-approval-request`.
|
|
265
|
+
*/
|
|
266
|
+
private routeEnriched;
|
|
267
|
+
private maybeEnrich;
|
|
268
|
+
private emitApprovalRequest;
|
|
269
|
+
private armApprovalTimer;
|
|
270
|
+
private cancelTimer;
|
|
271
|
+
private cancelAllTimers;
|
|
272
|
+
private handleApprovalTimeout;
|
|
273
|
+
}
|