@mcp-use/client 2.0.0-beta.13 → 2.0.0-beta.15
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/README.md +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/auth/browser.d.ts +3 -0
- package/dist/auth/browser.d.ts.map +1 -1
- package/dist/auth/callback.d.ts.map +1 -1
- package/dist/auth/flow.d.ts.map +1 -1
- package/dist/auth/node.d.ts +16 -1
- package/dist/auth/node.d.ts.map +1 -1
- package/dist/index-browser.js +124 -64
- package/dist/index-browser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +137 -47
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +424 -152
- package/dist/react/index.js.map +1 -1
- package/dist/react/storage.d.ts.map +1 -1
- package/dist/react/token-expiry.d.ts +9 -0
- package/dist/react/token-expiry.d.ts.map +1 -0
- package/dist/react/useMcp.d.ts.map +1 -1
- package/dist/react/view/ViewRenderer.d.ts +5 -4
- package/dist/react/view/ViewRenderer.d.ts.map +1 -1
- package/dist/react/view/ext-apps-bridge.d.ts +1 -1
- package/dist/react/view/ext-apps-bridge.d.ts.map +1 -1
- package/dist/react/view/sandbox-blob-url.d.ts +2 -0
- package/dist/react/view/sandbox-blob-url.d.ts.map +1 -1
- package/dist/react/view/types.d.ts +22 -4
- package/dist/react/view/types.d.ts.map +1 -1
- package/dist/react/view/view-host-policy.d.ts +26 -0
- package/dist/react/view/view-host-policy.d.ts.map +1 -0
- package/dist/telemetry/events.d.ts.map +1 -1
- package/dist/telemetry/tel-fetch.d.ts.map +1 -1
- package/dist/transport/connection-manager.d.ts +4 -0
- package/dist/transport/connection-manager.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -1534,7 +1534,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1534
1534
|
};
|
|
1535
1535
|
|
|
1536
1536
|
// src/utils/version.ts
|
|
1537
|
-
var VERSION = "2.0.0-beta.
|
|
1537
|
+
var VERSION = "2.0.0-beta.15";
|
|
1538
1538
|
function getPackageVersion() {
|
|
1539
1539
|
return VERSION;
|
|
1540
1540
|
}
|
|
@@ -2068,7 +2068,7 @@ var OAuthSessionStore = class _OAuthSessionStore {
|
|
|
2068
2068
|
*/
|
|
2069
2069
|
async storeAuthorizationState(authorizationUrl, opts = {}) {
|
|
2070
2070
|
const state = globalThis.crypto.randomUUID();
|
|
2071
|
-
const stateKey = `${this.storageKeyPrefix}
|
|
2071
|
+
const stateKey = `${this.storageKeyPrefix}_${this.serverUrlHash}_state_${state}`;
|
|
2072
2072
|
const stateData = {
|
|
2073
2073
|
serverUrlHash: this.serverUrlHash,
|
|
2074
2074
|
expiry: Date.now() + 1e3 * 60 * 10,
|
|
@@ -2140,6 +2140,7 @@ var BrowserOAuthClientProvider = class {
|
|
|
2140
2140
|
connectionUrl;
|
|
2141
2141
|
proxyOAuthRequests;
|
|
2142
2142
|
lastAttemptedAuthUrl = null;
|
|
2143
|
+
authorizationPending = false;
|
|
2143
2144
|
onPopupWindow;
|
|
2144
2145
|
constructor(serverUrl, options = {}) {
|
|
2145
2146
|
if (options.staticClientInfo?.client_secret) {
|
|
@@ -2190,6 +2191,12 @@ var BrowserOAuthClientProvider = class {
|
|
|
2190
2191
|
getKey(keySuffix) {
|
|
2191
2192
|
return this.session.getKey(keySuffix);
|
|
2192
2193
|
}
|
|
2194
|
+
get hasPendingFlow() {
|
|
2195
|
+
return this.authorizationPending;
|
|
2196
|
+
}
|
|
2197
|
+
markFlowComplete() {
|
|
2198
|
+
this.authorizationPending = false;
|
|
2199
|
+
}
|
|
2193
2200
|
/**
|
|
2194
2201
|
* Re-anchor an SDK-derived OAuth discovery URL from the MCP connection
|
|
2195
2202
|
* (proxy) origin onto the actual MCP server.
|
|
@@ -2370,6 +2377,7 @@ var BrowserOAuthClientProvider = class {
|
|
|
2370
2377
|
}
|
|
2371
2378
|
saveTokens(tokens, ctx) {
|
|
2372
2379
|
this.lastAttemptedAuthUrl = null;
|
|
2380
|
+
this.authorizationPending = false;
|
|
2373
2381
|
return this.session.saveTokens(tokens, ctx);
|
|
2374
2382
|
}
|
|
2375
2383
|
async clientInformation(ctx) {
|
|
@@ -2450,6 +2458,7 @@ var BrowserOAuthClientProvider = class {
|
|
|
2450
2458
|
}
|
|
2451
2459
|
);
|
|
2452
2460
|
this.lastAttemptedAuthUrl = prepared;
|
|
2461
|
+
this.authorizationPending = true;
|
|
2453
2462
|
return prepared;
|
|
2454
2463
|
}
|
|
2455
2464
|
/**
|
|
@@ -2506,15 +2515,13 @@ var BrowserOAuthClientProvider = class {
|
|
|
2506
2515
|
}
|
|
2507
2516
|
clearStorage() {
|
|
2508
2517
|
this.lastAttemptedAuthUrl = null;
|
|
2518
|
+
this.authorizationPending = false;
|
|
2509
2519
|
const prefixPattern = `${this.storageKeyPrefix}_${this.serverUrlHash}_`;
|
|
2510
|
-
const statePattern = `${this.storageKeyPrefix}:state_`;
|
|
2511
2520
|
const keysToRemove = [];
|
|
2512
2521
|
let count = 0;
|
|
2513
2522
|
for (const key of this.storage.keys()) {
|
|
2514
2523
|
if (key.startsWith(prefixPattern)) {
|
|
2515
2524
|
keysToRemove.push(key);
|
|
2516
|
-
} else if (key.startsWith(statePattern)) {
|
|
2517
|
-
keysToRemove.push(key);
|
|
2518
2525
|
}
|
|
2519
2526
|
}
|
|
2520
2527
|
const uniqueKeysToRemove = [...new Set(keysToRemove)];
|
|
@@ -2550,16 +2557,13 @@ var MCPAgentExecutionEvent = class extends BaseTelemetryEvent {
|
|
|
2550
2557
|
return {
|
|
2551
2558
|
// Core execution info
|
|
2552
2559
|
execution_method: this.data.executionMethod,
|
|
2553
|
-
query: this.data.query,
|
|
2554
2560
|
query_length: this.data.query.length,
|
|
2555
2561
|
success: this.data.success,
|
|
2556
2562
|
// Agent configuration
|
|
2557
2563
|
model_provider: this.data.modelProvider,
|
|
2558
2564
|
model_name: this.data.modelName,
|
|
2559
2565
|
server_count: this.data.serverCount,
|
|
2560
|
-
server_identifiers: this.data.serverIdentifiers,
|
|
2561
2566
|
total_tools_available: this.data.totalToolsAvailable,
|
|
2562
|
-
tools_available_names: this.data.toolsAvailableNames,
|
|
2563
2567
|
max_steps_configured: this.data.maxStepsConfigured,
|
|
2564
2568
|
memory_enabled: this.data.memoryEnabled,
|
|
2565
2569
|
use_server_manager: this.data.useServerManager,
|
|
@@ -2570,8 +2574,6 @@ var MCPAgentExecutionEvent = class extends BaseTelemetryEvent {
|
|
|
2570
2574
|
// Execution results (always include, even if null)
|
|
2571
2575
|
steps_taken: this.data.stepsTaken ?? null,
|
|
2572
2576
|
tools_used_count: this.data.toolsUsedCount ?? null,
|
|
2573
|
-
tools_used_names: this.data.toolsUsedNames ?? null,
|
|
2574
|
-
response: this.data.response ?? null,
|
|
2575
2577
|
response_length: this.data.response ? this.data.response.length : null,
|
|
2576
2578
|
execution_time_ms: this.data.executionTimeMs ?? null,
|
|
2577
2579
|
error_type: this.data.errorType ?? null,
|
|
@@ -2667,21 +2669,72 @@ async function telFetch(url, init) {
|
|
|
2667
2669
|
}
|
|
2668
2670
|
var POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
2669
2671
|
var POSTHOG_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2672
|
+
var CONTENT_PROPERTY = /(^|_)(arguments?|args|body|command|headers?|location|message|query|response|secret|subject|token|uri|url|user_agent)(_|$)/i;
|
|
2673
|
+
var IDENTIFYING_PROPERTY = /(^|_)(server_identifiers?|server_names?|servers|tool_names?|tools_(available|used)_names)(_|$)/i;
|
|
2674
|
+
var AGGREGATE_PROPERTY = /(_count|_length|_duration(?:_ms)?|_time_ms|(^|_)num_[a-z0-9_]+)$/i;
|
|
2675
|
+
function normalizePropertyKey(key) {
|
|
2676
|
+
return key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-z0-9_$]+/gi, "_").toLowerCase();
|
|
2677
|
+
}
|
|
2678
|
+
function sanitizeValue(value, seen) {
|
|
2679
|
+
if (Array.isArray(value)) {
|
|
2680
|
+
if (seen.has(value)) {
|
|
2681
|
+
throw new TypeError("Cyclic telemetry properties are not supported");
|
|
2682
|
+
}
|
|
2683
|
+
seen.add(value);
|
|
2684
|
+
const sanitized = value.map((item) => sanitizeValue(item, seen));
|
|
2685
|
+
seen.delete(value);
|
|
2686
|
+
return sanitized;
|
|
2687
|
+
}
|
|
2688
|
+
if (value !== null && typeof value === "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)) {
|
|
2689
|
+
if (seen.has(value)) {
|
|
2690
|
+
throw new TypeError("Cyclic telemetry properties are not supported");
|
|
2691
|
+
}
|
|
2692
|
+
seen.add(value);
|
|
2693
|
+
const sanitized = sanitizeProperties(
|
|
2694
|
+
value,
|
|
2695
|
+
seen
|
|
2696
|
+
);
|
|
2697
|
+
seen.delete(value);
|
|
2698
|
+
return sanitized;
|
|
2699
|
+
}
|
|
2700
|
+
return value;
|
|
2701
|
+
}
|
|
2702
|
+
function sanitizeProperties(properties, seen = /* @__PURE__ */ new WeakSet()) {
|
|
2703
|
+
const sanitized = {};
|
|
2704
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
2705
|
+
const normalizedKey = normalizePropertyKey(key);
|
|
2706
|
+
if (AGGREGATE_PROPERTY.test(normalizedKey)) {
|
|
2707
|
+
if (value === null || typeof value === "number") {
|
|
2708
|
+
sanitized[key] = value;
|
|
2709
|
+
}
|
|
2710
|
+
continue;
|
|
2711
|
+
}
|
|
2712
|
+
if (IDENTIFYING_PROPERTY.test(normalizedKey) || CONTENT_PROPERTY.test(normalizedKey)) {
|
|
2713
|
+
continue;
|
|
2714
|
+
}
|
|
2715
|
+
sanitized[key] = sanitizeValue(value, seen);
|
|
2716
|
+
}
|
|
2717
|
+
return sanitized;
|
|
2718
|
+
}
|
|
2719
|
+
async function capturePostHog(params) {
|
|
2720
|
+
try {
|
|
2721
|
+
const host = params.host ?? POSTHOG_HOST;
|
|
2722
|
+
const apiKey = params.apiKey ?? POSTHOG_API_KEY;
|
|
2723
|
+
const body = JSON.stringify({
|
|
2678
2724
|
api_key: apiKey,
|
|
2679
2725
|
event: params.event,
|
|
2680
2726
|
distinct_id: params.distinctId,
|
|
2681
|
-
properties: params.properties,
|
|
2727
|
+
properties: sanitizeProperties(params.properties),
|
|
2682
2728
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2683
|
-
})
|
|
2684
|
-
|
|
2729
|
+
});
|
|
2730
|
+
await telFetch(`${host}/i/v0/e/`, {
|
|
2731
|
+
method: "POST",
|
|
2732
|
+
headers: { "Content-Type": "application/json" },
|
|
2733
|
+
keepalive: true,
|
|
2734
|
+
body
|
|
2735
|
+
});
|
|
2736
|
+
} catch {
|
|
2737
|
+
}
|
|
2685
2738
|
}
|
|
2686
2739
|
|
|
2687
2740
|
// src/telemetry/telemetry.ts
|
|
@@ -3013,11 +3066,12 @@ async function completeOAuthFlow(provider, serverUrl, options = {}) {
|
|
|
3013
3066
|
throw new Error(`Unexpected OAuth auth() result: ${result}`);
|
|
3014
3067
|
}
|
|
3015
3068
|
}
|
|
3016
|
-
if (typeof flowProvider.getAuthorizationCode === "function") {
|
|
3017
|
-
const
|
|
3069
|
+
if (typeof flowProvider.getAuthorizationResponse === "function" || typeof flowProvider.getAuthorizationCode === "function") {
|
|
3070
|
+
const response = typeof flowProvider.getAuthorizationResponse === "function" ? await flowProvider.getAuthorizationResponse() : { code: await flowProvider.getAuthorizationCode() };
|
|
3018
3071
|
await auth(provider, {
|
|
3019
3072
|
serverUrl,
|
|
3020
|
-
authorizationCode: code,
|
|
3073
|
+
authorizationCode: response.code,
|
|
3074
|
+
...response.iss !== void 0 ? { iss: response.iss } : {},
|
|
3021
3075
|
fetchFn
|
|
3022
3076
|
});
|
|
3023
3077
|
return;
|
|
@@ -3031,6 +3085,8 @@ async function waitForBrowserAuthComplete(provider, timeoutMs) {
|
|
|
3031
3085
|
);
|
|
3032
3086
|
}
|
|
3033
3087
|
if (provider.useRedirectFlow) {
|
|
3088
|
+
await new Promise(() => {
|
|
3089
|
+
});
|
|
3034
3090
|
return;
|
|
3035
3091
|
}
|
|
3036
3092
|
const tokensKey = provider.getKey?.("tokens");
|
|
@@ -3047,25 +3103,29 @@ async function waitForBrowserAuthComplete(provider, timeoutMs) {
|
|
|
3047
3103
|
} catch {
|
|
3048
3104
|
}
|
|
3049
3105
|
}
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3106
|
+
try {
|
|
3107
|
+
const result = await runAuthPopup({
|
|
3108
|
+
popup: null,
|
|
3109
|
+
state,
|
|
3110
|
+
tokensKey,
|
|
3111
|
+
timeoutMs
|
|
3112
|
+
});
|
|
3113
|
+
switch (result.kind) {
|
|
3114
|
+
case "success":
|
|
3115
|
+
return;
|
|
3116
|
+
case "cancelled":
|
|
3117
|
+
throw new Error("OAuth authentication was cancelled.");
|
|
3118
|
+
case "timeout":
|
|
3119
|
+
throw new Error(
|
|
3120
|
+
`OAuth callback not received within ${timeoutMs}ms. Ensure /oauth/callback calls onMcpAuthorization().`
|
|
3121
|
+
);
|
|
3122
|
+
case "error":
|
|
3123
|
+
throw new Error(result.error);
|
|
3124
|
+
default:
|
|
3125
|
+
throw new Error("Unexpected OAuth popup result");
|
|
3126
|
+
}
|
|
3127
|
+
} finally {
|
|
3128
|
+
provider.markFlowComplete?.();
|
|
3069
3129
|
}
|
|
3070
3130
|
}
|
|
3071
3131
|
|
|
@@ -4544,6 +4604,16 @@ function useMcpOperations(params) {
|
|
|
4544
4604
|
};
|
|
4545
4605
|
}
|
|
4546
4606
|
|
|
4607
|
+
// src/react/token-expiry.ts
|
|
4608
|
+
function getOAuthTokenExpiry(tokens) {
|
|
4609
|
+
try {
|
|
4610
|
+
const payload = JSON.parse(atob(tokens.access_token?.split(".")[1] ?? ""));
|
|
4611
|
+
if (typeof payload.exp === "number") return payload.exp * 1e3;
|
|
4612
|
+
} catch {
|
|
4613
|
+
}
|
|
4614
|
+
return typeof tokens.expires_in === "number" ? Date.now() + tokens.expires_in * 1e3 : void 0;
|
|
4615
|
+
}
|
|
4616
|
+
|
|
4547
4617
|
// src/react/useMcp.ts
|
|
4548
4618
|
var DEFAULT_RECONNECT_DELAY = 3e3;
|
|
4549
4619
|
var DEFAULT_RETRY_DELAY = 5e3;
|
|
@@ -5257,7 +5327,7 @@ function useMcp(options) {
|
|
|
5257
5327
|
return "failed";
|
|
5258
5328
|
}
|
|
5259
5329
|
if (tokens?.access_token) {
|
|
5260
|
-
const expiresAt = tokens
|
|
5330
|
+
const expiresAt = getOAuthTokenExpiry(tokens);
|
|
5261
5331
|
let tokenEndpoint = null;
|
|
5262
5332
|
let resource = null;
|
|
5263
5333
|
let clientCreds = null;
|
|
@@ -5367,8 +5437,10 @@ function useMcp(options) {
|
|
|
5367
5437
|
fetchFn: authProviderRef.current.getProxyFetch?.()
|
|
5368
5438
|
});
|
|
5369
5439
|
if (authResult === "REDIRECT") {
|
|
5370
|
-
const
|
|
5371
|
-
|
|
5440
|
+
const flowProvider = authProviderRef.current;
|
|
5441
|
+
const authResponse = await flowProvider.getAuthorizationResponse?.();
|
|
5442
|
+
const authCode = authResponse?.code ?? await flowProvider.getAuthorizationCode?.();
|
|
5443
|
+
if (typeof authCode !== "string") {
|
|
5372
5444
|
throw new Error(
|
|
5373
5445
|
"Authorization code not captured by headless provider"
|
|
5374
5446
|
);
|
|
@@ -5376,6 +5448,7 @@ function useMcp(options) {
|
|
|
5376
5448
|
await auth2(authProviderRef.current, {
|
|
5377
5449
|
serverUrl: url,
|
|
5378
5450
|
authorizationCode: authCode,
|
|
5451
|
+
...authResponse?.iss !== void 0 ? { iss: authResponse.iss } : {},
|
|
5379
5452
|
fetchFn: authProviderRef.current.getProxyFetch?.()
|
|
5380
5453
|
});
|
|
5381
5454
|
}
|
|
@@ -5970,20 +6043,14 @@ function renderResult(title, message, error, returnUrl) {
|
|
|
5970
6043
|
}
|
|
5971
6044
|
document.body.appendChild(container);
|
|
5972
6045
|
}
|
|
5973
|
-
function findStoredState(state) {
|
|
5974
|
-
const
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
key = candidate;
|
|
5982
|
-
break;
|
|
5983
|
-
}
|
|
5984
|
-
}
|
|
5985
|
-
}
|
|
5986
|
-
const serialized = key ? localStorage.getItem(key) : null;
|
|
6046
|
+
async function findStoredState(state) {
|
|
6047
|
+
const store = new LocalStorageKVStore();
|
|
6048
|
+
const legacySuffix = `:state_${state}`;
|
|
6049
|
+
const scopedSuffix = `_state_${state}`;
|
|
6050
|
+
const key = (await store.keys()).find(
|
|
6051
|
+
(candidate) => candidate.endsWith(legacySuffix) || candidate.endsWith(scopedSuffix)
|
|
6052
|
+
);
|
|
6053
|
+
const serialized = key ? await store.get(key) : null;
|
|
5987
6054
|
if (!key || !serialized) {
|
|
5988
6055
|
throw new Error(`Invalid or expired OAuth state "${state}".`);
|
|
5989
6056
|
}
|
|
@@ -5991,10 +6058,10 @@ function findStoredState(state) {
|
|
|
5991
6058
|
try {
|
|
5992
6059
|
value = JSON.parse(serialized);
|
|
5993
6060
|
} catch {
|
|
5994
|
-
|
|
6061
|
+
await store.remove(key);
|
|
5995
6062
|
throw new Error("Failed to parse stored OAuth state.");
|
|
5996
6063
|
}
|
|
5997
|
-
return { key, value };
|
|
6064
|
+
return { key, value, store };
|
|
5998
6065
|
}
|
|
5999
6066
|
function redirectWithError(returnUrl, message) {
|
|
6000
6067
|
const url = new URL(returnUrl);
|
|
@@ -6053,17 +6120,19 @@ async function completeAuthorization() {
|
|
|
6053
6120
|
const callbackParams = new URLSearchParams(window.location.search);
|
|
6054
6121
|
const state = callbackParams.get("state");
|
|
6055
6122
|
let stateKey = null;
|
|
6123
|
+
let stateStore = null;
|
|
6056
6124
|
let storedState = null;
|
|
6057
6125
|
let provider = null;
|
|
6058
6126
|
try {
|
|
6059
6127
|
if (!state) {
|
|
6060
6128
|
throw new Error("OAuth callback is missing the state parameter.");
|
|
6061
6129
|
}
|
|
6062
|
-
const stored = findStoredState(state);
|
|
6130
|
+
const stored = await findStoredState(state);
|
|
6063
6131
|
stateKey = stored.key;
|
|
6132
|
+
stateStore = stored.store;
|
|
6064
6133
|
storedState = stored.value;
|
|
6065
6134
|
if (!storedState.expiry || storedState.expiry < Date.now()) {
|
|
6066
|
-
|
|
6135
|
+
await stateStore.remove(stateKey);
|
|
6067
6136
|
throw new Error(
|
|
6068
6137
|
"OAuth state has expired. Please start authentication again."
|
|
6069
6138
|
);
|
|
@@ -6078,7 +6147,7 @@ async function completeAuthorization() {
|
|
|
6078
6147
|
fetch: provider.getProxyFetch()
|
|
6079
6148
|
});
|
|
6080
6149
|
await transport.finishAuth(callbackParams);
|
|
6081
|
-
|
|
6150
|
+
await stateStore.remove(stateKey);
|
|
6082
6151
|
signalResult(true, void 0, storedState, {
|
|
6083
6152
|
state,
|
|
6084
6153
|
serverUrlHash: storedState.serverUrlHash
|
|
@@ -6086,8 +6155,12 @@ async function completeAuthorization() {
|
|
|
6086
6155
|
} catch (error) {
|
|
6087
6156
|
const message = error instanceof Error ? error.message : String(error);
|
|
6088
6157
|
console.error("[mcp-callback] OAuth callback failed:", error);
|
|
6089
|
-
if (stateKey)
|
|
6090
|
-
if (provider)
|
|
6158
|
+
if (stateKey && stateStore) await stateStore.remove(stateKey);
|
|
6159
|
+
if (provider) {
|
|
6160
|
+
await (stateStore ?? new LocalStorageKVStore()).remove(
|
|
6161
|
+
provider.getKey("last_auth_url")
|
|
6162
|
+
);
|
|
6163
|
+
}
|
|
6091
6164
|
signalResult(false, message, storedState, {
|
|
6092
6165
|
state,
|
|
6093
6166
|
serverUrlHash: storedState?.serverUrlHash
|
|
@@ -6963,7 +7036,13 @@ var LocalStorageProvider = class {
|
|
|
6963
7036
|
);
|
|
6964
7037
|
const serialized = JSON.stringify(sanitized);
|
|
6965
7038
|
if (serialized !== stored) {
|
|
6966
|
-
|
|
7039
|
+
try {
|
|
7040
|
+
localStorage.setItem(this.storageKey, serialized);
|
|
7041
|
+
} catch {
|
|
7042
|
+
console.error(
|
|
7043
|
+
"[LocalStorageProvider] Failed to persist sanitized servers."
|
|
7044
|
+
);
|
|
7045
|
+
}
|
|
6967
7046
|
}
|
|
6968
7047
|
return sanitized;
|
|
6969
7048
|
} catch {
|
|
@@ -7158,8 +7237,20 @@ function findOpeningConstructEnd(html, lowercasePrefix) {
|
|
|
7158
7237
|
if (start === -1) return void 0;
|
|
7159
7238
|
const boundary = lowercaseHtml[start + lowercasePrefix.length];
|
|
7160
7239
|
if (boundary === ">" || boundary === " " || boundary === " " || boundary === "\n" || boundary === "\r" || boundary === "\f") {
|
|
7161
|
-
|
|
7162
|
-
|
|
7240
|
+
let quote;
|
|
7241
|
+
for (let index = start + lowercasePrefix.length; index < html.length; index++) {
|
|
7242
|
+
const character = html[index];
|
|
7243
|
+
if (quote) {
|
|
7244
|
+
if (character === quote) quote = void 0;
|
|
7245
|
+
continue;
|
|
7246
|
+
}
|
|
7247
|
+
if (character === '"' || character === "'") {
|
|
7248
|
+
quote = character;
|
|
7249
|
+
continue;
|
|
7250
|
+
}
|
|
7251
|
+
if (character === ">") return index + 1;
|
|
7252
|
+
}
|
|
7253
|
+
return void 0;
|
|
7163
7254
|
}
|
|
7164
7255
|
searchFrom = start + lowercasePrefix.length;
|
|
7165
7256
|
}
|
|
@@ -7216,6 +7307,11 @@ function resolveViewResource(options) {
|
|
|
7216
7307
|
}
|
|
7217
7308
|
|
|
7218
7309
|
// src/react/view/sandbox-blob-url.ts
|
|
7310
|
+
function buildViewSandboxUrl(sandboxDocumentUrl, options) {
|
|
7311
|
+
const url = new URL(sandboxDocumentUrl.href);
|
|
7312
|
+
applySandboxSearchParams(url, options);
|
|
7313
|
+
return url;
|
|
7314
|
+
}
|
|
7219
7315
|
function applySandboxSearchParams(url, options) {
|
|
7220
7316
|
const { cspMode, permissions, widgetCsp } = options;
|
|
7221
7317
|
url.searchParams.set(
|
|
@@ -7582,6 +7678,67 @@ var VIEW_DIMENSIONS = {
|
|
|
7582
7678
|
FULLSCREEN_HEADER_HEIGHT: 50
|
|
7583
7679
|
};
|
|
7584
7680
|
|
|
7681
|
+
// src/react/view/view-host-policy.ts
|
|
7682
|
+
function buildDefaultHostCapabilities({
|
|
7683
|
+
hasConnection,
|
|
7684
|
+
hasMessageHandler,
|
|
7685
|
+
hasModelContextHandler,
|
|
7686
|
+
hasLogHandler,
|
|
7687
|
+
hasSamplingHandler,
|
|
7688
|
+
hasDownloadHandler,
|
|
7689
|
+
messageCapabilities,
|
|
7690
|
+
modelContextCapabilities
|
|
7691
|
+
}) {
|
|
7692
|
+
return {
|
|
7693
|
+
openLinks: {},
|
|
7694
|
+
...hasConnection ? {
|
|
7695
|
+
serverTools: {},
|
|
7696
|
+
serverResources: {}
|
|
7697
|
+
} : {},
|
|
7698
|
+
...hasLogHandler ? { logging: {} } : {},
|
|
7699
|
+
...hasSamplingHandler ? { sampling: {} } : {},
|
|
7700
|
+
...hasDownloadHandler ? { downloadFile: {} } : {},
|
|
7701
|
+
...hasModelContextHandler ? { updateModelContext: modelContextCapabilities ?? { text: {} } } : {},
|
|
7702
|
+
...hasMessageHandler ? { message: messageCapabilities ?? { text: {} } } : {}
|
|
7703
|
+
};
|
|
7704
|
+
}
|
|
7705
|
+
function isToolVisibleToModel(tool) {
|
|
7706
|
+
if (!tool._meta || typeof tool._meta !== "object") return true;
|
|
7707
|
+
const ui = tool._meta.ui;
|
|
7708
|
+
if (!ui || typeof ui !== "object") return true;
|
|
7709
|
+
const visibility = ui.visibility;
|
|
7710
|
+
return !Array.isArray(visibility) || visibility.some((value) => value === "model");
|
|
7711
|
+
}
|
|
7712
|
+
async function dispatchUiMessage(handler, content) {
|
|
7713
|
+
if (!handler) {
|
|
7714
|
+
throw new Error("This host surface does not support ui/message");
|
|
7715
|
+
}
|
|
7716
|
+
if (content.length === 0) {
|
|
7717
|
+
throw new Error("ui/message requires at least one content block");
|
|
7718
|
+
}
|
|
7719
|
+
await handler(content);
|
|
7720
|
+
}
|
|
7721
|
+
function resolveRequestedDisplayMode({
|
|
7722
|
+
requested,
|
|
7723
|
+
current,
|
|
7724
|
+
hostAvailable,
|
|
7725
|
+
appAvailable
|
|
7726
|
+
}) {
|
|
7727
|
+
const hostModes = hostAvailable ?? ["inline"];
|
|
7728
|
+
const appModes = appAvailable ?? ["inline"];
|
|
7729
|
+
return hostModes.includes(requested) && appModes.includes(requested) ? requested : current;
|
|
7730
|
+
}
|
|
7731
|
+
function assertAppCanCallTool(tools, name) {
|
|
7732
|
+
const tool = tools?.find((candidate) => candidate.name === name);
|
|
7733
|
+
if (!tool) {
|
|
7734
|
+
throw new Error(`Tool "${name}" is not available to this app`);
|
|
7735
|
+
}
|
|
7736
|
+
const visibility = tool._meta?.ui?.visibility;
|
|
7737
|
+
if (visibility && !visibility.includes("app")) {
|
|
7738
|
+
throw new Error(`Tool "${name}" is not available to this app`);
|
|
7739
|
+
}
|
|
7740
|
+
}
|
|
7741
|
+
|
|
7585
7742
|
// src/react/view/view-detection.ts
|
|
7586
7743
|
function getViewResourceUri(toolMeta) {
|
|
7587
7744
|
const uri = toolMeta?.ui;
|
|
@@ -7601,15 +7758,6 @@ function isViewResource(mimeType) {
|
|
|
7601
7758
|
var DEFAULT_HOST_INFO = { name: "mcp-use-client", version: "2.0.0" };
|
|
7602
7759
|
var DEFAULT_TOOL_CALL_TIMEOUT = 6e5;
|
|
7603
7760
|
var SANDBOX_PROXY_READY = "ui/notifications/sandbox-proxy-ready";
|
|
7604
|
-
var DEFAULT_HOST_CAPABILITIES = {
|
|
7605
|
-
openLinks: {},
|
|
7606
|
-
serverTools: {},
|
|
7607
|
-
serverResources: {},
|
|
7608
|
-
logging: {},
|
|
7609
|
-
updateModelContext: { text: {} },
|
|
7610
|
-
// ponytail: always advertised; bridge.onmessage no-ops when onMessage unset
|
|
7611
|
-
message: { text: {} }
|
|
7612
|
-
};
|
|
7613
7761
|
function CloseIcon() {
|
|
7614
7762
|
return /* @__PURE__ */ React2.createElement(
|
|
7615
7763
|
"svg",
|
|
@@ -7673,12 +7821,17 @@ function ViewRendererBase({
|
|
|
7673
7821
|
hostInfo = DEFAULT_HOST_INFO,
|
|
7674
7822
|
hostContext,
|
|
7675
7823
|
hostCapabilities,
|
|
7824
|
+
messageCapabilities,
|
|
7825
|
+
modelContextCapabilities,
|
|
7676
7826
|
cspMode = "widget-declared",
|
|
7677
7827
|
displayMode: displayModeProp,
|
|
7678
7828
|
onDisplayModeChange,
|
|
7679
7829
|
inlineMaxWidth = 768,
|
|
7680
7830
|
chromeless,
|
|
7681
7831
|
onMessage,
|
|
7832
|
+
onSamplingRequest,
|
|
7833
|
+
onDownloadFile,
|
|
7834
|
+
onAppToolsChanged,
|
|
7682
7835
|
onModelContextUpdate,
|
|
7683
7836
|
onLog,
|
|
7684
7837
|
onReady,
|
|
@@ -7716,6 +7869,37 @@ function ViewRendererBase({
|
|
|
7716
7869
|
);
|
|
7717
7870
|
const [internalDisplayMode, setInternalDisplayMode] = useState4("inline");
|
|
7718
7871
|
const displayMode = displayModeProp ?? internalDisplayMode;
|
|
7872
|
+
const hasMessageHandler = onMessage !== void 0;
|
|
7873
|
+
const hasModelContextHandler = onModelContextUpdate !== void 0;
|
|
7874
|
+
const hasLogHandler = onLog !== void 0;
|
|
7875
|
+
const hasSamplingHandler = onSamplingRequest !== void 0;
|
|
7876
|
+
const hasDownloadHandler = onDownloadFile !== void 0;
|
|
7877
|
+
const effectiveHostCapabilities = useMemo3(
|
|
7878
|
+
() => ({
|
|
7879
|
+
...buildDefaultHostCapabilities({
|
|
7880
|
+
hasConnection: source.kind === "live",
|
|
7881
|
+
hasMessageHandler,
|
|
7882
|
+
hasModelContextHandler,
|
|
7883
|
+
hasLogHandler,
|
|
7884
|
+
hasSamplingHandler,
|
|
7885
|
+
hasDownloadHandler,
|
|
7886
|
+
messageCapabilities,
|
|
7887
|
+
modelContextCapabilities
|
|
7888
|
+
}),
|
|
7889
|
+
...hostCapabilities
|
|
7890
|
+
}),
|
|
7891
|
+
[
|
|
7892
|
+
hostCapabilities,
|
|
7893
|
+
hasLogHandler,
|
|
7894
|
+
hasSamplingHandler,
|
|
7895
|
+
hasDownloadHandler,
|
|
7896
|
+
hasMessageHandler,
|
|
7897
|
+
hasModelContextHandler,
|
|
7898
|
+
messageCapabilities,
|
|
7899
|
+
modelContextCapabilities,
|
|
7900
|
+
source.kind
|
|
7901
|
+
]
|
|
7902
|
+
);
|
|
7719
7903
|
const effectiveHostContext = useMemo3(() => {
|
|
7720
7904
|
if (!hostContext) return hostContext;
|
|
7721
7905
|
if (hostContext.displayMode === displayMode) return hostContext;
|
|
@@ -7725,6 +7909,12 @@ function ViewRendererBase({
|
|
|
7725
7909
|
hostContextRef.current = effectiveHostContext;
|
|
7726
7910
|
const onMessageRef = useRef4(onMessage);
|
|
7727
7911
|
onMessageRef.current = onMessage;
|
|
7912
|
+
const onSamplingRequestRef = useRef4(onSamplingRequest);
|
|
7913
|
+
onSamplingRequestRef.current = onSamplingRequest;
|
|
7914
|
+
const onDownloadFileRef = useRef4(onDownloadFile);
|
|
7915
|
+
onDownloadFileRef.current = onDownloadFile;
|
|
7916
|
+
const onAppToolsChangedRef = useRef4(onAppToolsChanged);
|
|
7917
|
+
onAppToolsChangedRef.current = onAppToolsChanged;
|
|
7728
7918
|
const toolInputRef = useRef4(toolInput);
|
|
7729
7919
|
toolInputRef.current = toolInput;
|
|
7730
7920
|
const partialToolInputRef = useRef4(partialToolInput);
|
|
@@ -7941,7 +8131,7 @@ function ViewRendererBase({
|
|
|
7941
8131
|
await readyPromise;
|
|
7942
8132
|
if (disposed) return;
|
|
7943
8133
|
const capabilities = {
|
|
7944
|
-
...
|
|
8134
|
+
...effectiveHostCapabilities,
|
|
7945
8135
|
sandbox: {
|
|
7946
8136
|
csp: cspMode === "permissive" ? void 0 : resolved.csp,
|
|
7947
8137
|
permissions: resolved.permissions
|
|
@@ -7950,75 +8140,110 @@ function ViewRendererBase({
|
|
|
7950
8140
|
bridge = new AppBridge(null, hostInfo, capabilities, {
|
|
7951
8141
|
hostContext: hostContextRef.current
|
|
7952
8142
|
});
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
onMessageRef.current
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
}
|
|
8143
|
+
if (capabilities.message) {
|
|
8144
|
+
bridge.onmessage = async ({
|
|
8145
|
+
content
|
|
8146
|
+
}) => {
|
|
8147
|
+
await dispatchUiMessage(onMessageRef.current, content);
|
|
8148
|
+
return {};
|
|
8149
|
+
};
|
|
8150
|
+
}
|
|
8151
|
+
if (capabilities.sampling) {
|
|
8152
|
+
bridge.oncreatesamplingmessage = async (params) => {
|
|
8153
|
+
const handler = onSamplingRequestRef.current;
|
|
8154
|
+
if (!handler) {
|
|
8155
|
+
throw new Error("This host surface does not support sampling");
|
|
8156
|
+
}
|
|
8157
|
+
return handler(params);
|
|
8158
|
+
};
|
|
8159
|
+
}
|
|
8160
|
+
if (capabilities.downloadFile) {
|
|
8161
|
+
bridge.ondownloadfile = async (params) => {
|
|
8162
|
+
const handler = onDownloadFileRef.current;
|
|
8163
|
+
if (!handler) {
|
|
8164
|
+
throw new Error("This host surface does not support downloads");
|
|
8165
|
+
}
|
|
8166
|
+
return handler(params);
|
|
8167
|
+
};
|
|
8168
|
+
}
|
|
7961
8169
|
bridge.onopenlink = async ({ url }) => {
|
|
7962
8170
|
if (url) window.open(url, "_blank", "noopener,noreferrer");
|
|
7963
8171
|
return {};
|
|
7964
8172
|
};
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
}
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
8173
|
+
if (capabilities.serverTools) {
|
|
8174
|
+
bridge.oncalltool = (async ({
|
|
8175
|
+
name,
|
|
8176
|
+
arguments: args
|
|
8177
|
+
}) => {
|
|
8178
|
+
const conn = connectionRef.current;
|
|
8179
|
+
if (!conn) throw new Error("Server connection not available");
|
|
8180
|
+
assertAppCanCallTool(conn.tools, name);
|
|
8181
|
+
try {
|
|
8182
|
+
return await conn.callTool(name, args || {}, {
|
|
8183
|
+
timeout: toolCallTimeout,
|
|
8184
|
+
resetTimeoutOnProgress: true
|
|
8185
|
+
});
|
|
8186
|
+
} catch (error) {
|
|
8187
|
+
bridge?.sendToolCancelled({
|
|
8188
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
8189
|
+
});
|
|
8190
|
+
throw error;
|
|
8191
|
+
}
|
|
8192
|
+
});
|
|
8193
|
+
}
|
|
8194
|
+
if (capabilities.serverResources) {
|
|
8195
|
+
bridge.onreadresource = (async ({
|
|
8196
|
+
uri
|
|
8197
|
+
}) => {
|
|
8198
|
+
const conn = connectionRef.current;
|
|
8199
|
+
if (!conn) throw new Error("Server connection not available");
|
|
8200
|
+
return await conn.readResource(uri);
|
|
8201
|
+
});
|
|
8202
|
+
bridge.onlistresources = (async () => {
|
|
8203
|
+
const conn = connectionRef.current;
|
|
8204
|
+
if (!conn) throw new Error("Server connection not available");
|
|
8205
|
+
return { resources: [...conn.resources ?? []] };
|
|
8206
|
+
});
|
|
8207
|
+
}
|
|
7995
8208
|
bridge.onrequestdisplaymode = async ({
|
|
7996
8209
|
mode
|
|
7997
8210
|
}) => {
|
|
7998
8211
|
const requested = mode ?? "inline";
|
|
7999
|
-
const
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8212
|
+
const effective = resolveRequestedDisplayMode({
|
|
8213
|
+
requested,
|
|
8214
|
+
current: displayModeRef.current,
|
|
8215
|
+
hostAvailable: hostContextRef.current?.availableDisplayModes,
|
|
8216
|
+
appAvailable: bridge?.getAppCapabilities()?.availableDisplayModes
|
|
8217
|
+
});
|
|
8005
8218
|
await handleDisplayModeChangeRef.current(effective);
|
|
8006
8219
|
return { mode: effective };
|
|
8007
8220
|
};
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8221
|
+
if (capabilities.updateModelContext) {
|
|
8222
|
+
bridge.onupdatemodelcontext = async ({
|
|
8223
|
+
content,
|
|
8224
|
+
structuredContent
|
|
8225
|
+
}) => {
|
|
8226
|
+
if (!onModelContextUpdateRef.current) {
|
|
8227
|
+
throw new Error(
|
|
8228
|
+
"This host surface does not support model context updates"
|
|
8229
|
+
);
|
|
8230
|
+
}
|
|
8231
|
+
await onModelContextUpdateRef.current({
|
|
8232
|
+
content,
|
|
8233
|
+
structuredContent
|
|
8234
|
+
});
|
|
8235
|
+
return {};
|
|
8236
|
+
};
|
|
8237
|
+
}
|
|
8238
|
+
if (capabilities.logging) {
|
|
8239
|
+
bridge.onloggingmessage = async ({
|
|
8240
|
+
level,
|
|
8241
|
+
data
|
|
8242
|
+
}) => {
|
|
8243
|
+
onLogRef.current?.({ level, data });
|
|
8244
|
+
return {};
|
|
8245
|
+
};
|
|
8246
|
+
}
|
|
8022
8247
|
bridge.onsizechange = async ({
|
|
8023
8248
|
height
|
|
8024
8249
|
}) => {
|
|
@@ -8028,6 +8253,35 @@ function ViewRendererBase({
|
|
|
8028
8253
|
onInlineHeightChangeRef.current?.(height);
|
|
8029
8254
|
}
|
|
8030
8255
|
};
|
|
8256
|
+
let publishedAppToolsSignature = null;
|
|
8257
|
+
const publishAppTools = async () => {
|
|
8258
|
+
const handler = onAppToolsChangedRef.current;
|
|
8259
|
+
if (!bridge || !handler) return;
|
|
8260
|
+
const appCapabilities = bridge.getAppCapabilities();
|
|
8261
|
+
if (!appCapabilities?.tools) {
|
|
8262
|
+
handler(null);
|
|
8263
|
+
return;
|
|
8264
|
+
}
|
|
8265
|
+
const result = await bridge.listTools({});
|
|
8266
|
+
if (disposed || !bridge) return;
|
|
8267
|
+
const signature = JSON.stringify(result.tools);
|
|
8268
|
+
if (signature === publishedAppToolsSignature) return;
|
|
8269
|
+
publishedAppToolsSignature = signature;
|
|
8270
|
+
const currentBridge = bridge;
|
|
8271
|
+
handler({
|
|
8272
|
+
tools: result.tools,
|
|
8273
|
+
callTool: (name, args) => currentBridge.callTool({
|
|
8274
|
+
name,
|
|
8275
|
+
arguments: args ?? {}
|
|
8276
|
+
})
|
|
8277
|
+
});
|
|
8278
|
+
};
|
|
8279
|
+
bridge.setNotificationHandler(
|
|
8280
|
+
"notifications/tools/list_changed",
|
|
8281
|
+
async () => {
|
|
8282
|
+
await publishAppTools();
|
|
8283
|
+
}
|
|
8284
|
+
);
|
|
8031
8285
|
const initPromise = hookInitialized(bridge);
|
|
8032
8286
|
let transport = new PostMessageTransport(
|
|
8033
8287
|
iframe.contentWindow,
|
|
@@ -8048,9 +8302,11 @@ function ViewRendererBase({
|
|
|
8048
8302
|
bridgeRef.current = bridge;
|
|
8049
8303
|
setInitCount((c) => c + 1);
|
|
8050
8304
|
onLifecycleChangeRef.current?.({ status: "initialized" });
|
|
8305
|
+
await publishAppTools();
|
|
8051
8306
|
const currentPartialToolInput = partialToolInputRef.current;
|
|
8052
|
-
|
|
8053
|
-
|
|
8307
|
+
const hasCompletedToolResult = toolOutputRef.current !== void 0 && toolOutputRef.current !== null;
|
|
8308
|
+
if (currentPartialToolInput && !hasCompletedToolResult) {
|
|
8309
|
+
await bridge.sendToolInputPartial({
|
|
8054
8310
|
arguments: currentPartialToolInput
|
|
8055
8311
|
});
|
|
8056
8312
|
} else {
|
|
@@ -8058,14 +8314,14 @@ function ViewRendererBase({
|
|
|
8058
8314
|
...toolInputRef.current,
|
|
8059
8315
|
...parseCustomProps(customPropsRef.current)
|
|
8060
8316
|
};
|
|
8061
|
-
bridge.sendToolInput({ arguments: mergedArgs });
|
|
8317
|
+
await bridge.sendToolInput({ arguments: mergedArgs });
|
|
8062
8318
|
}
|
|
8063
8319
|
const toolResultPayload = buildToolResultPayload(
|
|
8064
8320
|
toolOutputRef.current,
|
|
8065
8321
|
customPropsRef.current
|
|
8066
8322
|
);
|
|
8067
8323
|
if (toolResultPayload) {
|
|
8068
|
-
bridge.sendToolResult(toolResultPayload);
|
|
8324
|
+
await bridge.sendToolResult(toolResultPayload);
|
|
8069
8325
|
}
|
|
8070
8326
|
onLifecycleChangeRef.current?.({ status: "ready" });
|
|
8071
8327
|
} catch (err) {
|
|
@@ -8082,6 +8338,7 @@ function ViewRendererBase({
|
|
|
8082
8338
|
disposed = true;
|
|
8083
8339
|
const toClose = bridge;
|
|
8084
8340
|
bridgeRef.current = null;
|
|
8341
|
+
onAppToolsChangedRef.current?.(null);
|
|
8085
8342
|
if (!toClose) return;
|
|
8086
8343
|
onLifecycleChangeRef.current?.({ status: "tearing-down" });
|
|
8087
8344
|
void (async () => {
|
|
@@ -8104,7 +8361,7 @@ function ViewRendererBase({
|
|
|
8104
8361
|
resolved,
|
|
8105
8362
|
activeSandboxUrl,
|
|
8106
8363
|
hostInfo,
|
|
8107
|
-
|
|
8364
|
+
effectiveHostCapabilities,
|
|
8108
8365
|
cspMode,
|
|
8109
8366
|
viewId,
|
|
8110
8367
|
wrapTransport,
|
|
@@ -8114,33 +8371,37 @@ function ViewRendererBase({
|
|
|
8114
8371
|
useEffect5(() => {
|
|
8115
8372
|
const bridge = bridgeRef.current;
|
|
8116
8373
|
if (!bridge || initCount === 0 || !effectiveHostContext) return;
|
|
8117
|
-
bridge.setHostContext(effectiveHostContext);
|
|
8374
|
+
void bridge.setHostContext(effectiveHostContext);
|
|
8118
8375
|
}, [effectiveHostContext, initCount]);
|
|
8119
8376
|
useEffect5(() => {
|
|
8120
8377
|
const bridge = bridgeRef.current;
|
|
8121
|
-
if (!bridge || initCount === 0 || !partialToolInput)
|
|
8122
|
-
|
|
8123
|
-
|
|
8378
|
+
if (!bridge || initCount === 0 || !partialToolInput || toolOutput !== void 0 && toolOutput !== null) {
|
|
8379
|
+
return;
|
|
8380
|
+
}
|
|
8381
|
+
void bridge.sendToolInputPartial({ arguments: partialToolInput });
|
|
8382
|
+
}, [initCount, partialToolInput, toolOutput]);
|
|
8124
8383
|
useEffect5(() => {
|
|
8125
8384
|
const bridge = bridgeRef.current;
|
|
8126
|
-
if (!bridge || initCount === 0 || partialToolInput)
|
|
8385
|
+
if (!bridge || initCount === 0 || partialToolInput && (toolOutput === void 0 || toolOutput === null)) {
|
|
8386
|
+
return;
|
|
8387
|
+
}
|
|
8127
8388
|
const mergedArgs = {
|
|
8128
8389
|
...toolInput,
|
|
8129
8390
|
...parseCustomProps(customProps)
|
|
8130
8391
|
};
|
|
8131
|
-
bridge.sendToolInput({ arguments: mergedArgs });
|
|
8132
|
-
}, [initCount, toolInput, partialToolInput, customProps]);
|
|
8392
|
+
void bridge.sendToolInput({ arguments: mergedArgs });
|
|
8393
|
+
}, [initCount, toolInput, partialToolInput, customProps, toolOutput]);
|
|
8133
8394
|
useEffect5(() => {
|
|
8134
8395
|
const bridge = bridgeRef.current;
|
|
8135
8396
|
if (!bridge || initCount === 0) return;
|
|
8136
8397
|
const toolResultPayload = buildToolResultPayload(toolOutput, customProps);
|
|
8137
8398
|
if (!toolResultPayload) return;
|
|
8138
|
-
bridge.sendToolResult(toolResultPayload);
|
|
8399
|
+
void bridge.sendToolResult(toolResultPayload);
|
|
8139
8400
|
}, [initCount, toolOutput, customProps]);
|
|
8140
8401
|
useEffect5(() => {
|
|
8141
8402
|
const bridge = bridgeRef.current;
|
|
8142
8403
|
if (!bridge || initCount === 0 || !cancelled) return;
|
|
8143
|
-
bridge.sendToolCancelled({ reason: "Cancelled by user" });
|
|
8404
|
+
void bridge.sendToolCancelled({ reason: "Cancelled by user" });
|
|
8144
8405
|
}, [cancelled, initCount]);
|
|
8145
8406
|
const readyFiredRef = useRef4(false);
|
|
8146
8407
|
useEffect5(() => {
|
|
@@ -8270,6 +8531,14 @@ function viewRendererAreEqual(prev, next) {
|
|
|
8270
8531
|
if (prev.customProps !== next.customProps) return false;
|
|
8271
8532
|
if (prev.hostContext !== next.hostContext) return false;
|
|
8272
8533
|
if (prev.hostCapabilities !== next.hostCapabilities) return false;
|
|
8534
|
+
if (prev.messageCapabilities !== next.messageCapabilities) return false;
|
|
8535
|
+
if (prev.modelContextCapabilities !== next.modelContextCapabilities)
|
|
8536
|
+
return false;
|
|
8537
|
+
if (prev.onMessage !== next.onMessage) return false;
|
|
8538
|
+
if (prev.onSamplingRequest !== next.onSamplingRequest) return false;
|
|
8539
|
+
if (prev.onDownloadFile !== next.onDownloadFile) return false;
|
|
8540
|
+
if (prev.onAppToolsChanged !== next.onAppToolsChanged) return false;
|
|
8541
|
+
if (prev.onModelContextUpdate !== next.onModelContextUpdate) return false;
|
|
8273
8542
|
if (prev.cspMode !== next.cspMode) return false;
|
|
8274
8543
|
if (prev.mockOpenAiFileApis !== next.mockOpenAiFileApis) return false;
|
|
8275
8544
|
if (prev.onInlineHeightChange !== next.onInlineHeightChange) return false;
|
|
@@ -8288,12 +8557,15 @@ export {
|
|
|
8288
8557
|
Tel,
|
|
8289
8558
|
Telemetry,
|
|
8290
8559
|
ViewRenderer,
|
|
8560
|
+
buildSandboxProxyBlobHtml,
|
|
8291
8561
|
buildViewSandboxBlobUrl,
|
|
8562
|
+
buildViewSandboxUrl,
|
|
8292
8563
|
clearRpcLogs,
|
|
8293
8564
|
detectFavicon,
|
|
8294
8565
|
getAllRpcLogs,
|
|
8295
8566
|
getRpcLogs,
|
|
8296
8567
|
getViewResourceUri,
|
|
8568
|
+
isToolVisibleToModel,
|
|
8297
8569
|
isViewResource,
|
|
8298
8570
|
isViewTool,
|
|
8299
8571
|
onMcpAuthorization,
|