@salesforce/sfdx-agent-sdk 0.27.0 → 0.29.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-sdk` are documented in this file.
4
4
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
+ ## [0.29.0] - 2026-07-02
7
+
8
+ ### Features
9
+ - **agent-sdk**: support GPT5/5.1/5.2/5.4 geo-aware + Opus 4.8 @W-23256760@ ([#635](https://github.com/forcedotcom/agentic-dx/pull/635))
10
+
11
+ ## [0.28.0] - 2026-06-30
12
+
13
+ ### Features
14
+ - **sdk,harness-mastra,harness-claude**: add bareToolName to MCP tool events for remember matcher @W-23090030 ([#634](https://github.com/forcedotcom/agentic-dx/pull/634))
15
+
16
+ ### Chores
17
+ - **deps-dev**: bump the eslint group across 1 directory with 2 updates ([#629](https://github.com/forcedotcom/agentic-dx/pull/629))
18
+ - **deps-dev**: bump prettier from 3.8.4 to 3.9.0 in the dev-dependencies group ([#628](https://github.com/forcedotcom/agentic-dx/pull/628))
19
+
6
20
  ## [0.27.0] - 2026-06-29
7
21
 
8
22
  ### Fixes
package/README.md CHANGED
@@ -196,10 +196,10 @@ Discriminated union (`event.type`) of streaming events:
196
196
  | `start` | — | Stream has begun. |
197
197
  | `text-delta` | `text` | Incremental response text. |
198
198
  | `reasoning-delta` | `text` | Chain-of-thought fragment. |
199
- | `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` | `toolCallId`, `toolName`, `args`, `annotations?`, `serverName?`, `bareToolName?` | 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. `toolName` is the harness-namespaced display name; `bareToolName` is the un-namespaced leaf paired with `serverName` (set for MCP tools only) — use the `(serverName, bareToolName)` pair, never string-split `toolName`, for cross-harness identity. |
200
200
  | `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). |
