@salesforce/sfdx-agent-sdk 0.39.0 → 0.40.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 +5 -0
- package/README.md +48 -24
- package/dist/harness/agent-harness.d.ts +8 -5
- package/dist/index.d.ts +2 -2
- package/dist/internal/telemetry-router.js +6 -4
- package/dist/types/telemetry-events.d.ts +15 -1
- package/dist/types/wire-communication-event.d.ts +57 -3
- package/dist/wire-communication-file-writer.js +28 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
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.40.0] - 2026-08-03
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
- **agent-sdk,harness-mastra,harness-claude,harness-openai**: observability gaps — mcp-tool-call-completed, llm-retry, responseText/TTFT @W-23528008@ ([#717](https://github.com/forcedotcom/agentic-dx/pull/717))
|
|
10
|
+
|
|
6
11
|
## [0.39.0] - 2026-07-30
|
|
7
12
|
|
|
8
13
|
### Features
|
package/README.md
CHANGED
|
@@ -1192,6 +1192,9 @@ const unsubscribe = manager.onWireCommunication((event) => {
|
|
|
1192
1192
|
case 'llm-response':
|
|
1193
1193
|
// matching response (or terminal failure)
|
|
1194
1194
|
break;
|
|
1195
|
+
case 'mcp-tool-call-completed':
|
|
1196
|
+
// completed MCP tool call; redact args/result before persisting
|
|
1197
|
+
break;
|
|
1195
1198
|
case 'wire-monitoring-not-supported':
|
|
1196
1199
|
// harness can't emit per-call events for this stream;
|
|
1197
1200
|
// event.message points at the workaround (typically a debug log file path)
|
|
@@ -1200,17 +1203,28 @@ const unsubscribe = manager.onWireCommunication((event) => {
|
|
|
1200
1203
|
});
|
|
1201
1204
|
```
|
|
1202
1205
|
|
|
1203
|
-
**Discriminated union —
|
|
1206
|
+
**Discriminated union — four variants keyed on `type`:**
|
|
1207
|
+
|
|
1208
|
+
| `type` | Fields |
|
|
1209
|
+
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1210
|
+
| `llm-request` | `timestamp`, `url`, `method`, `model`, `correlationId?`, `xClientTraceId?`, `body?` |
|
|
1211
|
+
| `llm-response` | `timestamp`, `model`, `correlationId?`, `status`, `xClientTraceId?`, `totalDurationMs?`, `timeToFirstTokenMs?`, `usage?` (`inputTokens?`, `outputTokens?`, `totalTokens?`, `reasoningTokens?`), `responseText?`, `error?` ({ `message` }) |
|
|
1212
|
+
| `mcp-tool-call-completed` | `timestamp`, `serverName`, `toolName`, `bareToolName`, `args`, `result`, `durationMs?` |
|
|
1213
|
+
| `wire-monitoring-not-supported` | `timestamp`, `harnessId`, `message` (free-form text — typically explains why direct wire monitoring isn't available and points at a fallback log file the harness wrote) |
|
|
1214
|
+
|
|
1215
|
+
`correlationId` is the harness-guaranteed pairing key stamped identically on a matching `llm-request` / `llm-response`
|
|
1216
|
+
pair. Pair requests and responses on it, **not** on their positions in the event stream. `xClientTraceId` is an optional
|
|
1217
|
+
header value for cross-checking, not the pairing contract.
|
|
1204
1218
|
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1219
|
+
`mcp-tool-call-completed` is a **DEBUG-ONLY** diagnostic event: it is opt-in and subscriber-gated like the rest of this
|
|
1220
|
+
channel, is never a `TelemetryEvent`, and is never shipped through telemetry or other externally-shipped event surfaces.
|
|
1221
|
+
Its `args` and `result` are captured verbatim and MAY contain PII. Apply your own redaction / scrubbing before
|
|
1222
|
+
persisting or sharing. `durationMs` is harness-specific: Claude reports RPC latency, while Mastra and OpenAI report an
|
|
1223
|
+
adapter-observed window. Do not compare `durationMs` across harnesses.
|
|
1210
1224
|
|
|
1211
|
-
**Privacy contract.**
|
|
1212
|
-
**not** flowed to the structured-log channel by
|
|
1213
|
-
|
|
1225
|
+
**Privacy contract.** LLM events MAY contain user prompts and model output in `body` / `responseText`; MCP completion
|
|
1226
|
+
events MAY contain PII in verbatim `args` / `result`. These events are **not** flowed to the structured-log channel by
|
|
1227
|
+
default — consumers opt in to wire-level visibility explicitly via `onWireCommunication`. Note that request HTTP headers
|
|
1214
1228
|
(e.g. `Authorization`) are **not** captured on the events; the harness's fetch wrapper sees them but doesn't forward
|
|
1215
1229
|
them onto the channel.
|
|
1216
1230
|
|
|
@@ -1221,17 +1235,26 @@ harness in particular skips writing the subprocess's debug log when nobody is li
|
|
|
1221
1235
|
`chat()` you want to inspect: subscriptions added mid-stream miss the in-flight subprocess on Claude (the listener count
|
|
1222
1236
|
is captured at stream-start).
|
|
1223
1237
|
|
|
1224
|
-
|
|
1238
|
+
#### Cross-harness coverage
|
|
1239
|
+
|
|
1240
|
+
This table is the canonical compatibility reference for the SDK's public observability and wire-diagnostic surfaces.
|
|
1241
|
+
Feature availability is intentionally asymmetric where a runtime does not expose a faithful observation seam.
|
|
1242
|
+
|
|
1243
|
+
| Feature | Claude | Mastra | OpenAI |
|
|
1244
|
+
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1245
|
+
| Structured `llm-request` / `llm-response` wire events | **Not implemented.** The opaque native subprocess provides no capturable, parseable per-call format. When subscribed, emits `wire-monitoring-not-supported` and writes a subprocess debug-log file. | **Delivered.** Emits one request/response pair per outbound LLM HTTP call. | **Delivered.** Emits one request/response pair per outbound LLM HTTP call. |
|
|
1246
|
+
| Pairing structured LLM events | N/A — no structured LLM wire events. | **Delivered.** Matching request/response events share a harness-generated `correlationId`; pair on it, never event position or `xClientTraceId` alone. | **Delivered.** Matching request/response events share a harness-generated `correlationId`; pair on it, never event position or `xClientTraceId` alone. |
|
|
1247
|
+
| `responseText` and `timeToFirstTokenMs` on `llm-response` | N/A — no structured LLM wire events. | **Delivered.** A streaming-body tee produces one HTTP-body-terminal response event with best-effort response text and first-token latency. | **Delivered.** A streaming-body tee produces one HTTP-body-terminal response event with best-effort response text and first-token latency. |
|
|
1248
|
+
| `mcp-tool-call-completed` debug event | **Delivered.** External-MCP bridge observation with true RPC latency in `durationMs`. | **Delivered.** Adapter/coordinator-observed `durationMs`, which can include a model round-trip. | **Delivered.** Adapter/coordinator-observed `durationMs`, which can include a model round-trip. |
|
|
1249
|
+
| `llm-retry` telemetry | **Delivered.** Emits numeric-only, PII-free data when the Claude Agent SDK reports an actual `api_retry`. | **Documented limitation:** does not emit; the stateless fetch layer has no retry loop or attempt counter. A `429` / `retry-after` response is a failed attempt, not a retry. | **Documented limitation:** does not emit; the stateless fetch layer has no retry loop or attempt counter. A `429` / `retry-after` response is a failed attempt, not a retry. |
|
|
1250
|
+
|
|
1251
|
+
Claude's debug log is written to `${storageRoot}/claude-debug-logs/${agentId}__${threadId}.log` when at least one
|
|
1252
|
+
consumer is subscribed at stream-start (one file per thread; turns of the same conversation accumulate, separated by
|
|
1253
|
+
greppable `# Turn started: <ISO>` banners). It is left in place; the consumer is responsible for retention and cleanup.
|
|
1225
1254
|
|
|
1226
|
-
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
- **Claude harness**: cannot emit per-call events because the Claude Agent SDK runs the model client in a subprocess
|
|
1230
|
-
with no programmatic HTTP-interception seam. Instead, when at least one consumer is subscribed at stream-start, the
|
|
1231
|
-
harness writes the subprocess's debug log to `${storageRoot}/claude-debug-logs/${agentId}__${threadId}.log` (one file
|
|
1232
|
-
per thread; turns of the same conversation accumulate, separated by greppable `# Turn started: <ISO>` banners) and
|
|
1233
|
-
emits a single `wire-monitoring-not-supported` event whose `message` field embeds the file path. The file is left in
|
|
1234
|
-
place; the consumer is responsible for retention and cleanup.
|
|
1255
|
+
Mastra and OpenAI callers can identify any upstream-retried requests only as distinct `llm-request` / `llm-response`
|
|
1256
|
+
pairs, using `correlationId`, `xClientTraceId`, and timestamps. Neither harness synthesizes a partial `llm-retry` event
|
|
1257
|
+
from an HTTP response header.
|
|
1235
1258
|
|
|
1236
1259
|
#### `WireCommunicationFileWriter`
|
|
1237
1260
|
|
|
@@ -1253,11 +1276,11 @@ const writer = new WireCommunicationFileWriter(manager, {
|
|
|
1253
1276
|
writer.detach();
|
|
1254
1277
|
```
|
|
1255
1278
|
|
|
1256
|
-
The output file is plain Markdown with one `### <iso-timestamp> [llm-request]`, `[llm-response]`,
|
|
1257
|
-
`[wire-monitoring-not-supported]` header per event followed by the populated fields.
|
|
1258
|
-
when set — sparse responses do not pad the file with empty `**Field**: N/A` lines. On
|
|
1259
|
-
`wire-monitoring-not-supported` block links to the per-thread debug log file where raw wire
|
|
1260
|
-
directly.
|
|
1279
|
+
The output file is plain Markdown with one `### <iso-timestamp> [llm-request]`, `[llm-response]`,
|
|
1280
|
+
`[mcp-tool-call-completed]`, or `[wire-monitoring-not-supported]` header per event followed by the populated fields.
|
|
1281
|
+
Optional fields are emitted only when set — sparse responses do not pad the file with empty `**Field**: N/A` lines. On
|
|
1282
|
+
the Claude harness, the `wire-monitoring-not-supported` block links to the per-thread debug log file where raw wire
|
|
1283
|
+
detail can be inspected directly.
|
|
1261
1284
|
|
|
1262
1285
|
The same privacy contract applies: the resulting file may contain prompts, tool arguments, and model output. Treat it as
|
|
1263
1286
|
sensitive and apply your own retention / scrubbing rules before sharing.
|
|
@@ -1491,6 +1514,7 @@ All variants share `{ type: <discriminant>, timestamp: Date }` plus the fields b
|
|
|
1491
1514
|
| `mcp-server-discovery-completed` | `agentId`, `serverName`, `toolCount`, `durationMs` |
|
|
1492
1515
|
| `mcp-server-discovery-failed` | `agentId`, `serverName`, `durationMs`, `error`, `errorDetail?` ([`McpServerErrorDetail`](#mcpservererrordetail)) |
|
|
1493
1516
|
| `mcp-server-status-changed` | `agentId`, `serverName`, `previousStatus`, `nextStatus`, `error?` |
|
|
1517
|
+
| `llm-retry` | `attempt`, `maxRetries`, `retryDelayMs`, `errorStatus?` — Claude-only; numeric-only and PII-free |
|
|
1494
1518
|
|
|
1495
1519
|
Each variant is also exported as a named type so consumers can write narrowed handlers: `AgentCreatedEvent`,
|
|
1496
1520
|
`AgentDestroyedEvent`, `SessionCreatedEvent`, `SessionDestroyedEvent`, `ChatStreamStartedEvent`,
|
|
@@ -100,11 +100,14 @@ export interface AgentHarness {
|
|
|
100
100
|
*
|
|
101
101
|
* Fidelity may differ between harnesses: the Mastra (in-process) path
|
|
102
102
|
* emits one `request` + one `response` event per outbound HTTP call,
|
|
103
|
-
* with the full body and status visible. The Claude
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* at the
|
|
107
|
-
*
|
|
103
|
+
* with the full body and status visible. The Claude path runs the model
|
|
104
|
+
* client in an opaque native subprocess with no capturable, parseable
|
|
105
|
+
* per-call debug format, so it emits `wire-monitoring-not-supported`
|
|
106
|
+
* pointing at the subprocess debug-log file rather than structured
|
|
107
|
+
* `llm-request` / `llm-response` events. Structured parsing is deferred
|
|
108
|
+
* pending a stable, capturable debug format. Consumers subscribe once at
|
|
109
|
+
* the `AgentManager` layer; the SDK forwards events upward through the
|
|
110
|
+
* bus hierarchy the same way it does for telemetry and log records.
|
|
108
111
|
*/
|
|
109
112
|
onWireCommunication(callback: WireCommunicationEventCallback): Unsubscribe;
|
|
110
113
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -19,11 +19,11 @@ export { type ChatSession, type ChatOptions } from './chat-session.js';
|
|
|
19
19
|
export type { AgentConnectivityResolver, ResolvedConnectivity } from './agent-connectivity-resolver.js';
|
|
20
20
|
export { ApiKeyConnectivityResolver, type ApiKeyConnectivityResolverConfig } from './api-key-connectivity-resolver.js';
|
|
21
21
|
export type { ModelConnectivityInfo, ProviderHint } from './types/model-connectivity-info.js';
|
|
22
|
-
export type { LlmRequestEvent, LlmResponseEvent, WireCommunicationEvent, WireCommunicationEventCallback, WireMonitoringNotSupportedEvent, } from './types/wire-communication-event.js';
|
|
22
|
+
export type { LlmRequestEvent, LlmResponseEvent, McpToolCallCompletedEvent, WireCommunicationEvent, WireCommunicationEventCallback, WireMonitoringNotSupportedEvent, } from './types/wire-communication-event.js';
|
|
23
23
|
export { WireCommunicationFileWriter, type WireCommunicationEmitter, type WireCommunicationFileWriterOptions, } from './wire-communication-file-writer.js';
|
|
24
24
|
export type { AgentHarness, HarnessFactory, WithAgentConfig, ConfigOf } from './harness/index.js';
|
|
25
25
|
export { AgentSDKError, AgentSDKErrorType } from './errors.js';
|
|
26
|
-
export type { AgentCreatedEvent, AgentDestroyedEvent, ChatStreamCompletedEvent, ChatStreamErrorEvent, ChatStreamStartedEvent, ChatStreamTrigger, McpServerDiscoveryCompletedEvent, McpServerDiscoveryFailedEvent, McpServerDiscoveryStartedEvent, McpServerStatusChangedEvent, SessionCreatedEvent, SessionDestroyedEvent, TelemetryEvent, TelemetryEventCallback, ToolApprovalPolicyResolvedEvent, ToolApprovalRequestedEvent, ToolApprovalResolvedEvent, ToolExecutionCompletedEvent, ToolExecutionStartedEvent, } from './types/telemetry-events.js';
|
|
26
|
+
export type { AgentCreatedEvent, AgentDestroyedEvent, ChatStreamCompletedEvent, ChatStreamErrorEvent, ChatStreamStartedEvent, ChatStreamTrigger, LlmRetryEvent, McpServerDiscoveryCompletedEvent, McpServerDiscoveryFailedEvent, McpServerDiscoveryStartedEvent, McpServerStatusChangedEvent, SessionCreatedEvent, SessionDestroyedEvent, TelemetryEvent, TelemetryEventCallback, ToolApprovalPolicyResolvedEvent, ToolApprovalRequestedEvent, ToolApprovalResolvedEvent, ToolExecutionCompletedEvent, ToolExecutionStartedEvent, } from './types/telemetry-events.js';
|
|
27
27
|
export type { LogLevel, LogRecord, Unsubscribe } from '@salesforce/agentic-common';
|
|
28
28
|
export { resolveMcpServerHeaders } from './mcp-auth.js';
|
|
29
29
|
export type { OrgConnection, OrgConnectionFactory } from '@salesforce/agentic-common';
|
|
@@ -91,10 +91,12 @@ export class TelemetryRouter {
|
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
agentSlice
|
|
97
|
-
|
|
94
|
+
if ('agentId' in event) {
|
|
95
|
+
const agentSlice = this.agentSlices.get(event.agentId);
|
|
96
|
+
if (agentSlice) {
|
|
97
|
+
agentSlice.telemetry.emit(event);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
98
100
|
}
|
|
99
101
|
this.unroutedSlice.telemetry.emit(event);
|
|
100
102
|
}
|
|
@@ -178,7 +178,21 @@ export type McpServerStatusChangedEvent = Base<'mcp-server-status-changed'> & {
|
|
|
178
178
|
/** Populated when `nextStatus === 'error'`. */
|
|
179
179
|
error?: string;
|
|
180
180
|
};
|
|
181
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Emitted for each retry attempt initiated by the Claude harness.
|
|
183
|
+
*
|
|
184
|
+
* This event is Claude-only by contract: Mastra and OpenAI expose no observable
|
|
185
|
+
* attempt counter. The type has no harness discriminant, but only the Claude
|
|
186
|
+
* harness emits it. Its required retry fields intentionally remain complete so
|
|
187
|
+
* consumers never receive a partial retry record.
|
|
188
|
+
*/
|
|
189
|
+
export type LlmRetryEvent = Base<'llm-retry'> & {
|
|
190
|
+
attempt: number;
|
|
191
|
+
maxRetries: number;
|
|
192
|
+
retryDelayMs: number;
|
|
193
|
+
errorStatus?: number;
|
|
194
|
+
};
|
|
195
|
+
export type TelemetryEvent = AgentCreatedEvent | AgentDestroyedEvent | SessionCreatedEvent | SessionDestroyedEvent | ChatStreamStartedEvent | ChatStreamCompletedEvent | ChatStreamErrorEvent | ToolExecutionStartedEvent | ToolExecutionCompletedEvent | ToolApprovalRequestedEvent | ToolApprovalResolvedEvent | ToolApprovalPolicyResolvedEvent | McpServerDiscoveryStartedEvent | McpServerDiscoveryCompletedEvent | McpServerDiscoveryFailedEvent | McpServerStatusChangedEvent | LlmRetryEvent;
|
|
182
196
|
export type TelemetryEventCallback = (event: TelemetryEvent) => void;
|
|
183
197
|
export type TelemetryBus = EventBus<TelemetryEvent>;
|
|
184
198
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { UsageMetadata } from './usage.js';
|
|
2
2
|
/**
|
|
3
3
|
* Wire-level communication events, emitted by the harness layer so consumers
|
|
4
|
-
* see the same shape regardless of harness. The union has
|
|
4
|
+
* see the same shape regardless of harness. The union has four members today:
|
|
5
5
|
* - `LlmRequestEvent` (`type: 'llm-request'`) — one outbound HTTP request to
|
|
6
6
|
* the LLM provider.
|
|
7
7
|
* - `LlmResponseEvent` (`type: 'llm-response'`) — the matching inbound
|
|
@@ -12,6 +12,8 @@ import type { UsageMetadata } from './usage.js';
|
|
|
12
12
|
* subprocess owns the HTTP traffic). The event carries a free-form
|
|
13
13
|
* `message` explaining the situation and (when applicable) where the
|
|
14
14
|
* underlying data was written instead.
|
|
15
|
+
* - `McpToolCallCompletedEvent` (`type: 'mcp-tool-call-completed'`) — an
|
|
16
|
+
* opt-in debug record of an MCP tool call's completed input and output.
|
|
15
17
|
*
|
|
16
18
|
* **Privacy contract.** Wire-communication events may contain user prompts,
|
|
17
19
|
* tool arguments, model output, and other PII. They are opt-in (subscribed
|
|
@@ -55,6 +57,18 @@ export type LlmRequestEvent = {
|
|
|
55
57
|
method: string;
|
|
56
58
|
/** Native model id sent on the wire (per `ModelConnectivityInfo.nativeModelId`). */
|
|
57
59
|
model: string;
|
|
60
|
+
/**
|
|
61
|
+
* Harness-generated per-fetch pairing key. Stamped identically on the matching
|
|
62
|
+
* `LlmResponseEvent`; consumers MUST use it as the reliable pairing key rather
|
|
63
|
+
* than positional event ordering. Producers obtain it from the injected
|
|
64
|
+
* `UniqueIDGenerator` in `@salesforce/agentic-common`, never `randomUUID()`.
|
|
65
|
+
*/
|
|
66
|
+
correlationId?: string;
|
|
67
|
+
/**
|
|
68
|
+
* `x-client-trace-id` header value attached to this request. Consumers pair on
|
|
69
|
+
* `correlationId` (the harness-guaranteed key) and may cross-check this value.
|
|
70
|
+
*/
|
|
71
|
+
xClientTraceId?: string;
|
|
58
72
|
/** Request body. Best-effort: partial / absent on harnesses that can't observe it. */
|
|
59
73
|
body?: Record<string, unknown>;
|
|
60
74
|
};
|
|
@@ -65,6 +79,13 @@ export type LlmResponseEvent = {
|
|
|
65
79
|
timestamp: Date;
|
|
66
80
|
/** Native model id from the matching request. */
|
|
67
81
|
model: string;
|
|
82
|
+
/**
|
|
83
|
+
* Harness-generated per-fetch pairing key. Stamped identically on the matching
|
|
84
|
+
* `LlmRequestEvent`; consumers MUST use it as the reliable pairing key rather
|
|
85
|
+
* than positional event ordering. Producers obtain it from the injected
|
|
86
|
+
* `UniqueIDGenerator` in `@salesforce/agentic-common`, never `randomUUID()`.
|
|
87
|
+
*/
|
|
88
|
+
correlationId?: string;
|
|
68
89
|
/** HTTP status code; `0` for harness-internal terminal failures with no transport response. */
|
|
69
90
|
status: number;
|
|
70
91
|
/** Error captured from a transport / parse failure, if any. */
|
|
@@ -85,9 +106,42 @@ export type LlmResponseEvent = {
|
|
|
85
106
|
totalDurationMs?: number;
|
|
86
107
|
/** Best-effort extracted response text (may be omitted by the harness). */
|
|
87
108
|
responseText?: string;
|
|
88
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* `x-client-trace-id` header value attached to the matching request. Consumers
|
|
111
|
+
* pair on `correlationId` (the harness-guaranteed key) and may cross-check this value.
|
|
112
|
+
*/
|
|
89
113
|
xClientTraceId?: string;
|
|
90
114
|
};
|
|
115
|
+
/**
|
|
116
|
+
* Debug-only, opt-in, subscriber-gated record of a completed MCP tool call.
|
|
117
|
+
* `args` and `result` are captured verbatim and MAY contain PII, so consumers
|
|
118
|
+
* must redact before persisting or sharing. This is not a telemetry event and
|
|
119
|
+
* MUST NOT be added to `TelemetryEvent` or any externally-shipped surface.
|
|
120
|
+
*
|
|
121
|
+
* `toolName` is the harness-namespaced display name and `bareToolName` is the
|
|
122
|
+
* un-namespaced leaf. `durationMs` semantics differ by harness: the Claude
|
|
123
|
+
* bridge reports true RPC latency, while Mastra and OpenAI report an
|
|
124
|
+
* adapter/coordinator-observed window that may include a model round-trip.
|
|
125
|
+
* Consumers MUST NOT compare durations across harnesses.
|
|
126
|
+
*/
|
|
127
|
+
export type McpToolCallCompletedEvent = {
|
|
128
|
+
/** Direction discriminator. */
|
|
129
|
+
type: 'mcp-tool-call-completed';
|
|
130
|
+
/** Wall-clock timestamp when the tool call completed. */
|
|
131
|
+
timestamp: Date;
|
|
132
|
+
/** Logical MCP server name from the configured server catalog. */
|
|
133
|
+
serverName: string;
|
|
134
|
+
/** Harness-namespaced display name presented to the model. */
|
|
135
|
+
toolName: string;
|
|
136
|
+
/** Un-namespaced tool-name leaf. */
|
|
137
|
+
bareToolName: string;
|
|
138
|
+
/** Verbatim arguments passed to the tool. May contain PII. */
|
|
139
|
+
args: Record<string, unknown>;
|
|
140
|
+
/** Verbatim result returned by the tool. May contain PII. */
|
|
141
|
+
result: unknown;
|
|
142
|
+
/** Harness-dependent observed duration; do not compare across harnesses. */
|
|
143
|
+
durationMs?: number;
|
|
144
|
+
};
|
|
91
145
|
/**
|
|
92
146
|
* Emitted by harnesses whose runtime doesn't expose a programmatic seam for
|
|
93
147
|
* per-call wire monitoring. The event signals to consumers that
|
|
@@ -120,5 +174,5 @@ export type WireMonitoringNotSupportedEvent = {
|
|
|
120
174
|
* Union over every wire-communication event the harness layer can emit.
|
|
121
175
|
* Discriminate on the `type` field.
|
|
122
176
|
*/
|
|
123
|
-
export type WireCommunicationEvent = LlmRequestEvent | LlmResponseEvent | WireMonitoringNotSupportedEvent;
|
|
177
|
+
export type WireCommunicationEvent = LlmRequestEvent | LlmResponseEvent | McpToolCallCompletedEvent | WireMonitoringNotSupportedEvent;
|
|
124
178
|
export type WireCommunicationEventCallback = (event: WireCommunicationEvent) => void;
|
|
@@ -68,6 +68,8 @@ function formatAsMarkdown(event) {
|
|
|
68
68
|
return formatRequestMarkdown(event);
|
|
69
69
|
case 'llm-response':
|
|
70
70
|
return formatResponseMarkdown(event);
|
|
71
|
+
case 'mcp-tool-call-completed':
|
|
72
|
+
return formatMcpToolCallCompletedMarkdown(event);
|
|
71
73
|
case 'wire-monitoring-not-supported':
|
|
72
74
|
return formatWireMonitoringNotSupportedMarkdown(event);
|
|
73
75
|
}
|
|
@@ -135,6 +137,32 @@ function formatResponseMarkdown(event) {
|
|
|
135
137
|
}
|
|
136
138
|
return lines.join('\n');
|
|
137
139
|
}
|
|
140
|
+
function formatMcpToolCallCompletedMarkdown(event) {
|
|
141
|
+
const lines = [
|
|
142
|
+
`### ${event.timestamp.toISOString()} [${event.type}]`,
|
|
143
|
+
``,
|
|
144
|
+
`**Server**: ${event.serverName}`,
|
|
145
|
+
``,
|
|
146
|
+
`**Tool**: ${event.toolName}`,
|
|
147
|
+
``,
|
|
148
|
+
`**Bare tool**: ${event.bareToolName}`,
|
|
149
|
+
``,
|
|
150
|
+
`**Args**:`,
|
|
151
|
+
'```json',
|
|
152
|
+
JSON.stringify(event.args, null, 2),
|
|
153
|
+
'```',
|
|
154
|
+
``,
|
|
155
|
+
`**Result**:`,
|
|
156
|
+
'```json',
|
|
157
|
+
JSON.stringify(event.result, null, 2),
|
|
158
|
+
'```',
|
|
159
|
+
``,
|
|
160
|
+
];
|
|
161
|
+
if (event.durationMs !== undefined) {
|
|
162
|
+
lines.push(`**Duration**: ${event.durationMs}`, ``);
|
|
163
|
+
}
|
|
164
|
+
return lines.join('\n');
|
|
165
|
+
}
|
|
138
166
|
function formatWireMonitoringNotSupportedMarkdown(event) {
|
|
139
167
|
const dateTime = event.timestamp.toISOString();
|
|
140
168
|
return [`### ${dateTime} [${event.type}]`, ``, `**Harness**: ${event.harnessId}`, ``, event.message, ``, ``].join('\n');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/sfdx-agent-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0",
|
|
4
4
|
"description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/js": "^10.0.1",
|
|
50
|
-
"@salesforce/sfdx-agent-harness-claude": "0.
|
|
51
|
-
"@salesforce/sfdx-agent-harness-mastra": "0.
|
|
52
|
-
"@salesforce/sfdx-agent-harness-openai": "0.
|
|
50
|
+
"@salesforce/sfdx-agent-harness-claude": "0.36.0",
|
|
51
|
+
"@salesforce/sfdx-agent-harness-mastra": "0.39.0",
|
|
52
|
+
"@salesforce/sfdx-agent-harness-openai": "0.5.0",
|
|
53
53
|
"@types/node": "^22.20.0",
|
|
54
54
|
"@vitest/coverage-istanbul": "^4.1.10",
|
|
55
55
|
"@vitest/eslint-plugin": "^1.6.22",
|