@salesforce/sfdx-agent-sdk 0.78.0 → 0.80.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 +2 -1
- package/dist/chat-session.d.ts +64 -1
- package/dist/chat-session.js +69 -1
- package/dist/harness/agent-harness.d.ts +6 -4
- package/dist/harness/public.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/models/model.d.ts +5 -2
- package/dist/models/model.js +5 -2
- package/dist/types/events.d.ts +34 -4
- package/dist/types/index.d.ts +1 -1
- package/dist/types/usage.d.ts +5 -1
- package/package.json +4 -4
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.80.0] - 2026-09-14
|
|
7
|
+
|
|
8
|
+
### Fixes
|
|
9
|
+
- **harness-mastra**: stamp Anthropic cache_control in the Mastra pass-through @W-24130072@ ([#811](https://github.com/forcedotcom/agentic-dx/pull/811))
|
|
10
|
+
|
|
11
|
+
## [0.79.0] - 2026-09-14
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
- add ChatSession.cancelTurn() with abort-persistence barrier @W-23559264@ ([#810](https://github.com/forcedotcom/agentic-dx/pull/810))
|
|
15
|
+
|
|
6
16
|
## [0.78.0] - 2026-09-09
|
|
7
17
|
|
|
8
18
|
_No changes — released alongside dependent packages._
|
package/README.md
CHANGED
|
@@ -170,6 +170,7 @@ A single conversation thread.
|
|
|
170
170
|
| `submitToolResult` | `(toolResult: ToolResultInfo) => Promise<void>` | Return a consumer-executed tool result. Control message on the existing turn — post-resume events flow on the same stream. |
|
|
171
171
|
| `approveToolCall` | `(toolCallId: string, options?: { remember?: boolean }) => Promise<void>` | Approve a pending tool call. `{ remember: true }` ("Allow always") appends an `allow` rule to `AgentConfig.toolPolicies` and persists it before settling. Control message on the existing turn. |
|
|
172
172
|
| `declineToolCall` | `(toolCallId: string, options?: DeclineToolCallOptions) => Promise<void>` | Decline a pending tool call. `{ remember: true }` ("Deny always") appends a `deny` rule and persists it before settling. `{ reason: { kind: 'organization-policy', modelMessage? } }` delivers a terminal policy explanation to the model and error result without persisting a remembered user rule. Control message on the existing turn. |
|
|
173
|
+
| `cancelTurn` | `() => Promise<void>` | Stop the in-flight turn (including one suspended awaiting a tool approval) and resolve only **after** the harness abort teardown AND its transcript-persistence flush complete. Fires an SDK-owned per-turn signal composed with any caller `abortSignal`, so it works with or without one. The turn's `eventStream` ends with exactly one `FinishEvent(finishReason: 'cancelled')` preceded by an `ErrorEvent` whose canonical `code` is `'cancelled'` (no harness-specific `'abort'`/`'aborted'`). Because the returned promise is a persistence barrier, a subsequent `getMessageHistory()` is deterministic with **no polling**. Idempotent / safe no-op with no turn in flight; owns no wall-clock timeout (wrap it if you need one). |
|
|
173
174
|
| `getMessageHistory` | `() => Promise<Message[]>` | Retrieve all messages in chronological order. |
|
|
174
175
|
| `clearHistory` | `() => Promise<void>` | Delete all messages. |
|
|
175
176
|
| `getContextUsage` | `() => ContextUsage` | Snapshot of how much of the model's context window the most recent turn used. |
|
|
@@ -764,7 +765,7 @@ type ContextUsage = {
|
|
|
764
765
|
usedFraction: number | undefined;
|
|
765
766
|
};
|
|
766
767
|
|
|
767
|
-
type FinishReason = 'stop' | 'length' | 'tool-calls' | 'content-filter' | 'error' | 'other';
|
|
768
|
+
type FinishReason = 'stop' | 'length' | 'tool-calls' | 'content-filter' | 'error' | 'max-steps' | 'cancelled' | 'other';
|
|
768
769
|
```
|
|
769
770
|
|
|
770
771
|
**Tracking context-window utilization.** `ChatSession.getContextUsage()` always returns a populated `ContextUsage` —
|
package/dist/chat-session.d.ts
CHANGED
|
@@ -87,7 +87,10 @@ export type ChatSessionParentBuses = {
|
|
|
87
87
|
* cleared, but the underlying harness turn keeps running until it settles, so the harness rejects
|
|
88
88
|
* the new turn until then. **To release a turn deterministically, abort it (via the turn's
|
|
89
89
|
* `abortSignal`) rather than merely abandoning its stream** — abort settles the coordinator, so the
|
|
90
|
-
* next `chat()` is admitted cleanly.
|
|
90
|
+
* next `chat()` is admitted cleanly. {@link ChatSession.cancelTurn} is the first-class verb for this:
|
|
91
|
+
* it fires an SDK-owned per-turn signal (composed with any caller `abortSignal`) and resolves only
|
|
92
|
+
* after teardown + transcript-persistence flush, so a subsequent `getMessageHistory()` is
|
|
93
|
+
* deterministic without polling.
|
|
91
94
|
*/
|
|
92
95
|
export interface ChatSession {
|
|
93
96
|
/** Returns the unique session/thread identifier. */
|
|
@@ -182,6 +185,35 @@ export interface ChatSession {
|
|
|
182
185
|
* terminal error result. Policy reasons require `remember: false` and are never persisted.
|
|
183
186
|
*/
|
|
184
187
|
declineToolCall(toolCallId: string, options?: DeclineToolCallOptions): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Stop the turn currently in flight — including one suspended awaiting a
|
|
190
|
+
* tool approval — and resolve only after the harness has fully settled the
|
|
191
|
+
* abort teardown, INCLUDING flushing whatever transcript persistence that
|
|
192
|
+
* harness performs. That persistence barrier is the point of the returned
|
|
193
|
+
* promise: once it resolves, {@link getMessageHistory} deterministically
|
|
194
|
+
* reflects the settled transcript with NO polling.
|
|
195
|
+
*
|
|
196
|
+
* Cancellation fires an SDK-owned per-turn `AbortController` that composes
|
|
197
|
+
* with any caller-supplied `options.abortSignal` — so it works whether or
|
|
198
|
+
* not the caller passed a signal, and a caller aborting their own signal has
|
|
199
|
+
* the identical effect. The turn's `eventStream` ends with exactly one
|
|
200
|
+
* terminal `FinishEvent(finishReason: 'cancelled')`, preceded by an
|
|
201
|
+
* `ErrorEvent` whose canonical `code` is `'cancelled'` on every harness — no
|
|
202
|
+
* cancelled turn surfaces `finishReason: 'error'`, and callers never branch
|
|
203
|
+
* on harness-specific `'abort'` / `'aborted'`.
|
|
204
|
+
*
|
|
205
|
+
* Idempotent and a safe no-op: calling it with no turn in flight, or a
|
|
206
|
+
* second time, does nothing harmful. It owns no wall-clock timeout — a
|
|
207
|
+
* consumer that needs one wraps the call itself.
|
|
208
|
+
*
|
|
209
|
+
* The cancelled turn's terminal `ErrorEvent` + `FinishEvent('cancelled')`
|
|
210
|
+
* still flow on the turn's own `eventStream`. As with any turn, drain (or
|
|
211
|
+
* abandon via `break` / `.return()`) that stream so the session's
|
|
212
|
+
* one-turn-at-a-time guard clears before the next {@link chat} — a
|
|
213
|
+
* `subscribe()`-only consumer that never iterates the returned stream can
|
|
214
|
+
* otherwise see `SESSION_BUSY` on the next `chat()` until it does.
|
|
215
|
+
*/
|
|
216
|
+
cancelTurn(): Promise<void>;
|
|
185
217
|
/**
|
|
186
218
|
* Retrieve message history for this session.
|
|
187
219
|
*
|
|
@@ -371,6 +403,25 @@ export declare class DefaultChatSession implements ChatSession {
|
|
|
371
403
|
* mutate this flag. See the interface-level "Failure handling" notes.
|
|
372
404
|
*/
|
|
373
405
|
private turnActive;
|
|
406
|
+
/**
|
|
407
|
+
* SDK-owned abort controller for the turn started by the most recent
|
|
408
|
+
* {@link chat}. Its signal is composed (via `AbortSignal.any`) with any
|
|
409
|
+
* caller-supplied `options.abortSignal` and handed to `harness.stream()`, so
|
|
410
|
+
* {@link cancelTurn} can stop the turn whether or not the caller passed a
|
|
411
|
+
* signal, and a caller-fired signal reaches the harness the same way.
|
|
412
|
+
* `undefined` before the first `chat()`. Aborting a controller whose turn has
|
|
413
|
+
* already settled is a harmless no-op, which is what makes `cancelTurn`
|
|
414
|
+
* idempotent without extra bookkeeping.
|
|
415
|
+
*/
|
|
416
|
+
private turnAbortController;
|
|
417
|
+
/**
|
|
418
|
+
* The current turn's settle barrier, taken from the harness's
|
|
419
|
+
* {@link HarnessStreamResult.settled}. {@link cancelTurn} awaits it so the
|
|
420
|
+
* returned promise resolves only after the harness abort teardown AND its
|
|
421
|
+
* transcript-persistence flush have completed. `undefined` when no turn has
|
|
422
|
+
* run, when the harness didn't supply one, or on a pre-stream failure.
|
|
423
|
+
*/
|
|
424
|
+
private turnSettled;
|
|
374
425
|
/**
|
|
375
426
|
* @param harness - The agent harness managing thread and message lifecycle.
|
|
376
427
|
* @param agentId - ID of the agent this session belongs to.
|
|
@@ -394,6 +445,18 @@ export declare class DefaultChatSession implements ChatSession {
|
|
|
394
445
|
* before returning a stream result.
|
|
395
446
|
*/
|
|
396
447
|
chat(message: string | MessagePart[], options?: ChatOptions): Promise<ChatStreamResult>;
|
|
448
|
+
/**
|
|
449
|
+
* @requirements
|
|
450
|
+
* - MUST fire `this.turnAbortController` so the SDK-owned per-turn signal (composed with any
|
|
451
|
+
* caller-supplied `options.abortSignal`) reaches the harness and tears the turn down.
|
|
452
|
+
* - MUST await `this.turnSettled` (the harness settle barrier) so it resolves only after the
|
|
453
|
+
* abort teardown AND its transcript-persistence flush have completed.
|
|
454
|
+
* - MUST be a safe no-op when no turn has ever run (`turnAbortController` undefined) and be
|
|
455
|
+
* idempotent on repeat calls / an already-settled turn (aborting a settled controller and
|
|
456
|
+
* awaiting an already-resolved barrier are both no-ops).
|
|
457
|
+
* - MUST NOT own a wall-clock timeout.
|
|
458
|
+
*/
|
|
459
|
+
cancelTurn(): Promise<void>;
|
|
397
460
|
/**
|
|
398
461
|
* @requirements
|
|
399
462
|
* - MUST delegate to `this.harness.submitToolResult()`, passing `this.agentId` and `this.threadId`.
|
package/dist/chat-session.js
CHANGED
|
@@ -6,6 +6,16 @@ import { backfillCreatedAt, EventBus, LogBus, RealClock, UUIDGenerator, } from '
|
|
|
6
6
|
import { resolveToolDeclineModelMessage } from './harness/tool-decline.js';
|
|
7
7
|
import { AgentSDKError, AgentSDKErrorType } from './errors.js';
|
|
8
8
|
import { createTelemetryBus, } from './types/telemetry-events.js';
|
|
9
|
+
/**
|
|
10
|
+
* Composes the SDK-owned per-turn abort signal with the caller's (if any) into
|
|
11
|
+
* one signal handed to `harness.stream()`, so firing EITHER aborts the turn.
|
|
12
|
+
* With no caller signal, the SDK signal is passed through unchanged. Uses
|
|
13
|
+
* `AbortSignal.any`, which yields an already-aborted signal when either input is
|
|
14
|
+
* already aborted — preserving the harness's abort-at-entry handling.
|
|
15
|
+
*/
|
|
16
|
+
function composeAbortSignals(own, caller) {
|
|
17
|
+
return caller === undefined ? own : AbortSignal.any([own, caller]);
|
|
18
|
+
}
|
|
9
19
|
/**
|
|
10
20
|
* Default implementation of {@link ChatSession} that delegates all operations
|
|
11
21
|
* to an {@link AgentHarness}. The session holds its agent ID and thread ID
|
|
@@ -98,6 +108,25 @@ export class DefaultChatSession {
|
|
|
98
108
|
* mutate this flag. See the interface-level "Failure handling" notes.
|
|
99
109
|
*/
|
|
100
110
|
turnActive = false;
|
|
111
|
+
/**
|
|
112
|
+
* SDK-owned abort controller for the turn started by the most recent
|
|
113
|
+
* {@link chat}. Its signal is composed (via `AbortSignal.any`) with any
|
|
114
|
+
* caller-supplied `options.abortSignal` and handed to `harness.stream()`, so
|
|
115
|
+
* {@link cancelTurn} can stop the turn whether or not the caller passed a
|
|
116
|
+
* signal, and a caller-fired signal reaches the harness the same way.
|
|
117
|
+
* `undefined` before the first `chat()`. Aborting a controller whose turn has
|
|
118
|
+
* already settled is a harmless no-op, which is what makes `cancelTurn`
|
|
119
|
+
* idempotent without extra bookkeeping.
|
|
120
|
+
*/
|
|
121
|
+
turnAbortController = undefined;
|
|
122
|
+
/**
|
|
123
|
+
* The current turn's settle barrier, taken from the harness's
|
|
124
|
+
* {@link HarnessStreamResult.settled}. {@link cancelTurn} awaits it so the
|
|
125
|
+
* returned promise resolves only after the harness abort teardown AND its
|
|
126
|
+
* transcript-persistence flush have completed. `undefined` when no turn has
|
|
127
|
+
* run, when the harness didn't supply one, or on a pre-stream failure.
|
|
128
|
+
*/
|
|
129
|
+
turnSettled = undefined;
|
|
101
130
|
/**
|
|
102
131
|
* @param harness - The agent harness managing thread and message lifecycle.
|
|
103
132
|
* @param agentId - ID of the agent this session belongs to.
|
|
@@ -144,9 +173,24 @@ export class DefaultChatSession {
|
|
|
144
173
|
// cannot slip past the guard.
|
|
145
174
|
this.assertNotBusy();
|
|
146
175
|
this.turnActive = true;
|
|
176
|
+
// SDK-owned per-turn signal composed with the caller's (if any) so
|
|
177
|
+
// cancelTurn() can stop this turn regardless of whether the caller passed
|
|
178
|
+
// one. Set before the `await` so a cancelTurn() racing this call still
|
|
179
|
+
// aborts the right controller.
|
|
180
|
+
const turnAbort = new AbortController();
|
|
181
|
+
this.turnAbortController = turnAbort;
|
|
182
|
+
const abortSignal = composeAbortSignals(turnAbort.signal, options?.abortSignal);
|
|
147
183
|
const startedAt = this.emitChatStreamStarted('chat');
|
|
184
|
+
const streamPromise = this.harness.stream(this.agentId, this.threadId, message, { ...options, abortSignal });
|
|
185
|
+
// Derive the settle barrier synchronously from the stream promise — before
|
|
186
|
+
// the `await` — so a `cancelTurn()` that races this `chat()` still awaits the
|
|
187
|
+
// real teardown + persistence flush rather than an `undefined` (an immediate
|
|
188
|
+
// resolve that would skip the barrier). On a pre-stream rejection there is no
|
|
189
|
+
// turn to settle, so the barrier resolves; the rejection itself surfaces on
|
|
190
|
+
// the awaited `streamPromise` below.
|
|
191
|
+
this.turnSettled = streamPromise.then((result) => result.settled, () => undefined);
|
|
148
192
|
try {
|
|
149
|
-
const result = await
|
|
193
|
+
const result = await streamPromise;
|
|
150
194
|
return {
|
|
151
195
|
textStream: result.textStream,
|
|
152
196
|
eventStream: this.wrapEventStream(result.eventStream, startedAt),
|
|
@@ -160,6 +204,30 @@ export class DefaultChatSession {
|
|
|
160
204
|
throw err;
|
|
161
205
|
}
|
|
162
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* @requirements
|
|
209
|
+
* - MUST fire `this.turnAbortController` so the SDK-owned per-turn signal (composed with any
|
|
210
|
+
* caller-supplied `options.abortSignal`) reaches the harness and tears the turn down.
|
|
211
|
+
* - MUST await `this.turnSettled` (the harness settle barrier) so it resolves only after the
|
|
212
|
+
* abort teardown AND its transcript-persistence flush have completed.
|
|
213
|
+
* - MUST be a safe no-op when no turn has ever run (`turnAbortController` undefined) and be
|
|
214
|
+
* idempotent on repeat calls / an already-settled turn (aborting a settled controller and
|
|
215
|
+
* awaiting an already-resolved barrier are both no-ops).
|
|
216
|
+
* - MUST NOT own a wall-clock timeout.
|
|
217
|
+
*/
|
|
218
|
+
async cancelTurn() {
|
|
219
|
+
this.assertNotDisposed();
|
|
220
|
+
const controller = this.turnAbortController;
|
|
221
|
+
if (controller === undefined) {
|
|
222
|
+
// No turn has ever started on this session — nothing to cancel.
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
controller.abort();
|
|
226
|
+
// Resolve only after the harness has settled teardown and flushed
|
|
227
|
+
// persistence. `settled` never rejects; absence (a harness that didn't
|
|
228
|
+
// supply one) degrades to abort-without-barrier.
|
|
229
|
+
await this.turnSettled;
|
|
230
|
+
}
|
|
163
231
|
/**
|
|
164
232
|
* @requirements
|
|
165
233
|
* - MUST delegate to `this.harness.submitToolResult()`, passing `this.agentId` and `this.threadId`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LogRecord, Unsubscribe } from '@salesforce/agentic-common';
|
|
2
2
|
import type { McpServerInfo, McpAuthProviders } from '../mcp-config.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { HarnessStreamResult } from '../types/events.js';
|
|
4
4
|
import type { Message, MessagePart } from '../types/messages.js';
|
|
5
5
|
import type { TelemetryEventCallback } from '../types/telemetry-events.js';
|
|
6
6
|
import type { ToolDeclineReason, ToolResultInfo } from '../types/tools.js';
|
|
@@ -367,8 +367,10 @@ export interface AgentHarness {
|
|
|
367
367
|
compactThread(agentId: string, threadId: string): Promise<string>;
|
|
368
368
|
/**
|
|
369
369
|
* Stream a response from the agent for the given message.
|
|
370
|
-
* Returns a {@link
|
|
371
|
-
*
|
|
370
|
+
* Returns a {@link HarnessStreamResult} — a {@link ChatStreamResult} (text-only
|
|
371
|
+
* or full-event consumption) plus an optional internal `settled` promise the
|
|
372
|
+
* SDK uses as the {@link ChatSession.cancelTurn} persistence barrier. The
|
|
373
|
+
* `settled` field is off the consumer surface; see {@link HarnessStreamResult}.
|
|
372
374
|
*
|
|
373
375
|
* @param agentId - ID of the agent to invoke.
|
|
374
376
|
* @param threadId - ID of the conversation thread.
|
|
@@ -377,7 +379,7 @@ export interface AgentHarness {
|
|
|
377
379
|
* passing `tool-call` / `tool-result` parts is a programmer error and harnesses reject it.
|
|
378
380
|
* @param options - Per-call streaming options.
|
|
379
381
|
*/
|
|
380
|
-
stream(agentId: string, threadId: string, message: string | MessagePart[], options?: StreamOptions): Promise<
|
|
382
|
+
stream(agentId: string, threadId: string, message: string | MessagePart[], options?: StreamOptions): Promise<HarnessStreamResult>;
|
|
381
383
|
/**
|
|
382
384
|
* Feed the result of a **consumer-executed (client-side) tool** back into the
|
|
383
385
|
* conversation. Implements the consumer-facing
|
package/dist/harness/public.d.ts
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
* is "harness-only" vs. "consumer-AND-harness", not "harness vs. consumer."
|
|
43
43
|
*/
|
|
44
44
|
export type { AgentHarness, HarnessFactory, WithAgentConfig, ConfigOf } from './index.js';
|
|
45
|
+
export type { HarnessStreamResult } from '../types/events.js';
|
|
45
46
|
export type { AgentHooks } from '../types/redaction.js';
|
|
46
47
|
export { SUPPORTED_PROTOCOL_VERSIONS } from './agent-harness.js';
|
|
47
48
|
export { mcpServerConfigEqual } from '../mcp-config.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { Message, MessagePart, MessageRole, ImagePart, FilePart } from './types/messages.js';
|
|
2
2
|
export type { JsonValue, SessionContext } from './types/session-context.js';
|
|
3
|
-
export type { ChatEvent, StartEvent, TextDeltaEvent, ReasoningDeltaEvent, ToolCallEvent, ToolCallDeltaEvent, ToolApprovalRequestEvent, ToolResultEvent, ToolProgressEvent, StepStartEvent, StepFinishEvent, ErrorEvent, FinishEvent, ChatStreamResult, } from './types/events.js';
|
|
3
|
+
export type { ChatEvent, StartEvent, TextDeltaEvent, ReasoningDeltaEvent, ToolCallEvent, ToolCallDeltaEvent, ToolApprovalRequestEvent, ToolResultEvent, ToolProgressEvent, StepStartEvent, StepFinishEvent, ErrorEvent, FinishEvent, ChatStreamResult, HarnessStreamResult, } from './types/events.js';
|
|
4
4
|
export type { DeclineToolCallOptions, Decision, ToolDeclineReason, ToolDefinition, ToolCallInfo, ToolMatcher, ToolPolicyRule, ToolResultInfo, } from './types/tools.js';
|
|
5
5
|
export { BUILT_IN_TOOL_POLICIES, SKILL_BRIDGE_SERVER_ID, definePolicy, matcherMatches, resolveToolApprovalPolicy, } from './policy-resolver.js';
|
|
6
6
|
export type { ResolverResult, ResolverTiers, ToolInvocation } from './policy-resolver.js';
|
package/dist/models/model.d.ts
CHANGED
|
@@ -58,8 +58,11 @@ export declare enum ModelName {
|
|
|
58
58
|
* - **Context-window tracking.** `ChatSession.getContextUsage()` reads
|
|
59
59
|
* `contextWindow` to compute "% of context used".
|
|
60
60
|
* - **Prompt-cache routing.** Anthropic-Claude-family models declare
|
|
61
|
-
* `supportsPromptCache: true`;
|
|
62
|
-
*
|
|
61
|
+
* `supportsPromptCache: true`; GPT models declare `false`. Read by the
|
|
62
|
+
* Mastra Anthropic pass-through (`buildAnthropicLanguageModel` /
|
|
63
|
+
* `buildAnthropicDirectLanguageModel`) to gate `cache_control` stamping on
|
|
64
|
+
* Bedrock-Anthropic and direct-Anthropic requests — caching is a Claude-only,
|
|
65
|
+
* explicit opt-in; GPT's prefix cache is automatic and needs no stamp.
|
|
63
66
|
*
|
|
64
67
|
* In-tree subclasses pin `name` to a {@link ModelName} enum member;
|
|
65
68
|
* instances built via {@link createClaudeModel} (the consumer-facing
|
package/dist/models/model.js
CHANGED
|
@@ -46,8 +46,11 @@ export var ModelName;
|
|
|
46
46
|
* - **Context-window tracking.** `ChatSession.getContextUsage()` reads
|
|
47
47
|
* `contextWindow` to compute "% of context used".
|
|
48
48
|
* - **Prompt-cache routing.** Anthropic-Claude-family models declare
|
|
49
|
-
* `supportsPromptCache: true`;
|
|
50
|
-
*
|
|
49
|
+
* `supportsPromptCache: true`; GPT models declare `false`. Read by the
|
|
50
|
+
* Mastra Anthropic pass-through (`buildAnthropicLanguageModel` /
|
|
51
|
+
* `buildAnthropicDirectLanguageModel`) to gate `cache_control` stamping on
|
|
52
|
+
* Bedrock-Anthropic and direct-Anthropic requests — caching is a Claude-only,
|
|
53
|
+
* explicit opt-in; GPT's prefix cache is automatic and needs no stamp.
|
|
51
54
|
*
|
|
52
55
|
* In-tree subclasses pin `name` to a {@link ModelName} enum member;
|
|
53
56
|
* instances built via {@link createClaudeModel} (the consumer-facing
|
package/dist/types/events.d.ts
CHANGED
|
@@ -258,10 +258,14 @@ export type ErrorEvent = {
|
|
|
258
258
|
/**
|
|
259
259
|
* Stable, machine-readable classification of the error, when the harness
|
|
260
260
|
* recognized it — consumers branch on this instead of string-matching
|
|
261
|
-
* `error.message`.
|
|
262
|
-
* `'context-window-exceeded'` (the
|
|
263
|
-
* overflow signal
|
|
264
|
-
*
|
|
261
|
+
* `error.message`. Two cross-harness values are emitted uniformly by every
|
|
262
|
+
* harness: `'context-window-exceeded'` (the
|
|
263
|
+
* {@link AgentSDKErrorType.CONTEXT_LENGTH_EXCEEDED} overflow signal) and
|
|
264
|
+
* `'cancelled'` (the canonical code paired with a terminal
|
|
265
|
+
* `FinishEvent(finishReason: 'cancelled')` when a turn is stopped by
|
|
266
|
+
* {@link ChatSession.cancelTurn} or a caller-fired `abortSignal` — callers
|
|
267
|
+
* no longer branch on harness-specific `'abort'` / `'aborted'`). Other values
|
|
268
|
+
* are harness-specific (e.g. `'network-error'`, `'tool-approval-timeout'`).
|
|
265
269
|
* `undefined` when the harness could not classify the error.
|
|
266
270
|
*/
|
|
267
271
|
code?: string;
|
|
@@ -291,3 +295,29 @@ export type ChatStreamResult = {
|
|
|
291
295
|
*/
|
|
292
296
|
textStream: AsyncGenerator<string>;
|
|
293
297
|
};
|
|
298
|
+
/**
|
|
299
|
+
* The result a harness's {@link AgentHarness.stream} returns to the SDK — a
|
|
300
|
+
* {@link ChatStreamResult} plus an optional internal `settled` promise. A
|
|
301
|
+
* harness-contract type (reachable from both `@salesforce/sfdx-agent-sdk` and
|
|
302
|
+
* `/harness`, like {@link AgentHarness}), NOT the consumer-facing result:
|
|
303
|
+
* `ChatSession.chat()` returns a plain {@link ChatStreamResult} that never
|
|
304
|
+
* carries `settled`. The SDK reads `settled` off the harness result and consumes
|
|
305
|
+
* it internally (the {@link ChatSession.cancelTurn} barrier); consumer code never
|
|
306
|
+
* sees the field.
|
|
307
|
+
*/
|
|
308
|
+
export type HarnessStreamResult = ChatStreamResult & {
|
|
309
|
+
/**
|
|
310
|
+
* Resolves once the turn has fully settled — its single per-turn sink has
|
|
311
|
+
* ended (natural `finish` or an abort/teardown) AND any persistence flush
|
|
312
|
+
* that settling entails has completed (the harness's transcript save is on
|
|
313
|
+
* disk). This is the barrier {@link ChatSession.cancelTurn} awaits so a
|
|
314
|
+
* subsequent `getMessages()` is deterministic with no polling.
|
|
315
|
+
*
|
|
316
|
+
* Optional so a harness that hasn't wired it still satisfies the contract:
|
|
317
|
+
* the SDK's `cancelTurn()` still aborts the turn, it just can't await the
|
|
318
|
+
* persistence barrier. All production harnesses populate it. It never
|
|
319
|
+
* rejects — a failed teardown still resolves it (the turn is over either
|
|
320
|
+
* way).
|
|
321
|
+
*/
|
|
322
|
+
settled?: Promise<void>;
|
|
323
|
+
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { Message, MessageRole, MessagePart, TextPart, ReasoningPart, ToolCallPart, ToolResultPart, } from './messages.js';
|
|
2
|
-
export type { ChatEvent, StartEvent, TextDeltaEvent, ReasoningDeltaEvent, ToolCallEvent, ToolApprovalRequestEvent, ToolResultEvent, StepStartEvent, StepFinishEvent, ErrorEvent, FinishEvent, ChatStreamResult, } from './events.js';
|
|
2
|
+
export type { ChatEvent, StartEvent, TextDeltaEvent, ReasoningDeltaEvent, ToolCallEvent, ToolApprovalRequestEvent, ToolResultEvent, StepStartEvent, StepFinishEvent, ErrorEvent, FinishEvent, ChatStreamResult, HarnessStreamResult, } from './events.js';
|
|
3
3
|
export type { ToolDefinition, ToolCallInfo, ToolResultInfo } from './tools.js';
|
|
4
4
|
export type { UsageMetadata, FinishReason } from './usage.js';
|
|
5
5
|
export type { ModelConnectivityInfo, ProviderHint } from './model-connectivity-info.js';
|
package/dist/types/usage.d.ts
CHANGED
|
@@ -172,6 +172,10 @@ export type ContextUsage = {
|
|
|
172
172
|
* - `max-steps` — The agentic loop was terminated because it reached the maximum step count.
|
|
173
173
|
* The model wanted to continue (e.g., it was requesting more tool calls) but the loop was forcibly stopped.
|
|
174
174
|
* This is distinct from `tool-calls` which in a step-finish context indicates normal mid-loop progress.
|
|
175
|
+
* - `cancelled` — The turn was stopped by an explicit cancellation — {@link ChatSession.cancelTurn} or the
|
|
176
|
+
* caller aborting the turn's `abortSignal`. Distinct from `error`: a cancel is an intentional stop, not a
|
|
177
|
+
* failure. The terminal `FinishEvent` for a cancelled turn always carries this reason (never `error`), and the
|
|
178
|
+
* accompanying `ErrorEvent.code` is the canonical `'cancelled'` on every harness.
|
|
175
179
|
* - `other` — Provider-specific reason that doesn't map to the standard values.
|
|
176
180
|
*/
|
|
177
|
-
export type FinishReason = 'stop' | 'length' | 'tool-calls' | 'content-filter' | 'error' | 'max-steps' | 'other';
|
|
181
|
+
export type FinishReason = 'stop' | 'length' | 'tool-calls' | 'content-filter' | 'error' | 'max-steps' | 'cancelled' | 'other';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/sfdx-agent-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.80.0",
|
|
4
4
|
"description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@eslint/js": "^10.0.1",
|
|
51
|
-
"@salesforce/sfdx-agent-harness-claude": "0.
|
|
52
|
-
"@salesforce/sfdx-agent-harness-mastra": "0.
|
|
53
|
-
"@salesforce/sfdx-agent-harness-openai": "0.
|
|
51
|
+
"@salesforce/sfdx-agent-harness-claude": "0.76.0",
|
|
52
|
+
"@salesforce/sfdx-agent-harness-mastra": "0.79.0",
|
|
53
|
+
"@salesforce/sfdx-agent-harness-openai": "0.45.0",
|
|
54
54
|
"@types/node": "^22.20.1",
|
|
55
55
|
"@vitest/coverage-istanbul": "^4.1.11",
|
|
56
56
|
"@vitest/eslint-plugin": "^1.6.27",
|