201
- | `tool-approval-request` | `toolCall: ToolCallInfo`, `annotations?`, `serverName?` | Engine requests approval before executing a tool. Same `annotations` / `serverName` semantics as `tool-call`. |
202
- | `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`. |
201
+ | `tool-approval-request` | `toolCall: ToolCallInfo`, `annotations?`, `serverName?`, `bareToolName?` | Engine requests approval before executing a tool. Same `annotations` / `serverName` / `bareToolName` semantics as `tool-call`. `bareToolName` is the field the SDK reads to build the `remember` policy matcher (see [Tool Approval](#tool-approval)). |
202
+ | `tool-result` | `toolCallId`, `toolName`, `result`, `isError?`, `error?`, `annotations?`, `serverName?`, `bareToolName?` | 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` / `bareToolName` semantics as `tool-call`. |
203
203
  | `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). |
204
204
  | `step-start` | `stepIndex` | New LLM invocation step began. |
205
205
  | `step-finish` | `stepIndex`, `finishReason`, `usage?` | Step completed with per-step token usage. |
@@ -320,9 +320,12 @@ const config: AgentConfig = {
320
320
  | Deny always | `declineToolCall(id, { remember: true })` | Append a `deny` `remember` rule, persist, then settle. |
321
321
 
322
322
  With `{ remember: true }` the SDK derives the matcher from the pending `tool-approval-request`'s
323
- `(toolName, serverName?)`, appends a `source: 'remember'` rule to `AgentConfig.toolPolicies`, and persists it via
324
- `updateAgentConfig` **before** settling so the decision survives a restart and a persistence failure surfaces as the
325
- settle's rejection. A `remember` settle for a `toolCallId` with no pending approval throws `TOOL_CALL_NOT_FOUND`.
323
+ `(serverName?, bareToolName ?? toolName)` `bareToolName` is the harness-supplied un-namespaced leaf for MCP tools
324
+ (building the matcher from the namespaced display `toolName` would never match on replay); built-in tools have no
325
+ `bareToolName` and their `toolName` is already bare. It appends a `source: 'remember'` rule to
326
+ `AgentConfig.toolPolicies` and persists it via `updateAgentConfig` **before** settling — so the decision survives a
327
+ restart and a persistence failure surfaces as the settle's rejection. A `remember` settle for a `toolCallId` with no
328
+ pending approval throws `TOOL_CALL_NOT_FOUND`.
326
329
 
327
330
  #### `MCPConfiguration`
328
331
 
@@ -75,10 +75,13 @@ function pickProviderHintForGatewayModel(model) {
75
75
  if (name.startsWith('llmgateway__BedrockAnthropic') || name.startsWith('llmgateway__Anthropic')) {
76
76
  return 'bedrock-anthropic';
77
77
  }
78
- if (name.startsWith('llmgateway__OpenAI')) {
78
+ if (name.startsWith('llmgateway__OpenAI') || name.startsWith('sfdc_ai__Default')) {
79
+ // `sfdc_ai__Default*` is the geo-aware OpenAI route (W-23256760): the
80
+ // gateway selects the regional deployment, but the wire shape is still
81
+ // OpenAI Responses, so it resolves to the same providerHint.
79
82
  return 'openai-responses';
80
83
  }
81
- throw new Error(`Cannot infer providerHint for model "${name}". Salesforce gateway models must start with "llmgateway__BedrockAnthropic*" or "llmgateway__OpenAI*".`);
84
+ throw new Error(`Cannot infer providerHint for model "${name}". Salesforce gateway models must start with "llmgateway__BedrockAnthropic*", "llmgateway__OpenAI*", or "sfdc_ai__Default*".`);
82
85
  }
83
86
  /**
84
87
  * Returns the Salesforce LLM Gateway base URL for the given environment.
@@ -512,8 +512,15 @@ export class DefaultChatSession {
512
512
  // rule. Drained on settle, and on every terminal `finish` (see
513
513
  // `wrapEventStream`) so a stale entry can't be remembered after the
514
514
  // turn that requested it has ended.
515
+ //
516
+ // For an MCP tool, `event.toolCall.toolName` is the harness-namespaced
517
+ // DISPLAY name (`${server}_${tool}` / `mcp__${server}__${tool}`), which
518
+ // the SDK's `mcp` matcher would never match on replay. The harness
519
+ // supplies the un-namespaced leaf on `event.bareToolName` (paired with
520
+ // `serverName`); prefer it. Built-in / consumer tools leave
521
+ // `bareToolName` undefined and their `toolName` is already bare.
515
522
  this.pendingApprovalsByToolCallId.set(event.toolCall.toolCallId, {
516
- toolName: event.toolCall.toolName,
523
+ toolName: event.bareToolName ?? event.toolCall.toolName,
517
524
  ...(event.serverName ? { serverName: event.serverName } : {}),
518
525
  });
519
526
  this.telemetryBus.emit({
@@ -0,0 +1,11 @@
1
+ import { Model, ModelName } from './model.js';
2
+ import { type SupportedFileFormat } from './types.js';
3
+ export declare class ClaudeOpus48 extends Model {
4
+ readonly name: ModelName;
5
+ readonly displayId: string;
6
+ readonly maxInputTokens: number;
7
+ readonly maxOutputTokens: number;
8
+ readonly contextWindow: number;
9
+ readonly supportsPromptCache: boolean;
10
+ readonly supportedFormats: readonly SupportedFileFormat[];
11
+ }
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc. All rights reserved.
3
+ * See LICENSE.txt for license terms.
4
+ */
5
+ import { Model, ModelName } from './model.js';
6
+ import { MimeType } from './types.js';
7
+ export class ClaudeOpus48 extends Model {
8
+ name = ModelName.CLAUDE_OPUS_4_8;
9
+ displayId = 'Claude Opus 4.8';
10
+ // Caps mirror Opus 4.7 pending the gateway registry entry for
11
+ // BedrockAnthropicClaude48Opus.yml (W-23256760).
12
+ maxInputTokens = 1_000_000;
13
+ maxOutputTokens = 128_000;
14
+ contextWindow = 1_000_000;
15
+ supportsPromptCache = true;
16
+ supportedFormats = [
17
+ { name: 'png', mimeType: MimeType.Png, maxBytesPerFile: 3.75 * 1024 * 1024 },
18
+ { name: 'jpeg', mimeType: MimeType.Jpeg, maxBytesPerFile: 3.75 * 1024 * 1024 },
19
+ { name: 'pdf', mimeType: MimeType.Pdf, maxBytesPerFile: 4.5 * 1024 * 1024, maxFilesPerRequest: 5 },
20
+ ];
21
+ }
22
+ //# sourceMappingURL=claude-opus-4-8.js.map
@@ -0,0 +1,15 @@
1
+ import { Model, ModelName } from './model.js';
2
+ import { type SupportedFileFormat } from './types.js';
3
+ /**
4
+ * GPT-5.1 on the geo-aware `sfdc_ai__Default*` gateway route — routes to the
5
+ * OpenAI Responses wire shape (Mastra harness). See W-23256760.
6
+ */
7
+ export declare class GPT51Geo extends Model {
8
+ readonly name: ModelName;
9
+ readonly displayId: string;
10
+ readonly maxInputTokens: number;
11
+ readonly maxOutputTokens: number;
12
+ readonly contextWindow: number;
13
+ readonly supportsPromptCache: boolean;
14
+ readonly supportedFormats: readonly SupportedFileFormat[];
15
+ }
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc. All rights reserved.
3
+ * See LICENSE.txt for license terms.
4
+ */
5
+ import { Model, ModelName } from './model.js';
6
+ import { MimeType } from './types.js';
7
+ /**
8
+ * GPT-5.1 on the geo-aware `sfdc_ai__Default*` gateway route — routes to the
9
+ * OpenAI Responses wire shape (Mastra harness). See W-23256760.
10
+ */
11
+ export class GPT51Geo extends Model {
12
+ name = ModelName.GPT_5_1_GEO;
13
+ displayId = 'GPT-5.1 (geo-aware)';
14
+ // source of truth: https://git.soma.salesforce.com/a360/file-metadata/blob/master/fm-model-config/src/main/resources/ai/file-metadata/model/openai/llmgateway/OpenAIGPT51.yml
15
+ maxInputTokens = 272000;
16
+ maxOutputTokens = 128000;
17
+ contextWindow = 272000;
18
+ supportsPromptCache = false;
19
+ supportedFormats = [
20
+ { name: 'png', mimeType: MimeType.Png },
21
+ { name: 'jpeg', mimeType: MimeType.Jpeg },
22
+ { name: 'pdf', mimeType: MimeType.Pdf },
23
+ ];
24
+ }
25
+ //# sourceMappingURL=gpt-5-1-geo.js.map
@@ -0,0 +1,15 @@
1
+ import { Model, ModelName } from './model.js';
2
+ import { type SupportedFileFormat } from './types.js';
3
+ /**
4
+ * GPT-5.2 on the geo-aware `sfdc_ai__Default*` gateway route — routes to the
5
+ * OpenAI Responses wire shape (Mastra harness). See W-23256760.
6
+ */
7
+ export declare class GPT52Geo extends Model {
8
+ readonly name: ModelName;
9
+ readonly displayId: string;
10
+ readonly maxInputTokens: number;
11
+ readonly maxOutputTokens: number;
12
+ readonly contextWindow: number;
13
+ readonly supportsPromptCache: boolean;
14
+ readonly supportedFormats: readonly SupportedFileFormat[];
15
+ }
@@ -0,0 +1,24 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc. All rights reserved.
3
+ * See LICENSE.txt for license terms.
4
+ */
5
+ import { Model, ModelName } from './model.js';
6
+ import { MimeType } from './types.js';
7
+ /**
8
+ * GPT-5.2 on the geo-aware `sfdc_ai__Default*` gateway route — routes to the
9
+ * OpenAI Responses wire shape (Mastra harness). See W-23256760.
10
+ */
11
+ export class GPT52Geo extends Model {
12
+ name = ModelName.GPT_5_2_GEO;
13
+ displayId = 'GPT-5.2 (geo-aware)';
14
+ maxInputTokens = 272000;
15
+ maxOutputTokens = 128000;
16
+ contextWindow = 272000;
17
+ supportsPromptCache = false;
18
+ supportedFormats = [
19
+ { name: 'png', mimeType: MimeType.Png },
20
+ { name: 'jpeg', mimeType: MimeType.Jpeg },
21
+ { name: 'pdf', mimeType: MimeType.Pdf },
22
+ ];
23
+ }
24
+ //# sourceMappingURL=gpt-5-2-geo.js.map
@@ -0,0 +1,16 @@
1
+ import { Model, ModelName } from './model.js';
2
+ import { type SupportedFileFormat } from './types.js';
3
+ /**
4
+ * GPT-5.4 on the geo-aware `sfdc_ai__Default*` gateway route — the regional
5
+ * counterpart to the pinned `llmgateway__OpenAIGPT54` route ({@link GPT54}).
6
+ * Routes to the OpenAI Responses wire shape (Mastra harness). See W-23256760.
7
+ */
8
+ export declare class GPT54Geo extends Model {
9
+ readonly name: ModelName;
10
+ readonly displayId: string;
11
+ readonly maxInputTokens: number;
12
+ readonly maxOutputTokens: number;
13
+ readonly contextWindow: number;
14
+ readonly supportsPromptCache: boolean;
15
+ readonly supportedFormats: readonly SupportedFileFormat[];
16
+ }
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc. All rights reserved.
3
+ * See LICENSE.txt for license terms.
4
+ */
5
+ import { Model, ModelName } from './model.js';
6
+ import { MimeType } from './types.js';
7
+ /**
8
+ * GPT-5.4 on the geo-aware `sfdc_ai__Default*` gateway route — the regional
9
+ * counterpart to the pinned `llmgateway__OpenAIGPT54` route ({@link GPT54}).
10
+ * Routes to the OpenAI Responses wire shape (Mastra harness). See W-23256760.
11
+ */
12
+ export class GPT54Geo extends Model {
13
+ name = ModelName.GPT_5_4_GEO;
14
+ displayId = 'GPT-5.4 (geo-aware)';
15
+ // Source of truth: https://git.soma.salesforce.com/a360/file-metadata/blob/master/fm-model-config/src/main/resources/ai/file-metadata/model/openai/llmgateway/OpenAIGPT54.yml
16
+ maxInputTokens = 1050000;
17
+ maxOutputTokens = 128000;
18
+ contextWindow = 1050000;
19
+ supportsPromptCache = false;
20
+ supportedFormats = [
21
+ { name: 'png', mimeType: MimeType.Png },
22
+ { name: 'jpeg', mimeType: MimeType.Jpeg },
23
+ { name: 'pdf', mimeType: MimeType.Pdf },
24
+ ];
25
+ }
26
+ //# sourceMappingURL=gpt-5-4-geo.js.map
@@ -0,0 +1,17 @@
1
+ import { Model, ModelName } from './model.js';
2
+ import { type SupportedFileFormat } from './types.js';
3
+ /**
4
+ * GPT-5 on the geo-aware `sfdc_ai__Default*` gateway route — the gateway
5
+ * picks the regional OpenAI deployment, distinct from the pinned
6
+ * `llmgateway__OpenAIGPT5` route ({@link GPT5}). Routes to the OpenAI
7
+ * Responses wire shape (Mastra harness). See W-23256760.
8
+ */
9
+ export declare class GPT5Geo extends Model {
10
+ readonly name: ModelName;
11
+ readonly displayId: string;
12
+ readonly maxInputTokens: number;
13
+ readonly maxOutputTokens: number;
14
+ readonly contextWindow: number;
15
+ readonly supportsPromptCache: boolean;
16
+ readonly supportedFormats: readonly SupportedFileFormat[];
17
+ }
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc. All rights reserved.
3
+ * See LICENSE.txt for license terms.
4
+ */
5
+ import { Model, ModelName } from './model.js';
6
+ import { MimeType } from './types.js';
7
+ /**
8
+ * GPT-5 on the geo-aware `sfdc_ai__Default*` gateway route — the gateway
9
+ * picks the regional OpenAI deployment, distinct from the pinned
10
+ * `llmgateway__OpenAIGPT5` route ({@link GPT5}). Routes to the OpenAI
11
+ * Responses wire shape (Mastra harness). See W-23256760.
12
+ */
13
+ export class GPT5Geo extends Model {
14
+ name = ModelName.GPT_5_GEO;
15
+ displayId = 'GPT-5 (geo-aware)';
16
+ // Reference: https://git.soma.salesforce.com/a360/file-metadata/blob/master/fm-model-config/src/main/resources/ai/file-metadata/model/openai/sfdc_ai/DefaultOpenAIGPT5.yml
17
+ maxInputTokens = 272000;
18
+ maxOutputTokens = 128000;
19
+ contextWindow = 272000;
20
+ supportsPromptCache = false;
21
+ // same as gpt-5
22
+ supportedFormats = [
23
+ { name: 'png', mimeType: MimeType.Png },
24
+ { name: 'jpeg', mimeType: MimeType.Jpeg },
25
+ { name: 'pdf', mimeType: MimeType.Pdf },
26
+ ];
27
+ }
28
+ //# sourceMappingURL=gpt-5-geo.js.map
@@ -5,11 +5,16 @@ export { validateMultimodalFiles, MAX_FILES_PER_REQUEST, MAX_TOTAL_FILE_BYTES }
5
5
  export { GPT5 } from './gpt-5.js';
6
6
  export { GPT54 } from './gpt-5-4.js';
7
7
  export { GPT55 } from './gpt-5-5.js';
8
+ export { GPT5Geo } from './gpt-5-geo.js';
9
+ export { GPT51Geo } from './gpt-5-1-geo.js';
10
+ export { GPT52Geo } from './gpt-5-2-geo.js';
11
+ export { GPT54Geo } from './gpt-5-4-geo.js';
8
12
  export { ClaudeSonnet45 } from './claude-sonnet-4-5.js';
9
13
  export { ClaudeSonnet46 } from './claude-sonnet-4-6.js';
10
14
  export { ClaudeOpus45 } from './claude-opus-4-5.js';
11
15
  export { ClaudeOpus46 } from './claude-opus-4-6.js';
12
16
  export { ClaudeOpus47 } from './claude-opus-4-7.js';
17
+ export { ClaudeOpus48 } from './claude-opus-4-8.js';
13
18
  export { createClaudeModel, type ClaudeModelOverrides } from './create-claude-model.js';
14
19
  export declare function getDefault(): Model;
15
20
  export declare function getByName(modelName: ModelName): Model;
@@ -6,22 +6,32 @@ import { Model, ModelName } from './model.js';
6
6
  import { GPT5 } from './gpt-5.js';
7
7
  import { GPT54 } from './gpt-5-4.js';
8
8
  import { GPT55 } from './gpt-5-5.js';
9
+ import { GPT5Geo } from './gpt-5-geo.js';
10
+ import { GPT51Geo } from './gpt-5-1-geo.js';
11
+ import { GPT52Geo } from './gpt-5-2-geo.js';
12
+ import { GPT54Geo } from './gpt-5-4-geo.js';
9
13
  import { ClaudeSonnet45 } from './claude-sonnet-4-5.js';
10
14
  import { ClaudeSonnet46 } from './claude-sonnet-4-6.js';
11
15
  import { ClaudeOpus45 } from './claude-opus-4-5.js';
12
16
  import { ClaudeOpus46 } from './claude-opus-4-6.js';
13
17
  import { ClaudeOpus47 } from './claude-opus-4-7.js';
18
+ import { ClaudeOpus48 } from './claude-opus-4-8.js';
14
19
  export { Model, ModelName } from './model.js';
15
20
  export { MimeType } from './types.js';
16
21
  export { validateMultimodalFiles, MAX_FILES_PER_REQUEST, MAX_TOTAL_FILE_BYTES } from './multimodal.js';
17
22
  export { GPT5 } from './gpt-5.js';
18
23
  export { GPT54 } from './gpt-5-4.js';
19
24
  export { GPT55 } from './gpt-5-5.js';
25
+ export { GPT5Geo } from './gpt-5-geo.js';
26
+ export { GPT51Geo } from './gpt-5-1-geo.js';
27
+ export { GPT52Geo } from './gpt-5-2-geo.js';
28
+ export { GPT54Geo } from './gpt-5-4-geo.js';
20
29
  export { ClaudeSonnet45 } from './claude-sonnet-4-5.js';
21
30
  export { ClaudeSonnet46 } from './claude-sonnet-4-6.js';
22
31
  export { ClaudeOpus45 } from './claude-opus-4-5.js';
23
32
  export { ClaudeOpus46 } from './claude-opus-4-6.js';
24
33
  export { ClaudeOpus47 } from './claude-opus-4-7.js';
34
+ export { ClaudeOpus48 } from './claude-opus-4-8.js';
25
35
  export { createClaudeModel } from './create-claude-model.js';
26
36
  export function getDefault() {
27
37
  return new ClaudeSonnet46();
@@ -33,6 +43,14 @@ export function getByName(modelName) {
33
43
  return new GPT54();
34
44
  if (modelName === ModelName.GPT_5_5)
35
45
  return new GPT55();
46
+ if (modelName === ModelName.GPT_5_GEO)
47
+ return new GPT5Geo();
48
+ if (modelName === ModelName.GPT_5_1_GEO)
49
+ return new GPT51Geo();
50
+ if (modelName === ModelName.GPT_5_2_GEO)
51
+ return new GPT52Geo();
52
+ if (modelName === ModelName.GPT_5_4_GEO)
53
+ return new GPT54Geo();
36
54
  if (modelName === ModelName.CLAUDE_SONNET_4_5)
37
55
  return new ClaudeSonnet45();
38
56
  if (modelName === ModelName.CLAUDE_SONNET_4_6)
@@ -43,6 +61,8 @@ export function getByName(modelName) {
43
61
  return new ClaudeOpus46();
44
62
  if (modelName === ModelName.CLAUDE_OPUS_4_7)
45
63
  return new ClaudeOpus47();
64
+ if (modelName === ModelName.CLAUDE_OPUS_4_8)
65
+ return new ClaudeOpus48();
46
66
  throw new Error(`No model mapping exists for "${modelName}".`);
47
67
  }
48
68
  export const Models = { getDefault, getByName };
@@ -13,11 +13,16 @@ export declare enum ModelName {
13
13
  GPT_5 = "llmgateway__OpenAIGPT5",
14
14
  GPT_5_4 = "llmgateway__OpenAIGPT54",
15
15
  GPT_5_5 = "llmgateway__OpenAIGPT55",
16
+ GPT_5_GEO = "sfdc_ai__DefaultGPT5",
17
+ GPT_5_1_GEO = "sfdc_ai__DefaultGPT51",
18
+ GPT_5_2_GEO = "sfdc_ai__DefaultGPT52",
19
+ GPT_5_4_GEO = "sfdc_ai__DefaultGPT54",
16
20
  CLAUDE_SONNET_4_5 = "llmgateway__BedrockAnthropicClaude45Sonnet",
17
21
  CLAUDE_SONNET_4_6 = "llmgateway__BedrockAnthropicClaude46Sonnet",
18
22
  CLAUDE_OPUS_4_5 = "llmgateway__BedrockAnthropicClaude45Opus",
19
23
  CLAUDE_OPUS_4_6 = "llmgateway__BedrockAnthropicClaude46Opus",
20
- CLAUDE_OPUS_4_7 = "llmgateway__BedrockAnthropicClaude47Opus"
24
+ CLAUDE_OPUS_4_7 = "llmgateway__BedrockAnthropicClaude47Opus",
25
+ CLAUDE_OPUS_4_8 = "llmgateway__BedrockAnthropicClaude48Opus"
21
26
  }
22
27
  /**
23
28
  * Abstract description of a model the SDK / harness can talk to. Used for:
@@ -17,11 +17,19 @@ export var ModelName;
17
17
  ModelName["GPT_5"] = "llmgateway__OpenAIGPT5";
18
18
  ModelName["GPT_5_4"] = "llmgateway__OpenAIGPT54";
19
19
  ModelName["GPT_5_5"] = "llmgateway__OpenAIGPT55";
20
+ // Geo-aware `sfdc_ai__Default*` route: the gateway selects the regional
21
+ // OpenAI deployment. Distinct ids from the pinned `llmgateway__OpenAIGPT*`
22
+ // entries above so both routings coexist (W-23256760).
23
+ ModelName["GPT_5_GEO"] = "sfdc_ai__DefaultGPT5";
24
+ ModelName["GPT_5_1_GEO"] = "sfdc_ai__DefaultGPT51";
25
+ ModelName["GPT_5_2_GEO"] = "sfdc_ai__DefaultGPT52";
26
+ ModelName["GPT_5_4_GEO"] = "sfdc_ai__DefaultGPT54";
20
27
  ModelName["CLAUDE_SONNET_4_5"] = "llmgateway__BedrockAnthropicClaude45Sonnet";
21
28
  ModelName["CLAUDE_SONNET_4_6"] = "llmgateway__BedrockAnthropicClaude46Sonnet";
22
29
  ModelName["CLAUDE_OPUS_4_5"] = "llmgateway__BedrockAnthropicClaude45Opus";
23
30
  ModelName["CLAUDE_OPUS_4_6"] = "llmgateway__BedrockAnthropicClaude46Opus";
24
31
  ModelName["CLAUDE_OPUS_4_7"] = "llmgateway__BedrockAnthropicClaude47Opus";
32
+ ModelName["CLAUDE_OPUS_4_8"] = "llmgateway__BedrockAnthropicClaude48Opus";
25
33
  })(ModelName || (ModelName = {}));
26
34
  /**
27
35
  * Abstract description of a model the SDK / harness can talk to. Used for:
@@ -67,6 +67,17 @@ export type ToolCallEvent = ToolCallInfo & {
67
67
  * server. `undefined` for consumer-declared tools or workspace tools.
68
68
  */
69
69
  serverName?: string;
70
+ /**
71
+ * The un-namespaced MCP tool name — the `(serverName, bareToolName)` pair
72
+ * equals `McpToolInfo.(serverName, toolName)`. Populated by the harness iff
73
+ * {@link serverName} is set; `undefined` for built-in / consumer / workspace
74
+ * tools (whose `toolName` is already bare). The display `toolName` field
75
+ * keeps the harness-namespaced form (Mastra `${server}_${tool}`, Claude
76
+ * `mcp__${server}__${tool}`); this is the policy-identity leaf the SDK builds
77
+ * a `{ type: 'mcp', serverName, toolName }` matcher from — harness-agnostic
78
+ * consumers MUST NOT derive it by string-splitting the display name.
79
+ */
80
+ bareToolName?: string;
70
81
  };
71
82
  /**
72
83
  * An incremental fragment of a tool call's args JSON, emitted while the
@@ -128,6 +139,18 @@ export type ToolApprovalRequestEvent = {
128
139
  * have no MCP origin.
129
140
  */
130
141
  serverName?: string;
142
+ /**
143
+ * The un-namespaced MCP tool name (the `(serverName, bareToolName)` pair
144
+ * equals `McpToolInfo.(serverName, toolName)`). Populated by the harness iff
145
+ * {@link serverName} is set. **This is the field
146
+ * {@link ChatSession.approveToolCall}(id, { remember: true }) reads to build
147
+ * the persisted `{ type: 'mcp', serverName, toolName }` rule** — the display
148
+ * `toolCall.toolName` keeps the harness-namespaced form, which the SDK's
149
+ * `mcp` matcher would never match on replay. `undefined` for built-in /
150
+ * consumer tools, whose `toolCall.toolName` is already the bare name the
151
+ * matcher uses.
152
+ */
153
+ bareToolName?: string;
131
154
  };
132
155
  /**
133
156
  * A real-time stream event indicating a tool execution has completed.
@@ -151,6 +174,14 @@ export type ToolResultEvent = ToolResultInfo & {
151
174
  * server. `undefined` for consumer-declared tools or workspace tools.
152
175
  */
153
176
  serverName?: string;
177
+ /**
178
+ * The un-namespaced MCP tool name; the `(serverName, bareToolName)` pair
179
+ * equals `McpToolInfo.(serverName, toolName)`. Populated by the harness iff
180
+ * {@link serverName} is set; `undefined` for built-in / consumer / workspace
181
+ * tools. The display `toolName` keeps the harness-namespaced form. See
182
+ * {@link ToolCallEvent.bareToolName}.
183
+ */
184
+ bareToolName?: string;
154
185
  };
155
186
  /**
156
187
  * An incremental tool-progress signal emitted while a long-running tool call is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/sfdx-agent-sdk",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -44,19 +44,19 @@
44
44
  },
45
45
  "devDependencies": {
46
46
  "@eslint/js": "^10.0.1",
47
- "@salesforce/sfdx-agent-harness-claude": "0.23.0",
48
- "@salesforce/sfdx-agent-harness-mastra": "0.26.0",
47
+ "@salesforce/sfdx-agent-harness-claude": "0.25.0",
48
+ "@salesforce/sfdx-agent-harness-mastra": "0.28.0",
49
49
  "@types/node": "^22.20.0",
50
50
  "@vitest/coverage-istanbul": "^4.1.8",
51
51
  "@vitest/eslint-plugin": "^1.6.20",
52
- "eslint": "^10.5.0",
52
+ "eslint": "^10.6.0",
53
53
  "eslint-config-prettier": "^10.1.8",
54
54
  "eslint-import-resolver-typescript": "^4.4.5",
55
55
  "eslint-plugin-import": "^2.32.0",
56
- "eslint-plugin-n": "^18.1.0",
56
+ "eslint-plugin-n": "^18.2.1",
57
57
  "globals": "^17.6.0",
58
58
  "lint-staged": "^17.0.7",
59
- "prettier": "^3.8.4",
59
+ "prettier": "^3.9.0",
60
60
  "rimraf": "^6.1.3",
61
61
  "tsx": "^4.22.4",
62
62
  "typescript": "^6.0.3",