@salesforce/sfdx-agent-sdk 0.19.0 → 0.20.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 +10 -0
- package/README.md +14 -12
- package/dist/index.d.ts +1 -1
- package/dist/types/events.d.ts +67 -1
- package/dist/types/usage.d.ts +26 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to `@salesforce/sfdx-agent-sdk` are documented in this file.
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
|
|
6
|
+
## [0.20.0] - 2026-06-12
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
- **agent-sdk,harness-mastra,harness-claude**: add tool-call-delta ChatEvent for streaming tool-call args @W-22965697@ ([#597](https://github.com/forcedotcom/agentic-dx/pull/597))
|
|
10
|
+
- **agent-sdk,harness-mastra,harness-claude**: add tool-progress ChatEvent variant @W-22951127@ ([#594](https://github.com/forcedotcom/agentic-dx/pull/594))
|
|
11
|
+
- **harness-claude**: map SDKThinkingTokensMessage to UsageMetadata.reasoningTokens ([#595](https://github.com/forcedotcom/agentic-dx/pull/595))
|
|
12
|
+
|
|
13
|
+
### Fixes
|
|
14
|
+
- **harness-claude**: map SDKResultSuccess.is_error to ChatEvent.error ([#593](https://github.com/forcedotcom/agentic-dx/pull/593))
|
|
15
|
+
|
|
6
16
|
## [0.19.0] - 2026-06-11
|
|
7
17
|
|
|
8
18
|
_No changes — released alongside dependent packages._
|
package/README.md
CHANGED
|
@@ -190,18 +190,20 @@ iterating the same `eventStream` until it sees a terminal `finish` event.
|
|
|
190
190
|
|
|
191
191
|
Discriminated union (`event.type`) of streaming events:
|
|
192
192
|
|
|
193
|
-
| Type | Key Fields | Description
|
|
194
|
-
| ----------------------- | --------------------------------------------------------------------------------------- |
|
|
195
|
-
| `start` | — | Stream has begun.
|
|
196
|
-
| `text-delta` | `text` | Incremental response text.
|
|
197
|
-
| `reasoning-delta` | `text` | Chain-of-thought fragment.
|
|
198
|
-
| `tool-call` | `toolCallId`, `toolName`, `args`, `annotations?`, `serverName?` | Tool invocation. `annotations` is the MCP-spec hints (`readOnlyHint`, `destructiveHint`, …) when the source declared them; `serverName` is set when the tool came from an MCP server.
|
|
199
|
-
| `tool-
|
|
200
|
-
| `tool-
|
|
201
|
-
| `
|
|
202
|
-
| `
|
|
203
|
-
| `
|
|
204
|
-
| `finish`
|
|
193
|
+
| Type | Key Fields | Description |
|
|
194
|
+
| ----------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
195
|
+
| `start` | — | Stream has begun. |
|
|
196
|
+
| `text-delta` | `text` | Incremental response text. |
|
|
197
|
+
| `reasoning-delta` | `text` | Chain-of-thought fragment. |
|
|
198
|
+
| `tool-call` | `toolCallId`, `toolName`, `args`, `annotations?`, `serverName?` | Tool invocation. `annotations` is the MCP-spec hints (`readOnlyHint`, `destructiveHint`, …) when the source declared them; `serverName` is set when the tool came from an MCP server. |
|
|
199
|
+
| `tool-call-delta` | `toolCallId`, `toolName?`, `argsTextDelta` | Incremental fragment of a tool call's args JSON, emitted while the model composes the call. Concatenate successive deltas for the same `toolCallId` to build the args text; the parsed result matches the terminal `tool-call.args`. Useful for live-typing tool inputs UI; consumers that don't need streaming-args can ignore this event and continue reading the parsed `args` on the terminal `tool-call`. `toolName` is optional (Claude's signal does not carry it on the wire). |
|
|
200
|
+
| `tool-approval-request` | `toolCall: ToolCallInfo`, `annotations?`, `serverName?` | Engine requests approval before executing a tool. Same `annotations` / `serverName` semantics as `tool-call`. |
|
|
201
|
+
| `tool-result` | `toolCallId`, `toolName`, `result`, `isError?`, `error?`, `annotations?`, `serverName?` | Tool execution completed. `error` is present when `isError` is true (best-effort: harnesses may synthesize an `Error` from a string payload, so `error.stack` is not guaranteed to point at the tool's throw site; the field may be absent on empty error payloads). Same `annotations` / `serverName` semantics as `tool-call`. |
|
|
202
|
+
| `tool-progress` | `toolCallId`, `toolName`, `output?`, `parentToolCallId?` | Incremental progress signal from a long-running tool call. Distinct from `tool-result`: zero or more `tool-progress` events may be emitted before exactly one terminal `tool-result`. `output` and `parentToolCallId` are best-effort enrichment that depends on the tool — the event itself is the load-bearing "tool is still working" signal; consumers SHOULD NOT branch on which optional fields are present. Useful for "tool is working" UI on long-running tools (build, test, deploy, large search, sub-agent tasks). |
|
|
203
|
+
| `step-start` | `stepIndex` | New LLM invocation step began. |
|
|
204
|
+
| `step-finish` | `stepIndex`, `finishReason`, `usage?` | Step completed with per-step token usage. |
|
|
205
|
+
| `error` | `error`, `code?` | Mid-stream error (yielded, not thrown). |
|
|
206
|
+
| `finish` | `finishReason`, `usage?` | Stream completed with aggregate token usage. |
|
|
205
207
|
|
|
206
208
|
> **Diagnostic logging.** The `ChatEvent` union is the harness-agnostic public stream — it never carries
|
|
207
209
|
> harness-internal chunk shapes. When a harness encounters a chunk type its adapter does not recognize (typically after
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { Message, MessagePart, ImagePart, FilePart } from './types/messages.js';
|
|
2
|
-
export type { ChatEvent, StartEvent, TextDeltaEvent, ReasoningDeltaEvent, ToolCallEvent, ToolApprovalRequestEvent, ToolResultEvent, StepStartEvent, StepFinishEvent, ErrorEvent, FinishEvent, ChatStreamResult, } from './types/events.js';
|
|
2
|
+
export type { ChatEvent, StartEvent, TextDeltaEvent, ReasoningDeltaEvent, ToolCallEvent, ToolCallDeltaEvent, ToolApprovalRequestEvent, ToolResultEvent, ToolProgressEvent, StepStartEvent, StepFinishEvent, ErrorEvent, FinishEvent, ChatStreamResult, } from './types/events.js';
|
|
3
3
|
export type { ToolDefinition, ToolCallInfo, ToolResultInfo } from './types/tools.js';
|
|
4
4
|
export type { ContextUsage, FinishReason, UsageMetadata } from './types/usage.js';
|
|
5
5
|
export type { AgentHooks, HooksForAgent, ToolResultRedactor, ToolResultRedactionInput, ToolResultRedactionResult, } from './types/redaction.js';
|
package/dist/types/events.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { FinishReason, UsageMetadata } from './usage.js';
|
|
|
8
8
|
* convention, with the addition of `tool-approval-request` for human-in-the-loop
|
|
9
9
|
* tool approval flows.
|
|
10
10
|
*/
|
|
11
|
-
export type ChatEvent = StartEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallEvent | ToolApprovalRequestEvent | ToolResultEvent | StepStartEvent | StepFinishEvent | ErrorEvent | FinishEvent;
|
|
11
|
+
export type ChatEvent = StartEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallEvent | ToolCallDeltaEvent | ToolApprovalRequestEvent | ToolResultEvent | ToolProgressEvent | StepStartEvent | StepFinishEvent | ErrorEvent | FinishEvent;
|
|
12
12
|
/**
|
|
13
13
|
* The stream has begun. Symmetric counterpart to {@link FinishEvent}.
|
|
14
14
|
*
|
|
@@ -68,6 +68,39 @@ export type ToolCallEvent = ToolCallInfo & {
|
|
|
68
68
|
*/
|
|
69
69
|
serverName?: string;
|
|
70
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* An incremental fragment of a tool call's args JSON, emitted while the
|
|
73
|
+
* model is still composing the call. Concatenate successive
|
|
74
|
+
* `tool-call-delta` events for the same `toolCallId` to build the complete
|
|
75
|
+
* args JSON that lands on the terminal {@link ToolCallEvent}.
|
|
76
|
+
*
|
|
77
|
+
* Useful for UIs that want to render "live-typing" tool args as the model
|
|
78
|
+
* generates them, mirroring `text-delta` for chat responses. Consumers that
|
|
79
|
+
* don't need streaming-args UX can ignore this event and continue to read
|
|
80
|
+
* the parsed `args` object on the terminal {@link ToolCallEvent}, which is
|
|
81
|
+
* unchanged.
|
|
82
|
+
*
|
|
83
|
+
* Both harnesses produce the underlying signal natively (Claude:
|
|
84
|
+
* `input_json_delta`; Mastra: `tool-call-delta` chunk). The terminal
|
|
85
|
+
* {@link ToolCallEvent} still fires once the full args object has been
|
|
86
|
+
* parsed — `tool-call-delta` is purely additive UX enrichment.
|
|
87
|
+
*/
|
|
88
|
+
export type ToolCallDeltaEvent = {
|
|
89
|
+
type: 'tool-call-delta';
|
|
90
|
+
/** The id of the in-progress tool call. Matches the eventual {@link ToolCallEvent.toolCallId}. */
|
|
91
|
+
toolCallId: string;
|
|
92
|
+
/**
|
|
93
|
+
* The name of the tool. Optional because Mastra's `tool-call-delta`
|
|
94
|
+
* chunk types `toolName` as optional and may omit it; Claude always
|
|
95
|
+
* populates it from the per-`toolCallId` state captured on the prior
|
|
96
|
+
* `content_block_start`. Consumers SHOULD NOT branch on `toolName`
|
|
97
|
+
* presence — when absent, resolve it from the prior
|
|
98
|
+
* {@link ToolCallEvent} on the same `toolCallId`.
|
|
99
|
+
*/
|
|
100
|
+
toolName?: string;
|
|
101
|
+
/** The args-JSON text fragment. */
|
|
102
|
+
argsTextDelta: string;
|
|
103
|
+
};
|
|
71
104
|
/**
|
|
72
105
|
* The harness is requesting approval before executing a tool call.
|
|
73
106
|
* The stream suspends until the consumer calls `approveToolCall()` or
|
|
@@ -119,6 +152,39 @@ export type ToolResultEvent = ToolResultInfo & {
|
|
|
119
152
|
*/
|
|
120
153
|
serverName?: string;
|
|
121
154
|
};
|
|
155
|
+
/**
|
|
156
|
+
* An incremental tool-progress signal emitted while a long-running tool call is
|
|
157
|
+
* still in flight. Distinct from {@link ToolResultEvent} which marks terminal
|
|
158
|
+
* completion: a single tool call may emit zero or more `tool-progress` events,
|
|
159
|
+
* followed by exactly one `tool-result`.
|
|
160
|
+
*
|
|
161
|
+
* Useful for UIs that want to render a "tool is working" indicator for
|
|
162
|
+
* long-running tools (build, test, deploy, large search, sub-agent tasks)
|
|
163
|
+
* where the user benefits from seeing intermediate activity before the terminal
|
|
164
|
+
* `tool-result` lands.
|
|
165
|
+
*
|
|
166
|
+
* The event itself is the load-bearing "tool is still working" signal —
|
|
167
|
+
* `output` and `parentToolCallId` are best-effort enrichment that depends on
|
|
168
|
+
* the tool. Consumer code SHOULD NOT branch on which optional fields are
|
|
169
|
+
* present.
|
|
170
|
+
*/
|
|
171
|
+
export type ToolProgressEvent = {
|
|
172
|
+
type: 'tool-progress';
|
|
173
|
+
/** The id of the in-progress tool call. Matches a prior {@link ToolCallEvent.toolCallId}. */
|
|
174
|
+
toolCallId: string;
|
|
175
|
+
/** The name of the tool. Matches a prior {@link ToolCallEvent.toolName}. */
|
|
176
|
+
toolName: string;
|
|
177
|
+
/**
|
|
178
|
+
* The tool's incremental output, if the tool produces one. Shape is
|
|
179
|
+
* tool-defined.
|
|
180
|
+
*/
|
|
181
|
+
output?: unknown;
|
|
182
|
+
/**
|
|
183
|
+
* The parent tool-call id when this progress is for a nested tool call
|
|
184
|
+
* (e.g. a sub-agent invoking another tool), if applicable.
|
|
185
|
+
*/
|
|
186
|
+
parentToolCallId?: string;
|
|
187
|
+
};
|
|
122
188
|
/**
|
|
123
189
|
* Marks the beginning of a new LLM invocation within a multi-step agentic loop.
|
|
124
190
|
*
|
package/dist/types/usage.d.ts
CHANGED
|
@@ -9,7 +9,25 @@ export type UsageMetadata = {
|
|
|
9
9
|
outputTokens?: number;
|
|
10
10
|
/** Sum of input and output tokens. */
|
|
11
11
|
totalTokens?: number;
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Tokens consumed by the model's reasoning/thinking phase.
|
|
14
|
+
*
|
|
15
|
+
* Provider-reported and possibly approximate: Mastra surfaces an
|
|
16
|
+
* actual billed count from the gateway, while Claude surfaces a live
|
|
17
|
+
* estimate digested from `SDKThinkingTokensMessage.estimated_tokens`
|
|
18
|
+
* (the SDK's own JSDoc flags this as "approximate progress for
|
|
19
|
+
* spinners/pills, not the authoritative billed output_tokens").
|
|
20
|
+
* Consumers reading this field see the best-available reasoning-token
|
|
21
|
+
* count regardless of harness — both surfaces populate the same slot
|
|
22
|
+
* with the same shape and semantics on `step-finish.usage` and
|
|
23
|
+
* `finish.usage`.
|
|
24
|
+
*
|
|
25
|
+
* Intentionally excluded from {@link ContextUsage.usedFraction} —
|
|
26
|
+
* reasoning tokens don't survive into the next turn's prompt, so they
|
|
27
|
+
* don't belong in a "should I compact?" denominator. See
|
|
28
|
+
* `packages/sfdx-agent-sdk/ARCHITECTURE.md` →
|
|
29
|
+
* "Context-window usage tracking" for the rationale.
|
|
30
|
+
*/
|
|
13
31
|
reasoningTokens?: number;
|
|
14
32
|
/** Input tokens served from provider cache (reduces cost). */
|
|
15
33
|
cachedInputTokens?: number;
|
|
@@ -74,6 +92,13 @@ export type ContextUsage = {
|
|
|
74
92
|
* cache-hit paths. Mastra is unaffected because it does not populate the
|
|
75
93
|
* cache fields, so the sum collapses to `inputTokens` alone.
|
|
76
94
|
*
|
|
95
|
+
* `reasoningTokens` is intentionally NOT in the sum: this fraction
|
|
96
|
+
* answers "should I compact for the next turn?" and reasoning blocks
|
|
97
|
+
* are stripped from the transcript before the next turn's prompt is
|
|
98
|
+
* sent, so they don't occupy next-turn context. See
|
|
99
|
+
* `packages/sfdx-agent-sdk/ARCHITECTURE.md` →
|
|
100
|
+
* "Context-window usage tracking" for the rationale.
|
|
101
|
+
*
|
|
77
102
|
* `undefined` when ALL three input-bearing fields are missing on the
|
|
78
103
|
* latest reading (pre-first-turn, post-`clearHistory()`, or when a
|
|
79
104
|
* harness emits a reading without any input-side counts). Consumers
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/sfdx-agent-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@eslint/js": "^10.0.1",
|
|
48
|
-
"@salesforce/sfdx-agent-harness-claude": "0.
|
|
49
|
-
"@salesforce/sfdx-agent-harness-mastra": "0.
|
|
48
|
+
"@salesforce/sfdx-agent-harness-claude": "0.16.0",
|
|
49
|
+
"@salesforce/sfdx-agent-harness-mastra": "0.19.0",
|
|
50
50
|
"@types/node": "^22.19.20",
|
|
51
51
|
"@vitest/coverage-istanbul": "^4.1.8",
|
|
52
52
|
"@vitest/eslint-plugin": "^1.6.19",
|