@salesforce/sfdx-agent-sdk 0.24.0 → 0.26.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 +13 -0
- package/README.md +103 -36
- package/dist/agent.js +10 -1
- package/dist/chat-session.d.ts +104 -12
- package/dist/chat-session.js +93 -15
- package/dist/harness/harness-config.d.ts +69 -1
- package/dist/harness/harness-config.js +5 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -0
- package/dist/policy-resolver.d.ts +126 -0
- package/dist/policy-resolver.js +175 -0
- package/dist/types/telemetry-events.d.ts +42 -1
- package/dist/types/tools.d.ts +83 -0
- package/package.json +5 -5
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { EventBus } from '@salesforce/agentic-common';
|
|
2
2
|
import type { McpServerErrorDetail, McpServerStatus, McpToolAnnotations } from '../mcp-config.js';
|
|
3
|
+
import type { Decision, ToolPolicyRule } from './tools.js';
|
|
3
4
|
import type { UsageMetadata } from './usage.js';
|
|
4
5
|
/**
|
|
5
6
|
* Telemetry events emitted by the Agent SDK.
|
|
@@ -85,6 +86,46 @@ export type ToolApprovalResolvedEvent = Base<'tool-approval-resolved'> & {
|
|
|
85
86
|
threadId: string;
|
|
86
87
|
toolCallId: string;
|
|
87
88
|
approved: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* `true` when the settle's `remember` flag triggered an
|
|
91
|
+
* `updateAgentConfig` call that appended a `'remember'` policy rule.
|
|
92
|
+
* Absent / `false` when the settle did not persist a rule.
|
|
93
|
+
*/
|
|
94
|
+
policyWritten?: boolean;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Emitted by a harness on every harness-executed tool call, after
|
|
98
|
+
* `resolveToolApprovalPolicy` decides and before any gate work happens.
|
|
99
|
+
* Lets telemetry sinks answer "why did this tool prompt / not prompt / get
|
|
100
|
+
* denied?" by reading the rule that fired.
|
|
101
|
+
*
|
|
102
|
+
* Emitted by the harness layer (Phase 2), not the SDK — the SDK exports the
|
|
103
|
+
* variant so the public `TelemetryEvent` union is complete before the harness
|
|
104
|
+
* PRs land.
|
|
105
|
+
*/
|
|
106
|
+
export type ToolApprovalPolicyResolvedEvent = Base<'tool-approval-policy-resolved'> & {
|
|
107
|
+
agentId: string;
|
|
108
|
+
threadId: string;
|
|
109
|
+
toolCallId: string;
|
|
110
|
+
toolName: string;
|
|
111
|
+
/** Originating MCP server name, when the tool was discovered through MCP. */
|
|
112
|
+
serverName?: string;
|
|
113
|
+
/** The resolved decision. */
|
|
114
|
+
decision: Decision;
|
|
115
|
+
/**
|
|
116
|
+
* The rule that drove the decision under cross-tier-deny-wins /
|
|
117
|
+
* within-tier-last-wins precedence (the last `'deny'` when denied, else the
|
|
118
|
+
* last matching non-deny rule). `undefined` when no rule matched and the
|
|
119
|
+
* resolver fell back to `defaultToolDecision ?? 'allow'`; the harness emits
|
|
120
|
+
* a `LogBus.warn` in that case.
|
|
121
|
+
*/
|
|
122
|
+
matchedRule?: ToolPolicyRule;
|
|
123
|
+
/**
|
|
124
|
+
* Every matching rule in resolved-list order. Optional debug verbosity for
|
|
125
|
+
* sinks that surface "remembered allow overridden by built-in deny"
|
|
126
|
+
* scenarios; most consumers use {@link matchedRule}.
|
|
127
|
+
*/
|
|
128
|
+
allMatchedRules?: ToolPolicyRule[];
|
|
88
129
|
};
|
|
89
130
|
export type McpServerDiscoveryStartedEvent = Base<'mcp-server-discovery-started'> & {
|
|
90
131
|
agentId: string;
|
|
@@ -137,7 +178,7 @@ export type McpServerStatusChangedEvent = Base<'mcp-server-status-changed'> & {
|
|
|
137
178
|
/** Populated when `nextStatus === 'error'`. */
|
|
138
179
|
error?: string;
|
|
139
180
|
};
|
|
140
|
-
export type TelemetryEvent = AgentCreatedEvent | AgentDestroyedEvent | SessionCreatedEvent | SessionDestroyedEvent | ChatStreamStartedEvent | ChatStreamCompletedEvent | ChatStreamErrorEvent | ToolExecutionStartedEvent | ToolExecutionCompletedEvent | ToolApprovalRequestedEvent | ToolApprovalResolvedEvent | McpServerDiscoveryStartedEvent | McpServerDiscoveryCompletedEvent | McpServerDiscoveryFailedEvent | McpServerStatusChangedEvent;
|
|
181
|
+
export type TelemetryEvent = AgentCreatedEvent | AgentDestroyedEvent | SessionCreatedEvent | SessionDestroyedEvent | ChatStreamStartedEvent | ChatStreamCompletedEvent | ChatStreamErrorEvent | ToolExecutionStartedEvent | ToolExecutionCompletedEvent | ToolApprovalRequestedEvent | ToolApprovalResolvedEvent | ToolApprovalPolicyResolvedEvent | McpServerDiscoveryStartedEvent | McpServerDiscoveryCompletedEvent | McpServerDiscoveryFailedEvent | McpServerStatusChangedEvent;
|
|
141
182
|
export type TelemetryEventCallback = (event: TelemetryEvent) => void;
|
|
142
183
|
export type TelemetryBus = EventBus<TelemetryEvent>;
|
|
143
184
|
export {};
|
package/dist/types/tools.d.ts
CHANGED
|
@@ -46,6 +46,89 @@ export type ToolDefinition = {
|
|
|
46
46
|
*/
|
|
47
47
|
annotations?: McpToolAnnotations;
|
|
48
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* The policy decision for a single tool invocation.
|
|
51
|
+
*
|
|
52
|
+
* - `'allow'` — the harness executes the tool without pausing.
|
|
53
|
+
* - `'deny'` — the harness refuses the call and synthesizes a
|
|
54
|
+
* `tool-result(isError=true)` so the model can recover; no
|
|
55
|
+
* `tool-approval-request` surfaces.
|
|
56
|
+
* - `'require-approval'` — the harness emits a `tool-approval-request`
|
|
57
|
+
* and suspends until the consumer settles via `approveToolCall` /
|
|
58
|
+
* `declineToolCall`.
|
|
59
|
+
*/
|
|
60
|
+
export type Decision = 'allow' | 'deny' | 'require-approval';
|
|
61
|
+
/**
|
|
62
|
+
* Structured matcher selecting which tool invocations a {@link ToolPolicyRule}
|
|
63
|
+
* applies to.
|
|
64
|
+
*
|
|
65
|
+
* The three shapes cover every tool category a harness gates:
|
|
66
|
+
*
|
|
67
|
+
* - `'builtin'` — harness-built-in tools (e.g. Claude's `Bash` / `Edit`;
|
|
68
|
+
* Mastra's `updateWorkingMemory`). Names are **harness-specific**, so a
|
|
69
|
+
* `'builtin'` rule applies asymmetrically across harnesses — `Bash` matches
|
|
70
|
+
* on Claude and is a no-op on Mastra. A `'builtin'` matcher matches only when
|
|
71
|
+
* the invocation has no `serverName` (MCP tools carry one).
|
|
72
|
+
* - `'mcp'` — MCP-discovered tools. Both `serverName` and `toolName` are
|
|
73
|
+
* optional: omitting `toolName` matches every tool from the given server;
|
|
74
|
+
* omitting `serverName` matches every tool from every MCP server; omitting
|
|
75
|
+
* both matches every MCP tool (a server-agnostic catch-all). MCP rules are
|
|
76
|
+
* **portable** — the same rule fires on both harnesses for the same tool.
|
|
77
|
+
* - `'mcp-annotation'` — matches any MCP tool whose discovered
|
|
78
|
+
* {@link McpToolAnnotations} carry the specified hint(s). Every field set on
|
|
79
|
+
* the matcher must equal the corresponding field on the discovered
|
|
80
|
+
* annotation (logical AND across set fields). A tool with no annotations does
|
|
81
|
+
* **not** match — the resolver falls through. This is fail-open by default;
|
|
82
|
+
* tenants needing fail-closed for un-annotated MCP servers set
|
|
83
|
+
* {@link AgentConfig.defaultToolDecision} to `'require-approval'`.
|
|
84
|
+
*
|
|
85
|
+
* There is intentionally no `consumer` matcher. Consumer-declared tools (those
|
|
86
|
+
* in {@link AgentConfig.tools} without an `execute`) are gated structurally at
|
|
87
|
+
* the harness boundary and never reach the resolver, so a matcher variant for
|
|
88
|
+
* them would be API surface for an unreachable case.
|
|
89
|
+
*/
|
|
90
|
+
export type ToolMatcher = {
|
|
91
|
+
type: 'builtin';
|
|
92
|
+
name: string;
|
|
93
|
+
} | {
|
|
94
|
+
type: 'mcp';
|
|
95
|
+
serverName?: string;
|
|
96
|
+
toolName?: string;
|
|
97
|
+
} | {
|
|
98
|
+
type: 'mcp-annotation';
|
|
99
|
+
readOnlyHint?: boolean;
|
|
100
|
+
destructiveHint?: boolean;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* One entry in an agent's tool-approval policy list.
|
|
104
|
+
*
|
|
105
|
+
* Resolution concatenates the SDK's `BUILT_IN_TOOL_POLICIES`, the harness's
|
|
106
|
+
* built-in array, any harness factory rules, and `AgentConfig.toolPolicies`,
|
|
107
|
+
* then applies **cross-tier deny-wins / within-tier last-wins** precedence (see
|
|
108
|
+
* `resolveToolApprovalPolicy`).
|
|
109
|
+
*/
|
|
110
|
+
export type ToolPolicyRule = {
|
|
111
|
+
/** Selects which tool invocations this rule applies to. */
|
|
112
|
+
matcher: ToolMatcher;
|
|
113
|
+
/** The decision to apply when {@link matcher} matches. */
|
|
114
|
+
decision: Decision;
|
|
115
|
+
/**
|
|
116
|
+
* Where this rule originated. Advisory metadata only — the resolver
|
|
117
|
+
* **ignores** `source` when computing a decision; telemetry surfaces it so
|
|
118
|
+
* operators can answer "which tier fired."
|
|
119
|
+
*
|
|
120
|
+
* - `'built-in'` — shipped by the SDK's `BUILT_IN_TOOL_POLICIES` or a
|
|
121
|
+
* harness package's `<HARNESS>_BUILT_IN_TOOL_POLICIES` array.
|
|
122
|
+
* - `'agent-config'` — authored by whoever wrote the `AgentConfig`. The
|
|
123
|
+
* default when unset on a consumer-supplied rule.
|
|
124
|
+
* - `'remember'` — written by `approveToolCall(id, { remember: true })` /
|
|
125
|
+
* `declineToolCall(id, { remember: true })`.
|
|
126
|
+
*
|
|
127
|
+
* v1 ships these three values. A future tenant-managed-policy tier will add
|
|
128
|
+
* `'managed'` to this union; that widening is strictly additive.
|
|
129
|
+
*/
|
|
130
|
+
source?: 'built-in' | 'agent-config' | 'remember';
|
|
131
|
+
};
|
|
49
132
|
/**
|
|
50
133
|
* Base shape for a tool call.
|
|
51
134
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/sfdx-agent-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"LICENSE.txt"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@salesforce/agentic-common": "0.
|
|
43
|
+
"@salesforce/agentic-common": "0.13.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@eslint/js": "^10.0.1",
|
|
47
|
-
"@salesforce/sfdx-agent-harness-claude": "0.
|
|
48
|
-
"@salesforce/sfdx-agent-harness-mastra": "0.
|
|
47
|
+
"@salesforce/sfdx-agent-harness-claude": "0.22.0",
|
|
48
|
+
"@salesforce/sfdx-agent-harness-mastra": "0.25.0",
|
|
49
49
|
"@types/node": "^22.20.0",
|
|
50
50
|
"@vitest/coverage-istanbul": "^4.1.8",
|
|
51
51
|
"@vitest/eslint-plugin": "^1.6.20",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"vitest": "^4.1.8"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|
|
67
|
-
"node": ">=22.
|
|
67
|
+
"node": ">=22.22.0"
|
|
68
68
|
},
|
|
69
69
|
"lint-staged": {
|
|
70
70
|
"*.{js,jsx,ts,tsx,json,md}": [
|