@salesforce/sfdx-agent-harness-openai 0.2.0 → 0.4.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 +4 -4
- package/dist/openai-agents-harness.js +17 -5
- package/dist/openai-agents-harness.js.map +1 -1
- package/dist/openai-approval-coordinator.d.ts +20 -0
- package/dist/openai-approval-coordinator.js +29 -0
- package/dist/openai-approval-coordinator.js.map +1 -1
- package/dist/openai-mcp-client-facade.d.ts +53 -0
- package/dist/openai-mcp-client-facade.js +169 -0
- package/dist/openai-mcp-client-facade.js.map +1 -0
- package/dist/openai-mcp-config-mapper.d.ts +28 -0
- package/dist/openai-mcp-config-mapper.js +5 -4
- package/dist/openai-mcp-config-mapper.js.map +1 -1
- package/dist/openai-tool-redaction.d.ts +17 -0
- package/dist/openai-tool-redaction.js +60 -19
- package/dist/openai-tool-redaction.js.map +1 -1
- package/dist/test/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -4
|
@@ -9,6 +9,26 @@ import { MCPServerStdio, MCPServerStreamableHttp, type MCPServer } from '@openai
|
|
|
9
9
|
*/
|
|
10
10
|
type MCPServerStdioOptions = ConstructorParameters<typeof MCPServerStdio>[0];
|
|
11
11
|
type MCPServerStreamableHttpOptions = ConstructorParameters<typeof MCPServerStreamableHttp>[0];
|
|
12
|
+
/**
|
|
13
|
+
* MCP SDK's built-in `StreamableHTTPReconnectionOptions` defaults. This is a
|
|
14
|
+
* byte-identical copy of the Mastra harness's `DEFAULT_RECONNECTION_OPTIONS`
|
|
15
|
+
* (`mcp-config-mapper.ts`) and the Claude harness's copy
|
|
16
|
+
* (`mcp-client-factory.ts`) — cross-harness imports are lint-blocked
|
|
17
|
+
* (`harnessIsolationPack`), so the constant is duplicated on purpose and the
|
|
18
|
+
* shared `@salesforce/harness-conformance` `RECONNECTION_DEFAULTS` table is the
|
|
19
|
+
* drift-guard that keeps the three in lockstep.
|
|
20
|
+
*
|
|
21
|
+
* The field-wise merge below (`{ ...DEFAULT_RECONNECTION_OPTIONS, ...input }`)
|
|
22
|
+
* is required because the underlying transport replaces the entire defaults
|
|
23
|
+
* object when `reconnectionOptions` is set — a partial override would otherwise
|
|
24
|
+
* zero out the unspecified fields.
|
|
25
|
+
*/
|
|
26
|
+
export declare const DEFAULT_RECONNECTION_OPTIONS: {
|
|
27
|
+
readonly maxRetries: 2;
|
|
28
|
+
readonly initialReconnectionDelay: 1000;
|
|
29
|
+
readonly maxReconnectionDelay: 30000;
|
|
30
|
+
readonly reconnectionDelayGrowFactor: 1.5;
|
|
31
|
+
};
|
|
12
32
|
/**
|
|
13
33
|
* Returns `true` if `config` contains at least one server that is not explicitly
|
|
14
34
|
* disabled. A server is enabled when its `enabled` property is `true` or absent.
|
|
@@ -55,4 +75,12 @@ export declare function toOpenAIMcpServerOptions(name: string, config: MCPServer
|
|
|
55
75
|
* `close()` lifecycle.
|
|
56
76
|
*/
|
|
57
77
|
export declare function mapToOpenAIMcpServers(config: MCPConfiguration, orgJwt?: JSONWebToken, innerFetch?: typeof fetch): Map<string, MCPServer>;
|
|
78
|
+
/**
|
|
79
|
+
* Build a `fetch` that resolves fresh MCP auth headers per request. Copied from
|
|
80
|
+
* the Mastra harness's `createAuthFetch` — {@link resolveMcpServerHeaders}
|
|
81
|
+
* injects the rotating JWT only for Salesforce Platform MCP URLs and passes
|
|
82
|
+
* every other URL through unchanged, so this is safe to wire on any remote
|
|
83
|
+
* server whenever an `orgJwt` is available.
|
|
84
|
+
*/
|
|
85
|
+
export declare function createAuthFetch(serverUrl: string | URL, orgJwt: JSONWebToken, innerFetch: typeof fetch, existingHeaders?: Record<string, string>): typeof fetch;
|
|
58
86
|
export {};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { resolveMcpServerHeaders } from '@salesforce/sfdx-agent-sdk';
|
|
6
6
|
import { MCPServerStdio, MCPServerStreamableHttp } from '@openai/agents';
|
|
7
|
+
import { buildMcpClient, ProgressCapableMcpServer } from './openai-mcp-client-facade.js';
|
|
7
8
|
/**
|
|
8
9
|
* MCP SDK's built-in `StreamableHTTPReconnectionOptions` defaults. This is a
|
|
9
10
|
* byte-identical copy of the Mastra harness's `DEFAULT_RECONNECTION_OPTIONS`
|
|
@@ -18,7 +19,7 @@ import { MCPServerStdio, MCPServerStreamableHttp } from '@openai/agents';
|
|
|
18
19
|
* object when `reconnectionOptions` is set — a partial override would otherwise
|
|
19
20
|
* zero out the unspecified fields.
|
|
20
21
|
*/
|
|
21
|
-
const DEFAULT_RECONNECTION_OPTIONS = {
|
|
22
|
+
export const DEFAULT_RECONNECTION_OPTIONS = {
|
|
22
23
|
maxRetries: 2,
|
|
23
24
|
initialReconnectionDelay: 1000,
|
|
24
25
|
maxReconnectionDelay: 30000,
|
|
@@ -107,8 +108,8 @@ export function mapToOpenAIMcpServers(config, orgJwt, innerFetch = fetch) {
|
|
|
107
108
|
for (const [name, serverConfig] of Object.entries(config)) {
|
|
108
109
|
if (serverConfig.enabled === false)
|
|
109
110
|
continue;
|
|
110
|
-
const
|
|
111
|
-
const server =
|
|
111
|
+
const built = buildMcpClient(serverConfig, orgJwt, innerFetch);
|
|
112
|
+
const server = new ProgressCapableMcpServer({ name, ...built, config: serverConfig });
|
|
112
113
|
servers.set(name, server);
|
|
113
114
|
}
|
|
114
115
|
return servers;
|
|
@@ -120,7 +121,7 @@ export function mapToOpenAIMcpServers(config, orgJwt, innerFetch = fetch) {
|
|
|
120
121
|
* every other URL through unchanged, so this is safe to wire on any remote
|
|
121
122
|
* server whenever an `orgJwt` is available.
|
|
122
123
|
*/
|
|
123
|
-
function createAuthFetch(serverUrl, orgJwt, innerFetch, existingHeaders) {
|
|
124
|
+
export function createAuthFetch(serverUrl, orgJwt, innerFetch, existingHeaders) {
|
|
124
125
|
return async (url, init) => {
|
|
125
126
|
const authHeaders = await resolveMcpServerHeaders(serverUrl, orgJwt, existingHeaders);
|
|
126
127
|
const merged = new Headers(init?.headers);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-mcp-config-mapper.js","sourceRoot":"","sources":["../src/openai-mcp-config-mapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAA+C,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAClH,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAkB,MAAM,gBAAgB,CAAC;AAWzF;;;;;;;;;;;;;GAaG;AACH,MAAM,4BAA4B,GAAG;
|
|
1
|
+
{"version":3,"file":"openai-mcp-config-mapper.js","sourceRoot":"","sources":["../src/openai-mcp-config-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import { type MCPServer, type Tool } from '@openai/agents';
|
|
2
2
|
import type { Decision, ToolInvocation, ToolResultRedactor } from '@salesforce/sfdx-agent-sdk';
|
|
3
|
+
import { type ProgressCapableMcpServer } from './openai-mcp-client-facade.js';
|
|
3
4
|
import type { McpCatalogEntry } from './openai-mcp-state.js';
|
|
5
|
+
export type ProgressHolder = {
|
|
6
|
+
emit?: (args: {
|
|
7
|
+
toolCallId: string;
|
|
8
|
+
toolName: string;
|
|
9
|
+
progress: number;
|
|
10
|
+
total?: number;
|
|
11
|
+
message?: string;
|
|
12
|
+
}) => void;
|
|
13
|
+
};
|
|
14
|
+
export type McpProgressContext = {
|
|
15
|
+
readonly holder: ProgressHolder;
|
|
16
|
+
readonly mcpCatalog: ReadonlyMap<string, McpCatalogEntry>;
|
|
17
|
+
readonly rawServerFor: (serverName: string) => ProgressCapableMcpServer | undefined;
|
|
18
|
+
readonly getSignal?: () => AbortSignal | undefined;
|
|
19
|
+
};
|
|
4
20
|
/**
|
|
5
21
|
* Everything a redaction seam needs to call the consumer's
|
|
6
22
|
* {@link ToolResultRedactor} with a faithful {@link ToolResultRedactionInput}.
|
|
@@ -86,4 +102,5 @@ export declare function applyRedaction(ctx: RedactionContext, args: {
|
|
|
86
102
|
export declare function buildManagedMcpTools(servers: MCPServer[], ctx: {
|
|
87
103
|
redaction?: RedactionContext;
|
|
88
104
|
approval?: McpApprovalContext;
|
|
105
|
+
progress?: McpProgressContext;
|
|
89
106
|
}): Promise<Tool[]>;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* See LICENSE.txt for license terms.
|
|
4
4
|
*/
|
|
5
5
|
import { getAllMcpTools } from '@openai/agents';
|
|
6
|
+
import { parseToolInput } from './openai-mcp-client-facade.js';
|
|
6
7
|
/**
|
|
7
8
|
* Lift a tool's **display name** (the `@openai/agents`-sanitized name carried on
|
|
8
9
|
* interruptions and materialized tools) to the {@link ToolInvocation} the policy
|
|
@@ -86,6 +87,7 @@ function manageFunctionTool(tool, ctx) {
|
|
|
86
87
|
const originalInvoke = tool.invoke.bind(tool);
|
|
87
88
|
const redaction = ctx.redaction;
|
|
88
89
|
const approval = ctx.approval;
|
|
90
|
+
const progress = ctx.progress;
|
|
89
91
|
return {
|
|
90
92
|
...tool,
|
|
91
93
|
// Gate the tool when the policy resolves its invocation to anything but
|
|
@@ -100,27 +102,66 @@ function manageFunctionTool(tool, ctx) {
|
|
|
100
102
|
needsApproval: async () => approval.policy(toToolInvocation(tool.name, approval.mcpCatalog)) !== 'allow',
|
|
101
103
|
}
|
|
102
104
|
: {}),
|
|
103
|
-
invoke:
|
|
104
|
-
?
|
|
105
|
-
|
|
106
|
-
const
|
|
105
|
+
invoke: progress !== undefined
|
|
106
|
+
? async (runContext, input, details) => {
|
|
107
|
+
const entry = progress.mcpCatalog.get(tool.name);
|
|
108
|
+
const serverName = entry?.serverName;
|
|
109
|
+
const facade = serverName !== undefined ? progress.rawServerFor(serverName) : undefined;
|
|
110
|
+
if (facade === undefined)
|
|
111
|
+
return originalInvoke(runContext, input, details);
|
|
107
112
|
const toolCallId = details?.toolCall?.callId;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
const onprogress = toolCallId === undefined
|
|
114
|
+
? undefined
|
|
115
|
+
: (note) => {
|
|
116
|
+
try {
|
|
117
|
+
progress.holder.emit?.({
|
|
118
|
+
toolCallId,
|
|
119
|
+
toolName: tool.name,
|
|
120
|
+
progress: note.progress,
|
|
121
|
+
...(note.total !== undefined ? { total: note.total } : {}),
|
|
122
|
+
...(note.message !== undefined ? { message: note.message } : {}),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// MCP invokes `onprogress` without a catch; a sink failure must not break the RPC.
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const signal = progress.getSignal?.();
|
|
130
|
+
let output = await facade.callTool(entry?.toolName ?? tool.name, parseToolInput(input), {
|
|
131
|
+
...(onprogress !== undefined ? { onprogress } : {}),
|
|
132
|
+
...(signal !== undefined ? { signal } : {}),
|
|
117
133
|
});
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
if (redaction !== undefined) {
|
|
135
|
+
output = (await applyRedaction(redaction, {
|
|
136
|
+
toolCallId: toolCallId ?? '',
|
|
137
|
+
toolName: tool.name,
|
|
138
|
+
output,
|
|
139
|
+
isError: false,
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
return output;
|
|
143
|
+
}
|
|
144
|
+
: redaction === undefined
|
|
145
|
+
? originalInvoke
|
|
146
|
+
: async (runContext, input, details) => {
|
|
147
|
+
const output = await originalInvoke(runContext, input, details);
|
|
148
|
+
const toolCallId = details?.toolCall?.callId;
|
|
149
|
+
// Without a callId the redaction input can't be faithfully
|
|
150
|
+
// attributed; still redact (the redactor keys on
|
|
151
|
+
// toolName/output), passing an empty id rather than
|
|
152
|
+
// dropping the hook.
|
|
153
|
+
const redacted = await applyRedaction(redaction, {
|
|
154
|
+
toolCallId: toolCallId ?? '',
|
|
155
|
+
toolName: tool.name,
|
|
156
|
+
output,
|
|
157
|
+
isError: isErrorOutput(output),
|
|
158
|
+
});
|
|
159
|
+
// `invoke` must return `string | Result`; a redactor may
|
|
160
|
+
// return any shape (the consumer owns matching the tool's
|
|
161
|
+
// expected shape, per the ToolResultRedactor contract — the
|
|
162
|
+
// harness does not validate it).
|
|
163
|
+
return redacted;
|
|
164
|
+
},
|
|
124
165
|
};
|
|
125
166
|
}
|
|
126
167
|
/** Best-effort MCP error detection: the model-visible output carries no structured flag, so duck-type it. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-tool-redaction.js","sourceRoot":"","sources":["../src/openai-tool-redaction.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAA6B,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-tool-redaction.js","sourceRoot":"","sources":["../src/openai-tool-redaction.ts"],"names":[],"mappings":"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"}
|