@salesforce/sfdx-agent-harness-mastra 0.92.0 → 0.94.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/CHANGELOG.md CHANGED
@@ -3,6 +3,20 @@
3
3
  All notable changes to `@salesforce/sfdx-agent-harness-mastra` are documented in this file.
4
4
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
+ ## [0.94.0] - 2026-10-01
7
+
8
+ ### Fixes
9
+ - **harness-mastra**: persist declined tool-call reason from approval.reason @W-24066893@ ([#850](https://github.com/forcedotcom/agentic-dx/pull/850))
10
+
11
+ ## [0.93.0] - 2026-09-29
12
+
13
+ ### Features
14
+ - **agent-sdk,harness-mastra,harness-claude,harness-openai**: project next-turn context occupancy @W-24236168@ ([#849](https://github.com/forcedotcom/agentic-dx/pull/849))
15
+
16
+ ### Chores
17
+ - **deps**: bump @anthropic-ai/sdk from 0.126.0 to 0.127.0 ([#847](https://github.com/forcedotcom/agentic-dx/pull/847))
18
+ - **deps-dev**: bump eslint from 10.10.0 to 10.11.0 in the eslint group ([#844](https://github.com/forcedotcom/agentic-dx/pull/844))
19
+
6
20
  ## [0.92.0] - 2026-09-25
7
21
 
8
22
  ### Fixes
@@ -2,6 +2,7 @@
2
2
  * Copyright 2026, Salesforce, Inc. All rights reserved.
3
3
  * See LICENSE.txt for license terms.
4
4
  */
5
+ import { DEFAULT_TOOL_DECLINE_REASON } from '@mastra/core/agent';
5
6
  import { CONTEXT_LENGTH_EXCEEDED_CODE, createContextLengthExceededError } from '@salesforce/sfdx-agent-sdk';
6
7
  import { hasToolArgsValidationErrorMarker } from './tool-args-marker.js';
7
8
  import { isClassifiedStreamError } from './stream-errors.js';
@@ -140,7 +141,7 @@ export class MastraEventAdapter {
140
141
  type: 'tool-result',
141
142
  toolCallId: chunk.payload.toolCallId,
142
143
  toolName: chunk.payload.toolName,
143
- result: chunk.payload.approval.reason ?? 'Tool call was not approved by the user',
144
+ result: chunk.payload.approval.reason ?? DEFAULT_TOOL_DECLINE_REASON,
144
145
  isError: true,
145
146
  };
146
147
  case 'step-start':
@@ -259,6 +259,23 @@ export declare class MastraHarness implements MastraAgentHarness {
259
259
  private readonly storageRootFolder;
260
260
  readonly harnessId = "mastra";
261
261
  readonly protocolVersion = 1;
262
+ /**
263
+ * `true` = "when a `reasoningTokens` count is reported, it is already inside
264
+ * `outputTokens`", so the SDK's forward-looking `projectedContextTokens`
265
+ * subtracts `reasoningTokens` from `outputTokens` to get the visible answer
266
+ * appended to the next prompt. Correct on both Mastra provider paths for two
267
+ * different reasons: OpenAI Responses (`mapOpenAIUsage`) reports reasoning
268
+ * INSIDE `output_tokens`, so the subtraction yields visible text; Bedrock-
269
+ * Anthropic (`mapAnthropicUsage`) reports NO reasoning tokens at all
270
+ * (`outputTokens.reasoning = undefined` → SDK `reasoningTokens: undefined`),
271
+ * so the subtraction is vacuous (`− (undefined ?? 0)`) — harmless, NOT
272
+ * "reasoning folded into output". This single boolean's correctness on the
273
+ * Anthropic path depends on `mapAnthropicUsage` continuing to report no
274
+ * reasoning; if that changes to report reasoning OUTSIDE `output_tokens`, this
275
+ * flag must become per-reading/per-provider. See
276
+ * {@link AgentHarness.outputTokensIncludeReasoning} (W-24236168).
277
+ */
278
+ readonly outputTokensIncludeReasoning = true;
262
279
  /**
263
280
  * Registry of agentId → Mastra state. Holds per-agent MCPClient instances
264
281
  * so each agent has isolated server connections; sharing across agents
@@ -417,6 +417,23 @@ export class MastraHarness {
417
417
  storageRootFolder;
418
418
  harnessId = 'mastra';
419
419
  protocolVersion = 1;
420
+ /**
421
+ * `true` = "when a `reasoningTokens` count is reported, it is already inside
422
+ * `outputTokens`", so the SDK's forward-looking `projectedContextTokens`
423
+ * subtracts `reasoningTokens` from `outputTokens` to get the visible answer
424
+ * appended to the next prompt. Correct on both Mastra provider paths for two
425
+ * different reasons: OpenAI Responses (`mapOpenAIUsage`) reports reasoning
426
+ * INSIDE `output_tokens`, so the subtraction yields visible text; Bedrock-
427
+ * Anthropic (`mapAnthropicUsage`) reports NO reasoning tokens at all
428
+ * (`outputTokens.reasoning = undefined` → SDK `reasoningTokens: undefined`),
429
+ * so the subtraction is vacuous (`− (undefined ?? 0)`) — harmless, NOT
430
+ * "reasoning folded into output". This single boolean's correctness on the
431
+ * Anthropic path depends on `mapAnthropicUsage` continuing to report no
432
+ * reasoning; if that changes to report reasoning OUTSIDE `output_tokens`, this
433
+ * flag must become per-reading/per-provider. See
434
+ * {@link AgentHarness.outputTokensIncludeReasoning} (W-24236168).
435
+ */
436
+ outputTokensIncludeReasoning = true;
420
437
  /**
421
438
  * Registry of agentId → Mastra state. Holds per-agent MCPClient instances
422
439
  * so each agent has isolated server connections; sharing across agents
@@ -1,4 +1,4 @@
1
- import type { MastraDBMessage, MastraMessagePart } from '@mastra/core/agent';
1
+ import { type MastraDBMessage, type MastraMessagePart } from '@mastra/core/agent';
2
2
  import type { Message, MessagePart } from '@salesforce/sfdx-agent-sdk';
3
3
  import type { LogBus } from '@salesforce/agentic-common';
4
4
  /**
@@ -2,6 +2,7 @@
2
2
  * Copyright 2026, Salesforce, Inc. All rights reserved.
3
3
  * See LICENSE.txt for license terms.
4
4
  */
5
+ import { DEFAULT_TOOL_DECLINE_REASON } from '@mastra/core/agent';
5
6
  import { hasToolArgsValidationErrorMarker } from './tool-args-marker.js';
6
7
  /**
7
8
  * Reads the SDK `fileName` stashed under `providerMetadata.salesforce.fileName` when a file part
@@ -188,14 +189,24 @@ export function mapMastraPartToMessagePart(part, logBus) {
188
189
  // Prefer the structured `result` (the write path preserves it
189
190
  // alongside `errorText`) so a non-string error payload round-trips
190
191
  // as an object, not a JSON string; fall back to `errorText` for
191
- // natively-persisted error invocations that carry only that.
192
+ // natively-persisted error invocations that carry only that. A
193
+ // decline persists as `output-denied` carrying its reason on
194
+ // `approval.reason` (no `result`/`errorText`), so read that last —
195
+ // otherwise the declined call's message is lost on reload. A
196
+ // compatible persisted record can omit the optional reason;
197
+ // use Mastra's default denial text as the final fallback for that
198
+ // state so history never reloads an empty decline.
192
199
  return [
193
200
  toolCall,
194
201
  {
195
202
  type: 'tool-result',
196
203
  toolCallId: inv.toolCallId,
197
204
  toolName: inv.toolName,
198
- result: inv.result ?? inv.errorText,
205
+ result: inv.result ??
206
+ inv.errorText ??
207
+ (inv.state === 'output-denied'
208
+ ? (inv.approval?.reason ?? DEFAULT_TOOL_DECLINE_REASON)
209
+ : undefined),
199
210
  isError: true,
200
211
  },
201
212
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/sfdx-agent-harness-mastra",
3
- "version": "0.92.0",
3
+ "version": "0.94.0",
4
4
  "description": "Mastra-backed AgentHarness implementation for @salesforce/sfdx-agent-sdk",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "dependencies": {
32
32
  "@ai-sdk/provider": "4.0.14",
33
33
  "@anthropic-ai/bedrock-sdk": "^0.33.6",
34
- "@anthropic-ai/sdk": "^0.126.0",
34
+ "@anthropic-ai/sdk": "^0.127.0",
35
35
  "@mastra/core": "^1.67.0",
36
36
  "@mastra/libsql": "^1.23.0",
37
37
  "@mastra/mcp": "^1.18.0",
@@ -42,16 +42,16 @@
42
42
  "openai": "^7.23.0"
43
43
  },
44
44
  "peerDependencies": {
45
- "@salesforce/sfdx-agent-sdk": "0.93.0"
45
+ "@salesforce/sfdx-agent-sdk": "0.95.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@eslint/js": "^10.0.1",
49
49
  "@salesforce/harness-conformance": "0.0.1",
50
- "@salesforce/sfdx-agent-sdk": "0.93.0",
50
+ "@salesforce/sfdx-agent-sdk": "0.95.0",
51
51
  "@types/node": "^22.20.1",
52
52
  "@vitest/coverage-istanbul": "^5.0.1",
53
53
  "@vitest/eslint-plugin": "^1.6.27",
54
- "eslint": "^10.10.0",
54
+ "eslint": "^10.11.0",
55
55
  "eslint-config-prettier": "^10.1.8",
56
56
  "eslint-import-resolver-typescript": "^4.4.5",
57
57
  "eslint-plugin-import": "^2.32.0",