@mcp-use/client 2.0.0-beta.1 → 2.0.0-beta.10
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/dist/.tsbuildinfo +1 -1
- package/dist/auth/browser.d.ts +8 -4
- package/dist/auth/browser.d.ts.map +1 -1
- package/dist/auth/session-store.d.ts +5 -0
- package/dist/auth/session-store.d.ts.map +1 -1
- package/dist/index-browser.d.ts +1 -1
- package/dist/index-browser.d.ts.map +1 -1
- package/dist/index-browser.js +49 -151
- 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 +22 -161
- package/dist/index.js.map +1 -1
- package/dist/react/index.js +294 -214
- package/dist/react/index.js.map +1 -1
- package/dist/react/types.d.ts +9 -3
- package/dist/react/types.d.ts.map +1 -1
- package/dist/react/useMcp-operations.d.ts.map +1 -1
- package/dist/react/useMcp.d.ts.map +1 -1
- package/dist/react/view/ViewRenderer.d.ts +2 -1
- package/dist/react/view/ViewRenderer.d.ts.map +1 -1
- package/dist/react/view/inject-openai-file-apis.d.ts +6 -0
- package/dist/react/view/inject-openai-file-apis.d.ts.map +1 -0
- package/dist/react/view/types.d.ts +16 -0
- package/dist/react/view/types.d.ts.map +1 -1
- package/dist/react/view/use-display-mode.d.ts +1 -0
- package/dist/react/view/use-display-mode.d.ts.map +1 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/tel-fetch.d.ts +0 -6
- package/dist/telemetry/tel-fetch.d.ts.map +1 -1
- package/dist/telemetry/telemetry-node.d.ts.map +1 -1
- package/dist/telemetry/telemetry.d.ts +0 -8
- package/dist/telemetry/telemetry.d.ts.map +1 -1
- package/dist/transport/http.d.ts +6 -6
- package/package.json +2 -2
package/dist/react/index.js
CHANGED
|
@@ -1473,7 +1473,7 @@ var HttpConnector = class extends BaseConnector {
|
|
|
1473
1473
|
};
|
|
1474
1474
|
|
|
1475
1475
|
// src/utils/version.ts
|
|
1476
|
-
var VERSION = "2.0.0-beta.
|
|
1476
|
+
var VERSION = "2.0.0-beta.9";
|
|
1477
1477
|
function getPackageVersion() {
|
|
1478
1478
|
return VERSION;
|
|
1479
1479
|
}
|
|
@@ -1849,6 +1849,14 @@ var OAuthSessionStore = class _OAuthSessionStore {
|
|
|
1849
1849
|
async getTokenEndpoint() {
|
|
1850
1850
|
return (await this.discoveryState())?.authorizationServerMetadata?.token_endpoint ?? null;
|
|
1851
1851
|
}
|
|
1852
|
+
/**
|
|
1853
|
+
* Return the protected-resource URL selected during OAuth discovery.
|
|
1854
|
+
* Consumers can persist it and reuse it for server-side refresh exchanges.
|
|
1855
|
+
*/
|
|
1856
|
+
async getResource() {
|
|
1857
|
+
const resource = (await this.discoveryState())?.resourceMetadata?.resource;
|
|
1858
|
+
return typeof resource === "string" ? resource : null;
|
|
1859
|
+
}
|
|
1852
1860
|
};
|
|
1853
1861
|
|
|
1854
1862
|
// src/auth/browser.ts
|
|
@@ -1966,20 +1974,19 @@ var BrowserOAuthClientProvider = class {
|
|
|
1966
1974
|
* therefore never alters fetch behavior for other servers, other
|
|
1967
1975
|
* connections, or the rest of the page.
|
|
1968
1976
|
*
|
|
1969
|
-
*
|
|
1970
|
-
*
|
|
1971
|
-
*
|
|
1972
|
-
*
|
|
1977
|
+
* OAuth metadata is always fetched with `cache: "no-store"`, including in
|
|
1978
|
+
* direct mode. Authorization servers commonly vary CORS headers by Origin;
|
|
1979
|
+
* bypassing the browser HTTP cache prevents a revalidated response cached
|
|
1980
|
+
* for another localhost origin from poisoning discovery. When OAuth proxying
|
|
1981
|
+
* is disabled or no `oauthProxyUrl` is configured, all requests still go
|
|
1982
|
+
* directly to their original URLs.
|
|
1973
1983
|
*
|
|
1974
1984
|
* @param baseFetch - The fetch used for non-OAuth requests and for the
|
|
1975
1985
|
* underlying proxy calls. Defaults to the global `fetch`.
|
|
1976
1986
|
*/
|
|
1977
1987
|
getProxyFetch(baseFetch) {
|
|
1978
|
-
if (!this.proxyOAuthRequests || !this.oauthProxyUrl) {
|
|
1979
|
-
return baseFetch;
|
|
1980
|
-
}
|
|
1981
1988
|
const base = baseFetch ?? globalThis.fetch.bind(globalThis);
|
|
1982
|
-
const oauthProxyUrl = this.oauthProxyUrl;
|
|
1989
|
+
const oauthProxyUrl = this.proxyOAuthRequests && this.oauthProxyUrl ? this.oauthProxyUrl : void 0;
|
|
1983
1990
|
const discoveredEndpoints = /* @__PURE__ */ new Set();
|
|
1984
1991
|
let restoredDiscovery = false;
|
|
1985
1992
|
return async (input, init) => {
|
|
@@ -1992,6 +1999,12 @@ var BrowserOAuthClientProvider = class {
|
|
|
1992
1999
|
return await base(input, init);
|
|
1993
2000
|
}
|
|
1994
2001
|
const isMetadata = pathname.includes("/.well-known/");
|
|
2002
|
+
if (!oauthProxyUrl) {
|
|
2003
|
+
return await base(
|
|
2004
|
+
isMetadata ? url : input,
|
|
2005
|
+
isMetadata ? { ...init, cache: "no-store" } : init
|
|
2006
|
+
);
|
|
2007
|
+
}
|
|
1995
2008
|
if (!restoredDiscovery) {
|
|
1996
2009
|
restoredDiscovery = true;
|
|
1997
2010
|
const metadata = (await this.discoveryState())?.authorizationServerMetadata;
|
|
@@ -2026,7 +2039,8 @@ var BrowserOAuthClientProvider = class {
|
|
|
2026
2039
|
if (isMetadata) {
|
|
2027
2040
|
const response2 = await base(proxyEndpoint, {
|
|
2028
2041
|
...init,
|
|
2029
|
-
method: "GET"
|
|
2042
|
+
method: "GET",
|
|
2043
|
+
cache: "no-store"
|
|
2030
2044
|
});
|
|
2031
2045
|
try {
|
|
2032
2046
|
const metadata = await response2.clone().json();
|
|
@@ -2083,7 +2097,16 @@ var BrowserOAuthClientProvider = class {
|
|
|
2083
2097
|
}
|
|
2084
2098
|
async saveClientInformation(clientInformation, ctx) {
|
|
2085
2099
|
if (this.staticClientInfo) return;
|
|
2086
|
-
|
|
2100
|
+
const { client_secret: discardedClientSecret, ...publicClientInformation } = clientInformation;
|
|
2101
|
+
if (discardedClientSecret) {
|
|
2102
|
+
console.info(
|
|
2103
|
+
`[${this.storageKeyPrefix}] Discarded client_secret returned for a public browser OAuth client.`
|
|
2104
|
+
);
|
|
2105
|
+
}
|
|
2106
|
+
return this.session.saveClientInformation(
|
|
2107
|
+
publicClientInformation,
|
|
2108
|
+
ctx
|
|
2109
|
+
);
|
|
2087
2110
|
}
|
|
2088
2111
|
codeVerifier() {
|
|
2089
2112
|
return this.session.codeVerifier();
|
|
@@ -2113,6 +2136,10 @@ var BrowserOAuthClientProvider = class {
|
|
|
2113
2136
|
getTokenEndpoint() {
|
|
2114
2137
|
return this.session.getTokenEndpoint();
|
|
2115
2138
|
}
|
|
2139
|
+
/** Return the protected-resource URL selected during OAuth discovery. */
|
|
2140
|
+
getResource() {
|
|
2141
|
+
return this.session.getResource();
|
|
2142
|
+
}
|
|
2116
2143
|
/**
|
|
2117
2144
|
* Return the stored public OAuth client ID. Browser providers do not retain
|
|
2118
2145
|
* client secrets.
|
|
@@ -2370,62 +2397,6 @@ async function telFetch(url, init) {
|
|
|
2370
2397
|
}
|
|
2371
2398
|
var POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
2372
2399
|
var POSTHOG_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
2373
|
-
var SCARF_GATEWAY_URL = "https://mcpuse.gateway.scarf.sh/events-ts";
|
|
2374
|
-
var SCARF_GATEWAY_BEACON_URL = "https://mcpuse.gateway.scarf.sh/simple/";
|
|
2375
|
-
var SCARF_BEACON_MAX_URL = 1800;
|
|
2376
|
-
var SCARF_BEACON_TRUNCATED_KEYS = /* @__PURE__ */ new Set(["query", "response", "messages"]);
|
|
2377
|
-
function stringifyScarfValue(value) {
|
|
2378
|
-
if (value === null || value === void 0) return "";
|
|
2379
|
-
if (typeof value === "string") return value;
|
|
2380
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
2381
|
-
return String(value);
|
|
2382
|
-
}
|
|
2383
|
-
try {
|
|
2384
|
-
return JSON.stringify(value);
|
|
2385
|
-
} catch {
|
|
2386
|
-
return String(value);
|
|
2387
|
-
}
|
|
2388
|
-
}
|
|
2389
|
-
function buildScarfBeaconUrl(properties, baseUrl = SCARF_GATEWAY_BEACON_URL) {
|
|
2390
|
-
const params = new URLSearchParams();
|
|
2391
|
-
for (const [key, value] of Object.entries(properties)) {
|
|
2392
|
-
let serialized = stringifyScarfValue(value);
|
|
2393
|
-
if (SCARF_BEACON_TRUNCATED_KEYS.has(key) && serialized.length > 120) {
|
|
2394
|
-
serialized = `${serialized.slice(0, 117)}...`;
|
|
2395
|
-
}
|
|
2396
|
-
if (serialized !== "") params.set(key, serialized);
|
|
2397
|
-
}
|
|
2398
|
-
let url = `${baseUrl}${baseUrl.includes("?") ? "&" : "?"}${params.toString()}`;
|
|
2399
|
-
if (url.length <= SCARF_BEACON_MAX_URL) return url;
|
|
2400
|
-
const keys = [...params.keys()].sort(
|
|
2401
|
-
(a, b) => (params.get(b)?.length ?? 0) - (params.get(a)?.length ?? 0)
|
|
2402
|
-
);
|
|
2403
|
-
for (const key of keys) {
|
|
2404
|
-
if (url.length <= SCARF_BEACON_MAX_URL) break;
|
|
2405
|
-
if (key === "event" || key === "user_id") continue;
|
|
2406
|
-
params.delete(key);
|
|
2407
|
-
url = `${baseUrl}${baseUrl.includes("?") ? "&" : "?"}${params.toString()}`;
|
|
2408
|
-
}
|
|
2409
|
-
return url.slice(0, SCARF_BEACON_MAX_URL);
|
|
2410
|
-
}
|
|
2411
|
-
function captureScarfPost(properties, endpoint) {
|
|
2412
|
-
return telFetch(endpoint, {
|
|
2413
|
-
method: "POST",
|
|
2414
|
-
headers: { "Content-Type": "application/json" },
|
|
2415
|
-
keepalive: true,
|
|
2416
|
-
body: JSON.stringify(properties)
|
|
2417
|
-
});
|
|
2418
|
-
}
|
|
2419
|
-
function captureScarfBeacon(properties, endpoint) {
|
|
2420
|
-
try {
|
|
2421
|
-
const url = buildScarfBeaconUrl(properties, endpoint);
|
|
2422
|
-
const img = new Image();
|
|
2423
|
-
img.referrerPolicy = "no-referrer-when-downgrade";
|
|
2424
|
-
img.src = url;
|
|
2425
|
-
} catch {
|
|
2426
|
-
}
|
|
2427
|
-
return Promise.resolve();
|
|
2428
|
-
}
|
|
2429
2400
|
function capturePostHog(params) {
|
|
2430
2401
|
const host = params.host ?? POSTHOG_HOST;
|
|
2431
2402
|
const apiKey = params.apiKey ?? POSTHOG_API_KEY;
|
|
@@ -2442,13 +2413,6 @@ function capturePostHog(params) {
|
|
|
2442
2413
|
})
|
|
2443
2414
|
});
|
|
2444
2415
|
}
|
|
2445
|
-
function captureScarf(properties, endpoint = SCARF_GATEWAY_URL) {
|
|
2446
|
-
if (typeof window !== "undefined") {
|
|
2447
|
-
const beaconEndpoint = endpoint === SCARF_GATEWAY_URL ? SCARF_GATEWAY_BEACON_URL : endpoint;
|
|
2448
|
-
return captureScarfBeacon(properties, beaconEndpoint);
|
|
2449
|
-
}
|
|
2450
|
-
return captureScarfPost(properties, endpoint);
|
|
2451
|
-
}
|
|
2452
2416
|
|
|
2453
2417
|
// src/telemetry/telemetry.ts
|
|
2454
2418
|
function generateUUID() {
|
|
@@ -2459,18 +2423,6 @@ function secureRandomString() {
|
|
|
2459
2423
|
globalThis.crypto.getRandomValues(array);
|
|
2460
2424
|
return Array.from(array, (v) => v.toString(16).padStart(2, "0")).join("");
|
|
2461
2425
|
}
|
|
2462
|
-
function isVersionGreater(a, b) {
|
|
2463
|
-
const parse = (v) => v.split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
|
|
2464
|
-
const pa = parse(a);
|
|
2465
|
-
const pb = parse(b);
|
|
2466
|
-
const len = Math.max(pa.length, pb.length);
|
|
2467
|
-
for (let i = 0; i < len; i++) {
|
|
2468
|
-
const da = pa[i] ?? 0;
|
|
2469
|
-
const db = pb[i] ?? 0;
|
|
2470
|
-
if (da !== db) return da > db;
|
|
2471
|
-
}
|
|
2472
|
-
return false;
|
|
2473
|
-
}
|
|
2474
2426
|
var USER_ID_STORAGE_KEY = "mcp_use_user_id";
|
|
2475
2427
|
var PROJECT_API_KEY = "phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI";
|
|
2476
2428
|
var HOST = "https://eu.i.posthog.com";
|
|
@@ -2499,10 +2451,7 @@ function createLocalStorageBackend() {
|
|
|
2499
2451
|
localStorage.setItem(USER_ID_STORAGE_KEY, id);
|
|
2500
2452
|
} catch {
|
|
2501
2453
|
}
|
|
2502
|
-
}
|
|
2503
|
-
// Package-download dedup is node/Scarf-oriented; localStorage unused.
|
|
2504
|
-
getDownloadedVersion: () => null,
|
|
2505
|
-
setDownloadedVersion: () => void 0
|
|
2454
|
+
}
|
|
2506
2455
|
};
|
|
2507
2456
|
}
|
|
2508
2457
|
function detectRuntimeEnvironment() {
|
|
@@ -2570,17 +2519,13 @@ var Telemetry = class _Telemetry {
|
|
|
2570
2519
|
_currUserId = null;
|
|
2571
2520
|
_telemetryEnabled = false;
|
|
2572
2521
|
_pending = /* @__PURE__ */ new Set();
|
|
2573
|
-
_scarfEnabled = false;
|
|
2574
2522
|
_runtimeEnvironment;
|
|
2575
2523
|
_storageCapability;
|
|
2576
2524
|
_storage;
|
|
2577
|
-
/** True when node entry installed fs storage (package-download dedup). */
|
|
2578
|
-
_fsBacked;
|
|
2579
2525
|
_source;
|
|
2580
2526
|
_productVersion;
|
|
2581
2527
|
constructor() {
|
|
2582
2528
|
this._runtimeEnvironment = detectRuntimeEnvironment();
|
|
2583
|
-
this._fsBacked = configuredStorage !== null;
|
|
2584
2529
|
this._storage = configuredStorage ?? createLocalStorageBackend() ?? null;
|
|
2585
2530
|
this._storageCapability = this._storage ? "persistent" : "session-only";
|
|
2586
2531
|
this._source = readSourceHint() || this._runtimeEnvironment;
|
|
@@ -2599,14 +2544,6 @@ var Telemetry = class _Telemetry {
|
|
|
2599
2544
|
"Anonymized telemetry enabled. Set MCP_USE_ANONYMIZED_TELEMETRY=false to disable."
|
|
2600
2545
|
);
|
|
2601
2546
|
this._telemetryEnabled = true;
|
|
2602
|
-
this._scarfEnabled = true;
|
|
2603
|
-
if (this._fsBacked) {
|
|
2604
|
-
setTimeout(() => {
|
|
2605
|
-
this.trackPackageDownload({ triggered_by: "initialization" }).catch(
|
|
2606
|
-
(e) => logger.debug(`Failed to track package download: ${e}`)
|
|
2607
|
-
);
|
|
2608
|
-
}, 0);
|
|
2609
|
-
}
|
|
2610
2547
|
}
|
|
2611
2548
|
}
|
|
2612
2549
|
get runtimeEnvironment() {
|
|
@@ -2638,7 +2575,7 @@ var Telemetry = class _Telemetry {
|
|
|
2638
2575
|
this._productVersion = version;
|
|
2639
2576
|
}
|
|
2640
2577
|
get isEnabled() {
|
|
2641
|
-
return this._telemetryEnabled
|
|
2578
|
+
return this._telemetryEnabled;
|
|
2642
2579
|
}
|
|
2643
2580
|
get userId() {
|
|
2644
2581
|
if (this._currUserId) return this._currUserId;
|
|
@@ -2661,7 +2598,7 @@ var Telemetry = class _Telemetry {
|
|
|
2661
2598
|
return this._currUserId;
|
|
2662
2599
|
}
|
|
2663
2600
|
async capture(event) {
|
|
2664
|
-
if (!this._telemetryEnabled
|
|
2601
|
+
if (!this._telemetryEnabled) return;
|
|
2665
2602
|
const currentUserId = this.userId;
|
|
2666
2603
|
const properties = {
|
|
2667
2604
|
...event.properties,
|
|
@@ -2670,52 +2607,15 @@ var Telemetry = class _Telemetry {
|
|
|
2670
2607
|
source: this._source,
|
|
2671
2608
|
runtime: this._runtimeEnvironment
|
|
2672
2609
|
};
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
properties
|
|
2680
|
-
});
|
|
2681
|
-
this._pending.add(p);
|
|
2682
|
-
void p.finally(() => this._pending.delete(p));
|
|
2683
|
-
}
|
|
2684
|
-
if (this._scarfEnabled) {
|
|
2685
|
-
const p = captureScarf({
|
|
2686
|
-
...properties,
|
|
2687
|
-
user_id: currentUserId,
|
|
2688
|
-
event: event.name
|
|
2689
|
-
});
|
|
2690
|
-
this._pending.add(p);
|
|
2691
|
-
void p.finally(() => this._pending.delete(p));
|
|
2692
|
-
}
|
|
2693
|
-
}
|
|
2694
|
-
async trackPackageDownload(properties) {
|
|
2695
|
-
if (!this._scarfEnabled || !this._fsBacked || !this._storage) return;
|
|
2696
|
-
const currentVersion = getPackageVersion();
|
|
2697
|
-
const saved = this._storage.getDownloadedVersion();
|
|
2698
|
-
let firstDownload = false;
|
|
2699
|
-
let shouldTrack = false;
|
|
2700
|
-
if (!saved) {
|
|
2701
|
-
shouldTrack = true;
|
|
2702
|
-
firstDownload = true;
|
|
2703
|
-
this._storage.setDownloadedVersion(currentVersion);
|
|
2704
|
-
} else if (isVersionGreater(currentVersion, saved)) {
|
|
2705
|
-
shouldTrack = true;
|
|
2706
|
-
this._storage.setDownloadedVersion(currentVersion);
|
|
2707
|
-
}
|
|
2708
|
-
if (!shouldTrack) return;
|
|
2709
|
-
await captureScarf({
|
|
2710
|
-
...properties || {},
|
|
2711
|
-
mcp_use_version: currentVersion,
|
|
2712
|
-
user_id: this.userId,
|
|
2713
|
-
event: "package_download",
|
|
2714
|
-
first_download: firstDownload,
|
|
2715
|
-
language: "typescript",
|
|
2716
|
-
source: this._source,
|
|
2717
|
-
runtime: this._runtimeEnvironment
|
|
2610
|
+
const p = capturePostHog({
|
|
2611
|
+
host: HOST,
|
|
2612
|
+
apiKey: PROJECT_API_KEY,
|
|
2613
|
+
event: event.name,
|
|
2614
|
+
distinctId: currentUserId,
|
|
2615
|
+
properties
|
|
2718
2616
|
});
|
|
2617
|
+
this._pending.add(p);
|
|
2618
|
+
void p.finally(() => this._pending.delete(p));
|
|
2719
2619
|
}
|
|
2720
2620
|
async trackAgentExecution(data) {
|
|
2721
2621
|
if (!this.isEnabled) return;
|
|
@@ -4384,6 +4284,7 @@ function useMcp(options) {
|
|
|
4384
4284
|
headers: headersOption,
|
|
4385
4285
|
proxyConfig,
|
|
4386
4286
|
oauthProxyUrl: oauthProxyUrlOption,
|
|
4287
|
+
connectionMode,
|
|
4387
4288
|
autoProxyFallback = false,
|
|
4388
4289
|
logLevel: logLevelOption = "silent",
|
|
4389
4290
|
autoRetry = false,
|
|
@@ -4407,6 +4308,7 @@ function useMcp(options) {
|
|
|
4407
4308
|
oauth: oauthOptions
|
|
4408
4309
|
} = options;
|
|
4409
4310
|
const transportType = "http";
|
|
4311
|
+
const requestedProxyAddress = proxyConfig?.proxyAddress;
|
|
4410
4312
|
const oauthClientId = oauthOptions?.clientId?.trim() || void 0;
|
|
4411
4313
|
const oauthClientMetadataUrl = oauthOptions?.clientMetadataUrl?.trim() || void 0;
|
|
4412
4314
|
const oauthScope = oauthOptions?.scope?.trim() || void 0;
|
|
@@ -4454,6 +4356,9 @@ function useMcp(options) {
|
|
|
4454
4356
|
);
|
|
4455
4357
|
const oauthClientConfig = derivedOAuthClientConfig;
|
|
4456
4358
|
const autoProxyFallbackConfig = useMemo(() => {
|
|
4359
|
+
if (connectionMode === "direct" || connectionMode === "proxy") {
|
|
4360
|
+
return { enabled: false, proxyAddress: void 0 };
|
|
4361
|
+
}
|
|
4457
4362
|
if (!autoProxyFallback) {
|
|
4458
4363
|
return { enabled: false, proxyAddress: void 0 };
|
|
4459
4364
|
}
|
|
@@ -4469,7 +4374,7 @@ function useMcp(options) {
|
|
|
4469
4374
|
enabled: autoProxyFallback.enabled !== false && Boolean(proxyAddress),
|
|
4470
4375
|
proxyAddress
|
|
4471
4376
|
};
|
|
4472
|
-
}, [autoProxyFallback, proxyConfig]);
|
|
4377
|
+
}, [autoProxyFallback, connectionMode, proxyConfig]);
|
|
4473
4378
|
const autoReconnectConfig = useMemo(() => {
|
|
4474
4379
|
if (autoReconnect === false) {
|
|
4475
4380
|
return {
|
|
@@ -4505,20 +4410,33 @@ function useMcp(options) {
|
|
|
4505
4410
|
const [effectiveProxyConfig, setEffectiveProxyConfig] = useState(void 0);
|
|
4506
4411
|
useEffect(() => {
|
|
4507
4412
|
setEffectiveProxyConfig(void 0);
|
|
4508
|
-
}, [
|
|
4413
|
+
}, [
|
|
4414
|
+
url,
|
|
4415
|
+
requestedProxyAddress,
|
|
4416
|
+
connectionMode,
|
|
4417
|
+
autoProxyFallbackConfig.proxyAddress
|
|
4418
|
+
]);
|
|
4509
4419
|
const activeProxyConfig = useMemo(() => {
|
|
4510
|
-
|
|
4511
|
-
|
|
4420
|
+
const hasCurrentAutoFallback = autoProxyFallbackConfig.enabled && effectiveProxyConfig?.proxyAddress === autoProxyFallbackConfig.proxyAddress;
|
|
4421
|
+
if (hasCurrentAutoFallback && effectiveProxyConfig) {
|
|
4422
|
+
const latestHeaders = proxyConfig?.headers ?? {};
|
|
4423
|
+
return {
|
|
4424
|
+
...effectiveProxyConfig,
|
|
4425
|
+
headers: {
|
|
4426
|
+
...latestHeaders,
|
|
4427
|
+
...effectiveProxyConfig.headers ?? {}
|
|
4428
|
+
}
|
|
4429
|
+
};
|
|
4512
4430
|
}
|
|
4513
|
-
const
|
|
4514
|
-
return
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4431
|
+
const startsDirect = connectionMode === "auto" || connectionMode === "direct" || connectionMode === void 0 && autoProxyFallbackConfig.enabled;
|
|
4432
|
+
return startsDirect ? void 0 : proxyConfig;
|
|
4433
|
+
}, [
|
|
4434
|
+
effectiveProxyConfig,
|
|
4435
|
+
proxyConfig,
|
|
4436
|
+
connectionMode,
|
|
4437
|
+
autoProxyFallbackConfig.enabled,
|
|
4438
|
+
autoProxyFallbackConfig.proxyAddress
|
|
4439
|
+
]);
|
|
4522
4440
|
const gatewayUrl = activeProxyConfig?.proxyAddress;
|
|
4523
4441
|
const proxyHeaders = activeProxyConfig?.headers ?? {};
|
|
4524
4442
|
const effectiveOAuthUrl = useMemo(() => {
|
|
@@ -4850,8 +4768,9 @@ function useMcp(options) {
|
|
|
4850
4768
|
clientInfo: mergedClientInfo,
|
|
4851
4769
|
// Pass a fetch that scopes OAuth-proxy routing to this server's
|
|
4852
4770
|
// transport/auth calls. getProxyFetch wraps `customFetch` (e.g. the
|
|
4853
|
-
// OAuth retry fetch for scope step-up)
|
|
4854
|
-
//
|
|
4771
|
+
// OAuth retry fetch for scope step-up), bypasses the browser cache
|
|
4772
|
+
// for OAuth metadata, and optionally routes OAuth through the BFF.
|
|
4773
|
+
// It never mutates the global fetch.
|
|
4855
4774
|
...(() => {
|
|
4856
4775
|
const scopedFetch = authProviderRef.current?.getProxyFetch?.(customFetch) ?? customFetch;
|
|
4857
4776
|
return scopedFetch ? { fetch: scopedFetch } : {};
|
|
@@ -5052,12 +4971,18 @@ function useMcp(options) {
|
|
|
5052
4971
|
if (tokens?.access_token) {
|
|
5053
4972
|
const expiresAt = tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : void 0;
|
|
5054
4973
|
let tokenEndpoint = null;
|
|
4974
|
+
let resource = null;
|
|
5055
4975
|
let clientCreds = null;
|
|
5056
4976
|
try {
|
|
5057
4977
|
tokenEndpoint = await authProviderRef.current.getTokenEndpoint?.() ?? null;
|
|
5058
4978
|
} catch {
|
|
5059
4979
|
tokenEndpoint = null;
|
|
5060
4980
|
}
|
|
4981
|
+
try {
|
|
4982
|
+
resource = await authProviderRef.current.getResource?.() ?? null;
|
|
4983
|
+
} catch {
|
|
4984
|
+
resource = null;
|
|
4985
|
+
}
|
|
5061
4986
|
try {
|
|
5062
4987
|
clientCreds = await authProviderRef.current.getClientCredentials?.() ?? null;
|
|
5063
4988
|
} catch {
|
|
@@ -5074,6 +4999,7 @@ function useMcp(options) {
|
|
|
5074
4999
|
refresh_token: tokens.refresh_token,
|
|
5075
5000
|
scope: tokens.scope,
|
|
5076
5001
|
...tokenEndpoint ? { token_endpoint: tokenEndpoint } : {},
|
|
5002
|
+
...resource ? { resource } : {},
|
|
5077
5003
|
...clientCreds?.client_id ? { client_id: clientCreds.client_id } : {},
|
|
5078
5004
|
...clientCreds?.client_secret ? { client_secret: clientCreds.client_secret } : {}
|
|
5079
5005
|
});
|
|
@@ -5318,19 +5244,20 @@ function useMcp(options) {
|
|
|
5318
5244
|
addLog("info", "Triggering fresh OAuth authorization...");
|
|
5319
5245
|
const parsedUrl = new URL(url);
|
|
5320
5246
|
const baseUrl = parsedUrl.origin + parsedUrl.pathname.replace(/\/+$/, "");
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5247
|
+
const authResult = await auth2(freshAuthProvider, {
|
|
5248
|
+
serverUrl: baseUrl,
|
|
5249
|
+
fetchFn: freshAuthProvider.getProxyFetch?.()
|
|
5250
|
+
});
|
|
5251
|
+
if (authResult === "AUTHORIZED") {
|
|
5326
5252
|
addLog("info", "OAuth flow completed (tokens obtained)");
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
"OAuth flow initiated (popup/redirect):",
|
|
5331
|
-
err instanceof Error ? err.message : "Redirecting..."
|
|
5332
|
-
);
|
|
5253
|
+
connectingRef.current = false;
|
|
5254
|
+
connectRef.current?.();
|
|
5255
|
+
return;
|
|
5333
5256
|
}
|
|
5257
|
+
if (authResult !== "REDIRECT") {
|
|
5258
|
+
throw new Error(`Unexpected OAuth auth() result: ${authResult}`);
|
|
5259
|
+
}
|
|
5260
|
+
addLog("info", "OAuth authorization redirect initiated");
|
|
5334
5261
|
const newAuthUrl = freshAuthProvider.getLastAttemptedAuthUrl?.();
|
|
5335
5262
|
if (newAuthUrl) {
|
|
5336
5263
|
setAuthUrl(newAuthUrl);
|
|
@@ -5396,11 +5323,8 @@ function useMcp(options) {
|
|
|
5396
5323
|
}
|
|
5397
5324
|
} catch (authError) {
|
|
5398
5325
|
if (!isMountedRef.current) return;
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
"error",
|
|
5402
|
-
`Manual authentication failed: ${authError instanceof Error ? authError.message : String(authError)}`
|
|
5403
|
-
);
|
|
5326
|
+
const error2 = authError instanceof Error ? authError : new Error(String(authError));
|
|
5327
|
+
failConnection(`Manual authentication failed: ${error2.message}`, error2);
|
|
5404
5328
|
}
|
|
5405
5329
|
} else if (currentState === "authenticating") {
|
|
5406
5330
|
addLog(
|
|
@@ -5608,6 +5532,7 @@ function useMcp(options) {
|
|
|
5608
5532
|
// Triggers reconnection when proxy fallback changes OAuth URL
|
|
5609
5533
|
proxyConfig,
|
|
5610
5534
|
// Triggers reconnection when proxy config (including headers) changes
|
|
5535
|
+
autoProxyFallbackConfig.proxyAddress,
|
|
5611
5536
|
providedAuthProvider
|
|
5612
5537
|
]);
|
|
5613
5538
|
const retryRef = useRef(retry);
|
|
@@ -6881,6 +6806,7 @@ import React2, {
|
|
|
6881
6806
|
memo,
|
|
6882
6807
|
useCallback as useCallback6,
|
|
6883
6808
|
useEffect as useEffect5,
|
|
6809
|
+
useMemo as useMemo3,
|
|
6884
6810
|
useRef as useRef4,
|
|
6885
6811
|
useState as useState4
|
|
6886
6812
|
} from "react";
|
|
@@ -6903,6 +6829,53 @@ function parseCustomProps(customProps) {
|
|
|
6903
6829
|
return parsed;
|
|
6904
6830
|
}
|
|
6905
6831
|
|
|
6832
|
+
// src/react/view/inject-openai-file-apis.ts
|
|
6833
|
+
var OPENAI_FILE_APIS_SCRIPT = `<script>
|
|
6834
|
+
(function () {
|
|
6835
|
+
var files = new Map();
|
|
6836
|
+
window.openai = window.openai || {};
|
|
6837
|
+
window.openai.uploadFile = async function (file) {
|
|
6838
|
+
var fileId = crypto.randomUUID();
|
|
6839
|
+
files.set(fileId, file);
|
|
6840
|
+
return { fileId: fileId };
|
|
6841
|
+
};
|
|
6842
|
+
window.openai.getFileDownloadUrl = async function (ref) {
|
|
6843
|
+
var file = files.get(ref.fileId);
|
|
6844
|
+
if (!file) {
|
|
6845
|
+
throw new Error("File not found: " + ref.fileId);
|
|
6846
|
+
}
|
|
6847
|
+
return { downloadUrl: URL.createObjectURL(file) };
|
|
6848
|
+
};
|
|
6849
|
+
})();
|
|
6850
|
+
</script>`;
|
|
6851
|
+
function injectOpenAiFileApis(html) {
|
|
6852
|
+
if (html.includes("<head>")) {
|
|
6853
|
+
return html.replace("<head>", "<head>" + OPENAI_FILE_APIS_SCRIPT);
|
|
6854
|
+
}
|
|
6855
|
+
if (html.includes("<HEAD>")) {
|
|
6856
|
+
return html.replace("<HEAD>", "<HEAD>" + OPENAI_FILE_APIS_SCRIPT);
|
|
6857
|
+
}
|
|
6858
|
+
if (html.includes("<html>")) {
|
|
6859
|
+
return html.replace(
|
|
6860
|
+
"<html>",
|
|
6861
|
+
"<html><head>" + OPENAI_FILE_APIS_SCRIPT + "</head>"
|
|
6862
|
+
);
|
|
6863
|
+
}
|
|
6864
|
+
if (html.includes("<HTML>")) {
|
|
6865
|
+
return html.replace(
|
|
6866
|
+
"<HTML>",
|
|
6867
|
+
"<HTML><head>" + OPENAI_FILE_APIS_SCRIPT + "</head>"
|
|
6868
|
+
);
|
|
6869
|
+
}
|
|
6870
|
+
if (html.includes("<!DOCTYPE") || html.includes("<!doctype")) {
|
|
6871
|
+
return html.replace(
|
|
6872
|
+
/(<!DOCTYPE[^>]*>|<!doctype[^>]*>)/i,
|
|
6873
|
+
"$1<head>" + OPENAI_FILE_APIS_SCRIPT + "</head>"
|
|
6874
|
+
);
|
|
6875
|
+
}
|
|
6876
|
+
return OPENAI_FILE_APIS_SCRIPT + html;
|
|
6877
|
+
}
|
|
6878
|
+
|
|
6906
6879
|
// src/react/view/resolve-view-resource.ts
|
|
6907
6880
|
function resolveViewResource(options) {
|
|
6908
6881
|
const { resourceResult, listingResource, cspMode, resourceUri } = options;
|
|
@@ -7252,9 +7225,9 @@ function buildSandboxProxyBlobHtml(search) {
|
|
|
7252
7225
|
// src/react/view/use-display-mode.ts
|
|
7253
7226
|
import { useCallback as useCallback5, useEffect as useEffect4 } from "react";
|
|
7254
7227
|
var SHELL_BASE = "w-full h-full min-h-0 bg-background flex flex-col [&:fullscreen]:h-full [&:fullscreen]:w-full [&:fullscreen]:bg-background";
|
|
7255
|
-
var WIDGET_FULLSCREEN_OVERLAY_CLASSES = `fixed inset-0 z-[
|
|
7228
|
+
var WIDGET_FULLSCREEN_OVERLAY_CLASSES = `fixed inset-0 z-[200] ${SHELL_BASE}`;
|
|
7256
7229
|
var WIDGET_PIP_SHELL_CLASSES = [
|
|
7257
|
-
"fixed top-4 left-1/2 -translate-x-1/2 z-[
|
|
7230
|
+
"fixed top-4 left-1/2 -translate-x-1/2 z-[200]",
|
|
7258
7231
|
"rounded-3xl w-full min-w-[300px] h-[400px]",
|
|
7259
7232
|
"shadow-2xl border overflow-hidden",
|
|
7260
7233
|
"bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80",
|
|
@@ -7312,7 +7285,8 @@ function useViewDisplayModeControls({
|
|
|
7312
7285
|
}
|
|
7313
7286
|
var VIEW_DIMENSIONS = {
|
|
7314
7287
|
PIP_MAX_WIDTH: 700,
|
|
7315
|
-
DEFAULT_HEIGHT: 400
|
|
7288
|
+
DEFAULT_HEIGHT: 400,
|
|
7289
|
+
FULLSCREEN_HEADER_HEIGHT: 50
|
|
7316
7290
|
};
|
|
7317
7291
|
|
|
7318
7292
|
// src/react/view/view-detection.ts
|
|
@@ -7339,8 +7313,28 @@ var DEFAULT_HOST_CAPABILITIES = {
|
|
|
7339
7313
|
serverTools: {},
|
|
7340
7314
|
serverResources: {},
|
|
7341
7315
|
logging: {},
|
|
7342
|
-
updateModelContext: { text: {} }
|
|
7316
|
+
updateModelContext: { text: {} },
|
|
7317
|
+
// ponytail: always advertised; bridge.onmessage no-ops when onMessage unset
|
|
7318
|
+
message: { text: {} }
|
|
7343
7319
|
};
|
|
7320
|
+
function CloseIcon() {
|
|
7321
|
+
return /* @__PURE__ */ React2.createElement(
|
|
7322
|
+
"svg",
|
|
7323
|
+
{
|
|
7324
|
+
width: "14",
|
|
7325
|
+
height: "14",
|
|
7326
|
+
viewBox: "0 0 24 24",
|
|
7327
|
+
fill: "none",
|
|
7328
|
+
stroke: "currentColor",
|
|
7329
|
+
strokeWidth: "2",
|
|
7330
|
+
strokeLinecap: "round",
|
|
7331
|
+
strokeLinejoin: "round",
|
|
7332
|
+
"aria-hidden": true
|
|
7333
|
+
},
|
|
7334
|
+
/* @__PURE__ */ React2.createElement("path", { d: "M18 6 6 18" }),
|
|
7335
|
+
/* @__PURE__ */ React2.createElement("path", { d: "m6 6 12 12" })
|
|
7336
|
+
);
|
|
7337
|
+
}
|
|
7344
7338
|
function waitForSandboxProxyReady(iframe) {
|
|
7345
7339
|
return new Promise((resolve) => {
|
|
7346
7340
|
const listener = (event) => {
|
|
@@ -7401,6 +7395,10 @@ function ViewRendererBase({
|
|
|
7401
7395
|
onResourceResolved,
|
|
7402
7396
|
wrapTransport,
|
|
7403
7397
|
toolCallTimeout = DEFAULT_TOOL_CALL_TIMEOUT,
|
|
7398
|
+
mockOpenAiFileApis = false,
|
|
7399
|
+
onInlineHeightChange,
|
|
7400
|
+
fullscreenHeader,
|
|
7401
|
+
renderFullscreenClose,
|
|
7404
7402
|
className,
|
|
7405
7403
|
testId = "mcp-app-frame",
|
|
7406
7404
|
invoking,
|
|
@@ -7409,6 +7407,9 @@ function ViewRendererBase({
|
|
|
7409
7407
|
const iframeRef = useRef4(null);
|
|
7410
7408
|
const bridgeRef = useRef4(null);
|
|
7411
7409
|
const containerRef = useRef4(null);
|
|
7410
|
+
const pendingBlobRevocationsRef = useRef4(
|
|
7411
|
+
/* @__PURE__ */ new Map()
|
|
7412
|
+
);
|
|
7412
7413
|
const connectionRef = useRef4(
|
|
7413
7414
|
source.kind === "live" ? source.connection : null
|
|
7414
7415
|
);
|
|
@@ -7422,12 +7423,19 @@ function ViewRendererBase({
|
|
|
7422
7423
|
);
|
|
7423
7424
|
const [internalDisplayMode, setInternalDisplayMode] = useState4("inline");
|
|
7424
7425
|
const displayMode = displayModeProp ?? internalDisplayMode;
|
|
7425
|
-
const
|
|
7426
|
-
|
|
7426
|
+
const effectiveHostContext = useMemo3(() => {
|
|
7427
|
+
if (!hostContext) return hostContext;
|
|
7428
|
+
if (hostContext.displayMode === displayMode) return hostContext;
|
|
7429
|
+
return { ...hostContext, displayMode };
|
|
7430
|
+
}, [hostContext, displayMode]);
|
|
7431
|
+
const hostContextRef = useRef4(effectiveHostContext);
|
|
7432
|
+
hostContextRef.current = effectiveHostContext;
|
|
7427
7433
|
const onMessageRef = useRef4(onMessage);
|
|
7428
7434
|
onMessageRef.current = onMessage;
|
|
7429
7435
|
const toolInputRef = useRef4(toolInput);
|
|
7430
7436
|
toolInputRef.current = toolInput;
|
|
7437
|
+
const partialToolInputRef = useRef4(partialToolInput);
|
|
7438
|
+
partialToolInputRef.current = partialToolInput;
|
|
7431
7439
|
const toolOutputRef = useRef4(toolOutput);
|
|
7432
7440
|
toolOutputRef.current = toolOutput;
|
|
7433
7441
|
const customPropsRef = useRef4(customProps);
|
|
@@ -7446,10 +7454,14 @@ function ViewRendererBase({
|
|
|
7446
7454
|
onReadyRef.current = onReady;
|
|
7447
7455
|
const onLifecycleChangeRef = useRef4(onLifecycleChange);
|
|
7448
7456
|
onLifecycleChangeRef.current = onLifecycleChange;
|
|
7457
|
+
const onInlineHeightChangeRef = useRef4(onInlineHeightChange);
|
|
7458
|
+
onInlineHeightChangeRef.current = onInlineHeightChange;
|
|
7449
7459
|
const sandboxUrlRef = useRef4(sandboxUrl);
|
|
7450
7460
|
sandboxUrlRef.current = sandboxUrl;
|
|
7451
7461
|
const cspModeRef = useRef4(cspMode);
|
|
7452
7462
|
cspModeRef.current = cspMode;
|
|
7463
|
+
const mockOpenAiFileApisRef = useRef4(mockOpenAiFileApis);
|
|
7464
|
+
mockOpenAiFileApisRef.current = mockOpenAiFileApis;
|
|
7453
7465
|
const resolveSandboxUrl = useCallback6((next) => {
|
|
7454
7466
|
const custom = sandboxUrlRef.current;
|
|
7455
7467
|
if (custom) {
|
|
@@ -7553,10 +7565,18 @@ function ViewRendererBase({
|
|
|
7553
7565
|
}, [source.kind, liveResourceUri, preloadedHtml, cspMode, resolveSandboxUrl]);
|
|
7554
7566
|
useEffect5(() => {
|
|
7555
7567
|
const url = activeSandboxUrl;
|
|
7568
|
+
if (!url || url.protocol !== "blob:") return;
|
|
7569
|
+
const pending = pendingBlobRevocationsRef.current.get(url.href);
|
|
7570
|
+
if (pending) {
|
|
7571
|
+
clearTimeout(pending);
|
|
7572
|
+
pendingBlobRevocationsRef.current.delete(url.href);
|
|
7573
|
+
}
|
|
7556
7574
|
return () => {
|
|
7557
|
-
|
|
7575
|
+
const timer = setTimeout(() => {
|
|
7558
7576
|
URL.revokeObjectURL(url.href);
|
|
7559
|
-
|
|
7577
|
+
pendingBlobRevocationsRef.current.delete(url.href);
|
|
7578
|
+
}, 1e3);
|
|
7579
|
+
pendingBlobRevocationsRef.current.set(url.href, timer);
|
|
7560
7580
|
};
|
|
7561
7581
|
}, [activeSandboxUrl]);
|
|
7562
7582
|
const isBlobSandbox = activeSandboxUrl?.protocol === "blob:";
|
|
@@ -7617,7 +7637,14 @@ function ViewRendererBase({
|
|
|
7617
7637
|
iframe.setAttribute("allow", allowAttribute);
|
|
7618
7638
|
}
|
|
7619
7639
|
const readyPromise = waitForSandboxProxyReady(iframe);
|
|
7620
|
-
|
|
7640
|
+
if (activeSandboxUrl.protocol === "blob:") {
|
|
7641
|
+
const response = await fetch(activeSandboxUrl.href);
|
|
7642
|
+
const sandboxHtml = await response.text();
|
|
7643
|
+
if (disposed) return;
|
|
7644
|
+
iframe.srcdoc = sandboxHtml;
|
|
7645
|
+
} else {
|
|
7646
|
+
iframe.src = activeSandboxUrl.href;
|
|
7647
|
+
}
|
|
7621
7648
|
await readyPromise;
|
|
7622
7649
|
if (disposed) return;
|
|
7623
7650
|
const capabilities = {
|
|
@@ -7703,7 +7730,10 @@ function ViewRendererBase({
|
|
|
7703
7730
|
height
|
|
7704
7731
|
}) => {
|
|
7705
7732
|
if (displayModeRef.current !== "inline") return;
|
|
7706
|
-
if (height !== void 0)
|
|
7733
|
+
if (height !== void 0) {
|
|
7734
|
+
setInlineHeight(height);
|
|
7735
|
+
onInlineHeightChangeRef.current?.(height);
|
|
7736
|
+
}
|
|
7707
7737
|
};
|
|
7708
7738
|
const initPromise = hookInitialized(bridge);
|
|
7709
7739
|
let transport = new PostMessageTransport(
|
|
@@ -7716,7 +7746,7 @@ function ViewRendererBase({
|
|
|
7716
7746
|
await bridge.connect(transport);
|
|
7717
7747
|
if (disposed) return;
|
|
7718
7748
|
await bridge.sendSandboxResourceReady({
|
|
7719
|
-
html: resolved.html,
|
|
7749
|
+
html: mockOpenAiFileApisRef.current ? injectOpenAiFileApis(resolved.html) : resolved.html,
|
|
7720
7750
|
csp: resolved.csp,
|
|
7721
7751
|
permissions: resolved.permissions
|
|
7722
7752
|
});
|
|
@@ -7725,11 +7755,18 @@ function ViewRendererBase({
|
|
|
7725
7755
|
bridgeRef.current = bridge;
|
|
7726
7756
|
setInitCount((c) => c + 1);
|
|
7727
7757
|
onLifecycleChangeRef.current?.({ status: "initialized" });
|
|
7728
|
-
const
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7758
|
+
const currentPartialToolInput = partialToolInputRef.current;
|
|
7759
|
+
if (currentPartialToolInput) {
|
|
7760
|
+
bridge.sendToolInputPartial({
|
|
7761
|
+
arguments: currentPartialToolInput
|
|
7762
|
+
});
|
|
7763
|
+
} else {
|
|
7764
|
+
const mergedArgs = {
|
|
7765
|
+
...toolInputRef.current,
|
|
7766
|
+
...parseCustomProps(customPropsRef.current)
|
|
7767
|
+
};
|
|
7768
|
+
bridge.sendToolInput({ arguments: mergedArgs });
|
|
7769
|
+
}
|
|
7733
7770
|
const toolResultPayload = buildToolResultPayload(
|
|
7734
7771
|
toolOutputRef.current,
|
|
7735
7772
|
customPropsRef.current
|
|
@@ -7778,13 +7815,14 @@ function ViewRendererBase({
|
|
|
7778
7815
|
cspMode,
|
|
7779
7816
|
viewId,
|
|
7780
7817
|
wrapTransport,
|
|
7781
|
-
toolCallTimeout
|
|
7818
|
+
toolCallTimeout,
|
|
7819
|
+
mockOpenAiFileApis
|
|
7782
7820
|
]);
|
|
7783
7821
|
useEffect5(() => {
|
|
7784
7822
|
const bridge = bridgeRef.current;
|
|
7785
|
-
if (!bridge || initCount === 0 || !
|
|
7786
|
-
bridge.setHostContext(
|
|
7787
|
-
}, [
|
|
7823
|
+
if (!bridge || initCount === 0 || !effectiveHostContext) return;
|
|
7824
|
+
bridge.setHostContext(effectiveHostContext);
|
|
7825
|
+
}, [effectiveHostContext, initCount]);
|
|
7788
7826
|
useEffect5(() => {
|
|
7789
7827
|
const bridge = bridgeRef.current;
|
|
7790
7828
|
if (!bridge || initCount === 0 || !partialToolInput) return;
|
|
@@ -7792,13 +7830,13 @@ function ViewRendererBase({
|
|
|
7792
7830
|
}, [initCount, partialToolInput]);
|
|
7793
7831
|
useEffect5(() => {
|
|
7794
7832
|
const bridge = bridgeRef.current;
|
|
7795
|
-
if (!bridge || initCount === 0) return;
|
|
7833
|
+
if (!bridge || initCount === 0 || partialToolInput) return;
|
|
7796
7834
|
const mergedArgs = {
|
|
7797
7835
|
...toolInput,
|
|
7798
7836
|
...parseCustomProps(customProps)
|
|
7799
7837
|
};
|
|
7800
7838
|
bridge.sendToolInput({ arguments: mergedArgs });
|
|
7801
|
-
}, [initCount, toolInput, customProps]);
|
|
7839
|
+
}, [initCount, toolInput, partialToolInput, customProps]);
|
|
7802
7840
|
useEffect5(() => {
|
|
7803
7841
|
const bridge = bridgeRef.current;
|
|
7804
7842
|
if (!bridge || initCount === 0) return;
|
|
@@ -7822,6 +7860,7 @@ function ViewRendererBase({
|
|
|
7822
7860
|
const timer = setTimeout(() => setShowSpinner(false), 300);
|
|
7823
7861
|
return () => clearTimeout(timer);
|
|
7824
7862
|
}, [initCount, showSpinner]);
|
|
7863
|
+
const showHostBorder = resolved !== null && resolved.prefersBorder && displayMode !== "fullscreen";
|
|
7825
7864
|
if (loadError) {
|
|
7826
7865
|
return /* @__PURE__ */ React2.createElement("div", { className }, /* @__PURE__ */ React2.createElement("div", { className: "border border-red-200/50 dark:border-red-800/50 bg-red-50/30 dark:bg-red-950/20 rounded-lg p-4" }, /* @__PURE__ */ React2.createElement("p", { className: "text-sm text-red-600 dark:text-red-400" }, "Failed to load view: ", loadError)));
|
|
7827
7866
|
}
|
|
@@ -7839,29 +7878,69 @@ function ViewRendererBase({
|
|
|
7839
7878
|
"div",
|
|
7840
7879
|
{
|
|
7841
7880
|
ref: containerRef,
|
|
7842
|
-
className: containerClassName,
|
|
7881
|
+
className: isFullscreen ? `${containerClassName} flex flex-col` : containerClassName,
|
|
7843
7882
|
style: isPip ? {
|
|
7844
7883
|
height: VIEW_DIMENSIONS.DEFAULT_HEIGHT,
|
|
7845
7884
|
maxWidth: VIEW_DIMENSIONS.PIP_MAX_WIDTH,
|
|
7846
7885
|
zIndex: 100
|
|
7847
7886
|
} : isFullscreen ? { zIndex: 100 } : void 0
|
|
7848
7887
|
},
|
|
7849
|
-
|
|
7888
|
+
isFullscreen && // ponytail: inspector Tailwind may not emit client arbitrary classes
|
|
7889
|
+
// (h-[50px], grid-cols-[auto_1fr_auto]) — use inline layout instead.
|
|
7890
|
+
/* @__PURE__ */ React2.createElement(
|
|
7891
|
+
"header",
|
|
7892
|
+
{
|
|
7893
|
+
className: "grid shrink-0 items-center border-b border-zinc-200 bg-background px-3 dark:border-zinc-700",
|
|
7894
|
+
style: {
|
|
7895
|
+
height: VIEW_DIMENSIONS.FULLSCREEN_HEADER_HEIGHT,
|
|
7896
|
+
gridTemplateColumns: "auto 1fr auto"
|
|
7897
|
+
}
|
|
7898
|
+
},
|
|
7899
|
+
renderFullscreenClose ? renderFullscreenClose({
|
|
7900
|
+
onClick: () => void handleDisplayModeChange("inline"),
|
|
7901
|
+
"data-testid": "debugger-exit-fullscreen-button",
|
|
7902
|
+
"aria-label": "Exit fullscreen"
|
|
7903
|
+
}) : /* @__PURE__ */ React2.createElement(
|
|
7904
|
+
"button",
|
|
7905
|
+
{
|
|
7906
|
+
type: "button",
|
|
7907
|
+
"data-testid": "debugger-exit-fullscreen-button",
|
|
7908
|
+
"aria-label": "Exit fullscreen",
|
|
7909
|
+
className: "flex size-8 cursor-pointer items-center justify-center rounded-full border border-zinc-200 bg-background text-foreground shadow-sm hover:bg-muted dark:border-zinc-700",
|
|
7910
|
+
onClick: () => void handleDisplayModeChange("inline")
|
|
7911
|
+
},
|
|
7912
|
+
/* @__PURE__ */ React2.createElement(CloseIcon, null)
|
|
7913
|
+
),
|
|
7914
|
+
/* @__PURE__ */ React2.createElement("div", { className: "flex min-w-0 items-center justify-center gap-2 px-2" }, fullscreenHeader?.iconUrl ? /* @__PURE__ */ React2.createElement(
|
|
7915
|
+
"img",
|
|
7916
|
+
{
|
|
7917
|
+
src: fullscreenHeader.iconUrl,
|
|
7918
|
+
alt: "",
|
|
7919
|
+
className: "size-6 shrink-0 rounded-md object-contain"
|
|
7920
|
+
}
|
|
7921
|
+
) : null, /* @__PURE__ */ React2.createElement("span", { className: "truncate text-sm font-medium text-foreground" }, fullscreenHeader?.title ?? toolName)),
|
|
7922
|
+
/* @__PURE__ */ React2.createElement("div", { className: "size-8 shrink-0", "aria-hidden": true })
|
|
7923
|
+
),
|
|
7924
|
+
isPip && (renderFullscreenClose ? /* @__PURE__ */ React2.createElement("div", { className: "absolute right-3 top-3", style: { zIndex: 110 } }, renderFullscreenClose({
|
|
7925
|
+
onClick: () => void handleDisplayModeChange("inline"),
|
|
7926
|
+
"data-testid": "debugger-exit-pip-button",
|
|
7927
|
+
"aria-label": "Exit picture-in-picture"
|
|
7928
|
+
})) : /* @__PURE__ */ React2.createElement(
|
|
7850
7929
|
"button",
|
|
7851
7930
|
{
|
|
7852
7931
|
type: "button",
|
|
7853
|
-
"data-testid":
|
|
7854
|
-
"aria-label":
|
|
7855
|
-
className: "absolute right-3 top-3 z-[110] flex size-8 items-center justify-center rounded-full border border-border bg-background/90 text-
|
|
7932
|
+
"data-testid": "debugger-exit-pip-button",
|
|
7933
|
+
"aria-label": "Exit picture-in-picture",
|
|
7934
|
+
className: "absolute right-3 top-3 z-[110] flex size-8 cursor-pointer items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm backdrop-blur-sm hover:bg-background",
|
|
7856
7935
|
style: { zIndex: 110 },
|
|
7857
7936
|
onClick: () => void handleDisplayModeChange("inline")
|
|
7858
7937
|
},
|
|
7859
|
-
|
|
7860
|
-
),
|
|
7938
|
+
/* @__PURE__ */ React2.createElement(CloseIcon, null)
|
|
7939
|
+
)),
|
|
7861
7940
|
/* @__PURE__ */ React2.createElement(
|
|
7862
7941
|
"div",
|
|
7863
7942
|
{
|
|
7864
|
-
className: isFullscreen
|
|
7943
|
+
className: isFullscreen ? "relative flex min-h-0 w-full flex-1 flex-col" : isPip ? "relative w-full h-full min-h-0 flex flex-1 flex-col" : "relative w-full flex flex-1 justify-center items-center"
|
|
7865
7944
|
},
|
|
7866
7945
|
showSpinner && /* @__PURE__ */ React2.createElement("div", { className: "flex absolute inset-0 items-center justify-center z-10" }, /* @__PURE__ */ React2.createElement("span", { className: "text-sm text-muted-foreground" }, "Loading\u2026")),
|
|
7867
7946
|
!isPip && !isFullscreen && (invoking || invoked) && /* @__PURE__ */ React2.createElement("div", { className: "absolute -top-8 left-2 z-10 whitespace-nowrap pointer-events-none text-xs text-muted-foreground" }, invoking && !toolOutput ? invoking : invoked),
|
|
@@ -7878,10 +7957,7 @@ function ViewRendererBase({
|
|
|
7878
7957
|
{
|
|
7879
7958
|
ref: iframeRef,
|
|
7880
7959
|
title: `MCP App: ${toolName}`,
|
|
7881
|
-
className: "w-full h-full border-
|
|
7882
|
-
style: {
|
|
7883
|
-
border: resolved.prefersBorder && displayMode !== "fullscreen" ? void 0 : "none"
|
|
7884
|
-
}
|
|
7960
|
+
className: showHostBorder ? "w-full h-full bg-transparent border border-border rounded-xl" : "w-full h-full bg-transparent border-0"
|
|
7885
7961
|
}
|
|
7886
7962
|
)
|
|
7887
7963
|
)
|
|
@@ -7902,6 +7978,10 @@ function viewRendererAreEqual(prev, next) {
|
|
|
7902
7978
|
if (prev.hostContext !== next.hostContext) return false;
|
|
7903
7979
|
if (prev.hostCapabilities !== next.hostCapabilities) return false;
|
|
7904
7980
|
if (prev.cspMode !== next.cspMode) return false;
|
|
7981
|
+
if (prev.mockOpenAiFileApis !== next.mockOpenAiFileApis) return false;
|
|
7982
|
+
if (prev.onInlineHeightChange !== next.onInlineHeightChange) return false;
|
|
7983
|
+
if (prev.fullscreenHeader !== next.fullscreenHeader) return false;
|
|
7984
|
+
if (prev.renderFullscreenClose !== next.renderFullscreenClose) return false;
|
|
7905
7985
|
if (prev.className !== next.className) return false;
|
|
7906
7986
|
if (prev.onReady !== next.onReady) return false;
|
|
7907
7987
|
if (prev.onLifecycleChange !== next.onLifecycleChange) return false;
|