open-mcp-app 0.1.3 → 0.1.4
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/core/index.d.ts +92 -53
- package/dist/core/index.js +95 -63
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.d.ts +307 -30
- package/dist/react/index.js +360 -115
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.js +3 -1
- package/dist/server/index.js.map +1 -1
- package/dist/vite/index.d.ts +0 -13
- package/dist/vite/index.js +3 -1
- package/dist/vite/index.js.map +1 -1
- package/package.json +6 -3
package/dist/react/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/react/useHost.ts
|
|
2
|
-
import { useSyncExternalStore, useEffect, useRef, useMemo } from "react";
|
|
2
|
+
import { useSyncExternalStore, useEffect as useEffect2, useRef as useRef2, useMemo, useState, useCallback } from "react";
|
|
3
3
|
|
|
4
4
|
// src/core/base/Subscribable.ts
|
|
5
5
|
var Subscribable = class {
|
|
@@ -278,6 +278,24 @@ var ChatGptAdapter = class _ChatGptAdapter {
|
|
|
278
278
|
get isCreature() {
|
|
279
279
|
return false;
|
|
280
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Experimental APIs for ChatGPT.
|
|
283
|
+
* Most are no-ops since ChatGPT doesn't support MCP Apps extensions.
|
|
284
|
+
*/
|
|
285
|
+
get experimental() {
|
|
286
|
+
return {
|
|
287
|
+
sendNotification: (_method, _params) => {
|
|
288
|
+
},
|
|
289
|
+
setWidgetState: (state) => {
|
|
290
|
+
this.base.setWidgetState(state);
|
|
291
|
+
},
|
|
292
|
+
setTitle: (_title) => {
|
|
293
|
+
},
|
|
294
|
+
getCreatureStyles: () => {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}
|
|
281
299
|
/**
|
|
282
300
|
* Get host context - returns null for ChatGPT as it doesn't use MCP Apps protocol.
|
|
283
301
|
*/
|
|
@@ -293,19 +311,6 @@ var ChatGptAdapter = class _ChatGptAdapter {
|
|
|
293
311
|
async callTool(toolName, args) {
|
|
294
312
|
return this.base.callTool(toolName, args);
|
|
295
313
|
}
|
|
296
|
-
/**
|
|
297
|
-
* Send notification - not supported on ChatGPT.
|
|
298
|
-
*/
|
|
299
|
-
sendNotification(_method, _params) {
|
|
300
|
-
}
|
|
301
|
-
setWidgetState(state) {
|
|
302
|
-
this.base.setWidgetState(state);
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Set pip/widget title - not supported on ChatGPT.
|
|
306
|
-
*/
|
|
307
|
-
setTitle(_title) {
|
|
308
|
-
}
|
|
309
314
|
async requestDisplayMode(params) {
|
|
310
315
|
return this.base.requestDisplayMode(params);
|
|
311
316
|
}
|
|
@@ -460,6 +465,26 @@ var StandaloneAdapter = class _StandaloneAdapter {
|
|
|
460
465
|
get isCreature() {
|
|
461
466
|
return false;
|
|
462
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* Experimental APIs for standalone mode.
|
|
470
|
+
* All methods are logged for development/debugging purposes.
|
|
471
|
+
*/
|
|
472
|
+
get experimental() {
|
|
473
|
+
return {
|
|
474
|
+
sendNotification: (method, params) => {
|
|
475
|
+
console.debug(`[Standalone] experimental.sendNotification("${method}")`, params);
|
|
476
|
+
},
|
|
477
|
+
setWidgetState: (state) => {
|
|
478
|
+
this.base.setWidgetState(state);
|
|
479
|
+
},
|
|
480
|
+
setTitle: (title) => {
|
|
481
|
+
console.debug(`[Standalone] experimental.setTitle("${title}")`);
|
|
482
|
+
},
|
|
483
|
+
getCreatureStyles: () => {
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
}
|
|
463
488
|
/**
|
|
464
489
|
* Get host context - returns null for standalone mode.
|
|
465
490
|
*/
|
|
@@ -475,21 +500,6 @@ var StandaloneAdapter = class _StandaloneAdapter {
|
|
|
475
500
|
async callTool(toolName, args) {
|
|
476
501
|
return this.base.callTool(toolName, args);
|
|
477
502
|
}
|
|
478
|
-
/**
|
|
479
|
-
* Send notification - logged in standalone mode.
|
|
480
|
-
*/
|
|
481
|
-
sendNotification(method, params) {
|
|
482
|
-
console.debug(`[Standalone] sendNotification("${method}")`, params);
|
|
483
|
-
}
|
|
484
|
-
setWidgetState(state) {
|
|
485
|
-
this.base.setWidgetState(state);
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* Set pip/widget title - logged in standalone mode.
|
|
489
|
-
*/
|
|
490
|
-
setTitle(title) {
|
|
491
|
-
console.debug(`[Standalone] setTitle("${title}")`);
|
|
492
|
-
}
|
|
493
503
|
async requestDisplayMode(params) {
|
|
494
504
|
return this.base.requestDisplayMode(params);
|
|
495
505
|
}
|
|
@@ -10156,14 +10166,29 @@ var UpgradingMcpAppsClient = class _UpgradingMcpAppsClient {
|
|
|
10156
10166
|
return this.base.getState().environment;
|
|
10157
10167
|
}
|
|
10158
10168
|
// ============================================================================
|
|
10159
|
-
//
|
|
10169
|
+
// Experimental APIs
|
|
10160
10170
|
// ============================================================================
|
|
10161
10171
|
/**
|
|
10162
|
-
*
|
|
10163
|
-
*
|
|
10172
|
+
* Experimental APIs with dynamic Creature support.
|
|
10173
|
+
* Methods like setTitle will only work when isCreature is true.
|
|
10164
10174
|
*/
|
|
10165
|
-
|
|
10166
|
-
return
|
|
10175
|
+
get experimental() {
|
|
10176
|
+
return {
|
|
10177
|
+
sendNotification: (method, params) => {
|
|
10178
|
+
this.base.sendNotification(method, params);
|
|
10179
|
+
},
|
|
10180
|
+
setWidgetState: (state) => {
|
|
10181
|
+
this.base.setWidgetState(state);
|
|
10182
|
+
},
|
|
10183
|
+
setTitle: (title) => {
|
|
10184
|
+
if (this.isCreature) {
|
|
10185
|
+
this.base.sendNotification("ui/notifications/title-changed", { title });
|
|
10186
|
+
}
|
|
10187
|
+
},
|
|
10188
|
+
getCreatureStyles: () => {
|
|
10189
|
+
return this.base.getCreatureStyles();
|
|
10190
|
+
}
|
|
10191
|
+
};
|
|
10167
10192
|
}
|
|
10168
10193
|
// ============================================================================
|
|
10169
10194
|
// UnifiedHostClient Implementation
|
|
@@ -10180,19 +10205,6 @@ var UpgradingMcpAppsClient = class _UpgradingMcpAppsClient {
|
|
|
10180
10205
|
async callTool(toolName, args) {
|
|
10181
10206
|
return this.base.callTool(toolName, args);
|
|
10182
10207
|
}
|
|
10183
|
-
sendNotification(method, params) {
|
|
10184
|
-
this.base.sendNotification(method, params);
|
|
10185
|
-
}
|
|
10186
|
-
setWidgetState(state) {
|
|
10187
|
-
this.base.setWidgetState(state);
|
|
10188
|
-
}
|
|
10189
|
-
/**
|
|
10190
|
-
* Set pip/widget title.
|
|
10191
|
-
* Sends a notification - hosts that support it will update the title.
|
|
10192
|
-
*/
|
|
10193
|
-
setTitle(title) {
|
|
10194
|
-
this.base.sendNotification("ui/notifications/title-changed", { title });
|
|
10195
|
-
}
|
|
10196
10208
|
async requestDisplayMode(params) {
|
|
10197
10209
|
return this.base.requestDisplayMode(params);
|
|
10198
10210
|
}
|
|
@@ -10262,6 +10274,25 @@ var McpAppsAdapter = class _McpAppsAdapter {
|
|
|
10262
10274
|
get isCreature() {
|
|
10263
10275
|
return false;
|
|
10264
10276
|
}
|
|
10277
|
+
/**
|
|
10278
|
+
* Experimental APIs for non-spec extensions.
|
|
10279
|
+
* Base MCP Apps adapter provides minimal implementations - CreatureAdapter overrides.
|
|
10280
|
+
*/
|
|
10281
|
+
get experimental() {
|
|
10282
|
+
return {
|
|
10283
|
+
sendNotification: (method, params) => {
|
|
10284
|
+
this.base.sendNotification(method, params);
|
|
10285
|
+
},
|
|
10286
|
+
setWidgetState: (state) => {
|
|
10287
|
+
this.base.setWidgetState(state);
|
|
10288
|
+
},
|
|
10289
|
+
setTitle: (_title) => {
|
|
10290
|
+
},
|
|
10291
|
+
getCreatureStyles: () => {
|
|
10292
|
+
return null;
|
|
10293
|
+
}
|
|
10294
|
+
};
|
|
10295
|
+
}
|
|
10265
10296
|
/**
|
|
10266
10297
|
* Get the host context received from the host.
|
|
10267
10298
|
* Useful for checking host-specific capabilities.
|
|
@@ -10278,19 +10309,6 @@ var McpAppsAdapter = class _McpAppsAdapter {
|
|
|
10278
10309
|
async callTool(toolName, args) {
|
|
10279
10310
|
return this.base.callTool(toolName, args);
|
|
10280
10311
|
}
|
|
10281
|
-
sendNotification(method, params) {
|
|
10282
|
-
this.base.sendNotification(method, params);
|
|
10283
|
-
}
|
|
10284
|
-
setWidgetState(state) {
|
|
10285
|
-
this.base.setWidgetState(state);
|
|
10286
|
-
}
|
|
10287
|
-
/**
|
|
10288
|
-
* Set pip/widget title.
|
|
10289
|
-
* Sends a notification - hosts that support it will update the title.
|
|
10290
|
-
*/
|
|
10291
|
-
setTitle(title) {
|
|
10292
|
-
this.base.sendNotification("ui/notifications/title-changed", { title });
|
|
10293
|
-
}
|
|
10294
10312
|
async requestDisplayMode(params) {
|
|
10295
10313
|
return this.base.requestDisplayMode(params);
|
|
10296
10314
|
}
|
|
@@ -10388,11 +10406,25 @@ var CreatureAdapter = class _CreatureAdapter extends McpAppsAdapter {
|
|
|
10388
10406
|
return this.base.isCreatureHost();
|
|
10389
10407
|
}
|
|
10390
10408
|
/**
|
|
10391
|
-
*
|
|
10392
|
-
* Returns null when not running in Creature.
|
|
10409
|
+
* Experimental APIs with Creature-specific implementations.
|
|
10393
10410
|
*/
|
|
10394
|
-
|
|
10395
|
-
return
|
|
10411
|
+
get experimental() {
|
|
10412
|
+
return {
|
|
10413
|
+
sendNotification: (method, params) => {
|
|
10414
|
+
this.base.sendNotification(method, params);
|
|
10415
|
+
},
|
|
10416
|
+
setWidgetState: (state) => {
|
|
10417
|
+
this.base.setWidgetState(state);
|
|
10418
|
+
},
|
|
10419
|
+
setTitle: (title) => {
|
|
10420
|
+
if (this.isCreature) {
|
|
10421
|
+
this.base.sendNotification("ui/notifications/title-changed", { title });
|
|
10422
|
+
}
|
|
10423
|
+
},
|
|
10424
|
+
getCreatureStyles: () => {
|
|
10425
|
+
return this.base.getCreatureStyles();
|
|
10426
|
+
}
|
|
10427
|
+
};
|
|
10396
10428
|
}
|
|
10397
10429
|
};
|
|
10398
10430
|
|
|
@@ -10539,13 +10571,164 @@ async function createHostAsync(config) {
|
|
|
10539
10571
|
});
|
|
10540
10572
|
}
|
|
10541
10573
|
|
|
10542
|
-
// src/react/
|
|
10543
|
-
|
|
10574
|
+
// src/react/HostContext.tsx
|
|
10575
|
+
import { createContext, useContext, useRef, useEffect } from "react";
|
|
10576
|
+
import { jsx } from "react/jsx-runtime";
|
|
10577
|
+
var HostContext = createContext(null);
|
|
10578
|
+
function useHostClient() {
|
|
10579
|
+
const client = useContext(HostContext);
|
|
10580
|
+
if (!client) {
|
|
10581
|
+
throw new Error(
|
|
10582
|
+
'useHostClient must be used within a HostProvider. Wrap your app with <HostProvider name="..." version="...">.'
|
|
10583
|
+
);
|
|
10584
|
+
}
|
|
10585
|
+
return client;
|
|
10586
|
+
}
|
|
10587
|
+
function useHostClientOptional() {
|
|
10588
|
+
return useContext(HostContext);
|
|
10589
|
+
}
|
|
10590
|
+
function HostProvider({
|
|
10591
|
+
name,
|
|
10592
|
+
version,
|
|
10593
|
+
children,
|
|
10594
|
+
onToolInput,
|
|
10595
|
+
onThemeChange,
|
|
10596
|
+
onTeardown
|
|
10597
|
+
}) {
|
|
10544
10598
|
const clientRef = useRef(null);
|
|
10545
10599
|
if (!clientRef.current) {
|
|
10546
|
-
clientRef.current = createHost({ name
|
|
10600
|
+
clientRef.current = createHost({ name, version });
|
|
10547
10601
|
}
|
|
10548
10602
|
const client = clientRef.current;
|
|
10603
|
+
const callbacksRef = useRef({ onToolInput, onThemeChange, onTeardown });
|
|
10604
|
+
useEffect(() => {
|
|
10605
|
+
callbacksRef.current = { onToolInput, onThemeChange, onTeardown };
|
|
10606
|
+
});
|
|
10607
|
+
useEffect(() => {
|
|
10608
|
+
const unsubs = [];
|
|
10609
|
+
if (callbacksRef.current.onToolInput) {
|
|
10610
|
+
unsubs.push(
|
|
10611
|
+
client.on("tool-input", (args) => callbacksRef.current.onToolInput?.(args))
|
|
10612
|
+
);
|
|
10613
|
+
}
|
|
10614
|
+
unsubs.push(
|
|
10615
|
+
client.on("theme-change", (theme) => callbacksRef.current.onThemeChange?.(theme))
|
|
10616
|
+
);
|
|
10617
|
+
unsubs.push(
|
|
10618
|
+
client.on("teardown", () => callbacksRef.current.onTeardown?.())
|
|
10619
|
+
);
|
|
10620
|
+
client.connect();
|
|
10621
|
+
return () => {
|
|
10622
|
+
unsubs.forEach((unsub) => unsub());
|
|
10623
|
+
client.disconnect();
|
|
10624
|
+
};
|
|
10625
|
+
}, [client]);
|
|
10626
|
+
return /* @__PURE__ */ jsx(HostContext.Provider, { value: client, children });
|
|
10627
|
+
}
|
|
10628
|
+
|
|
10629
|
+
// src/react/useHost.ts
|
|
10630
|
+
var INITIAL_TOOL_STATE = {
|
|
10631
|
+
status: "idle",
|
|
10632
|
+
data: null,
|
|
10633
|
+
result: null,
|
|
10634
|
+
error: null,
|
|
10635
|
+
isError: false,
|
|
10636
|
+
text: null,
|
|
10637
|
+
title: null,
|
|
10638
|
+
instanceId: null
|
|
10639
|
+
};
|
|
10640
|
+
function extractResultMetadata(result) {
|
|
10641
|
+
const structured = result.structuredContent;
|
|
10642
|
+
let data = null;
|
|
10643
|
+
let title = null;
|
|
10644
|
+
let instanceId = null;
|
|
10645
|
+
if (structured) {
|
|
10646
|
+
const { title: resultTitle, instanceId: resultInstanceId, ...rest } = structured;
|
|
10647
|
+
data = rest;
|
|
10648
|
+
if (resultTitle) title = resultTitle;
|
|
10649
|
+
if (resultInstanceId) instanceId = resultInstanceId;
|
|
10650
|
+
}
|
|
10651
|
+
const text = result.content?.[0]?.text ?? null;
|
|
10652
|
+
return { data, title, instanceId, text };
|
|
10653
|
+
}
|
|
10654
|
+
function useHost(config) {
|
|
10655
|
+
const contextClient = useHostClientOptional();
|
|
10656
|
+
const useContext2 = !config && contextClient !== null;
|
|
10657
|
+
const clientRef = useRef2(null);
|
|
10658
|
+
if (!useContext2) {
|
|
10659
|
+
if (!config) {
|
|
10660
|
+
throw new Error(
|
|
10661
|
+
'useHost() requires either a HostProvider wrapper or config argument. Either wrap your app with <HostProvider name="..." version="..."> or pass { name, version } to useHost().'
|
|
10662
|
+
);
|
|
10663
|
+
}
|
|
10664
|
+
if (!clientRef.current) {
|
|
10665
|
+
clientRef.current = createHost({ name: config.name, version: config.version });
|
|
10666
|
+
}
|
|
10667
|
+
}
|
|
10668
|
+
const client = useContext2 ? contextClient : clientRef.current;
|
|
10669
|
+
const [toolStates, setToolStates] = useState(
|
|
10670
|
+
() => /* @__PURE__ */ new Map()
|
|
10671
|
+
);
|
|
10672
|
+
const toolFunctionsRef = useRef2(/* @__PURE__ */ new Map());
|
|
10673
|
+
const updateToolState = useCallback(
|
|
10674
|
+
(toolName, newState) => {
|
|
10675
|
+
setToolStates((prev) => {
|
|
10676
|
+
const current = prev.get(toolName) ?? INITIAL_TOOL_STATE;
|
|
10677
|
+
const updated = { ...current, ...newState };
|
|
10678
|
+
const next = new Map(prev);
|
|
10679
|
+
next.set(toolName, updated);
|
|
10680
|
+
return next;
|
|
10681
|
+
});
|
|
10682
|
+
},
|
|
10683
|
+
[]
|
|
10684
|
+
);
|
|
10685
|
+
const getOrCreateToolFunction = useCallback(
|
|
10686
|
+
(toolName) => {
|
|
10687
|
+
const existing = toolFunctionsRef.current.get(toolName);
|
|
10688
|
+
if (existing) {
|
|
10689
|
+
return existing;
|
|
10690
|
+
}
|
|
10691
|
+
const runFn = async (args = {}) => {
|
|
10692
|
+
updateToolState(toolName, {
|
|
10693
|
+
status: "loading",
|
|
10694
|
+
error: null
|
|
10695
|
+
});
|
|
10696
|
+
try {
|
|
10697
|
+
const result = await client.callTool(toolName, args);
|
|
10698
|
+
const { data, title, instanceId, text } = extractResultMetadata(result);
|
|
10699
|
+
updateToolState(toolName, {
|
|
10700
|
+
status: "success",
|
|
10701
|
+
data,
|
|
10702
|
+
result,
|
|
10703
|
+
error: null,
|
|
10704
|
+
isError: result.isError ?? false,
|
|
10705
|
+
text,
|
|
10706
|
+
title,
|
|
10707
|
+
instanceId
|
|
10708
|
+
});
|
|
10709
|
+
return result;
|
|
10710
|
+
} catch (err) {
|
|
10711
|
+
updateToolState(toolName, {
|
|
10712
|
+
status: "error",
|
|
10713
|
+
error: err,
|
|
10714
|
+
isError: true
|
|
10715
|
+
});
|
|
10716
|
+
throw err;
|
|
10717
|
+
}
|
|
10718
|
+
};
|
|
10719
|
+
toolFunctionsRef.current.set(toolName, runFn);
|
|
10720
|
+
return runFn;
|
|
10721
|
+
},
|
|
10722
|
+
[client, updateToolState]
|
|
10723
|
+
);
|
|
10724
|
+
const callTool = useCallback(
|
|
10725
|
+
(toolName) => {
|
|
10726
|
+
const runFn = getOrCreateToolFunction(toolName);
|
|
10727
|
+
const currentState = toolStates.get(toolName) ?? INITIAL_TOOL_STATE;
|
|
10728
|
+
return [runFn, currentState];
|
|
10729
|
+
},
|
|
10730
|
+
[getOrCreateToolFunction, toolStates]
|
|
10731
|
+
);
|
|
10549
10732
|
const log = useMemo(() => {
|
|
10550
10733
|
const logFn = (message, data) => {
|
|
10551
10734
|
client.log("info", message, data);
|
|
@@ -10567,13 +10750,16 @@ function useHost(config) {
|
|
|
10567
10750
|
};
|
|
10568
10751
|
return logFn;
|
|
10569
10752
|
}, [client]);
|
|
10570
|
-
const
|
|
10753
|
+
const requestDisplayMode = useMemo(
|
|
10754
|
+
() => client.requestDisplayMode.bind(client),
|
|
10755
|
+
[client]
|
|
10756
|
+
);
|
|
10757
|
+
const experimental = useMemo(
|
|
10571
10758
|
() => ({
|
|
10572
|
-
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
requestDisplayMode: client.requestDisplayMode.bind(client)
|
|
10759
|
+
sendNotification: client.experimental.sendNotification.bind(client.experimental),
|
|
10760
|
+
setWidgetState: client.experimental.setWidgetState.bind(client.experimental),
|
|
10761
|
+
setTitle: client.experimental.setTitle.bind(client.experimental),
|
|
10762
|
+
getCreatureStyles: client.experimental.getCreatureStyles.bind(client.experimental)
|
|
10577
10763
|
}),
|
|
10578
10764
|
[client]
|
|
10579
10765
|
);
|
|
@@ -10582,23 +10768,33 @@ function useHost(config) {
|
|
|
10582
10768
|
() => client.getState(),
|
|
10583
10769
|
() => client.getState()
|
|
10584
10770
|
);
|
|
10585
|
-
const
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10771
|
+
const experimental_widgetState = useCallback(
|
|
10772
|
+
() => {
|
|
10773
|
+
const currentState = state.widgetState;
|
|
10774
|
+
const setState = (newState) => {
|
|
10775
|
+
client.experimental.setWidgetState(newState);
|
|
10776
|
+
};
|
|
10777
|
+
return [currentState, setState];
|
|
10778
|
+
},
|
|
10779
|
+
[state.widgetState, client]
|
|
10780
|
+
);
|
|
10781
|
+
const callbacksRef = useRef2({
|
|
10782
|
+
onToolInput: config?.onToolInput,
|
|
10783
|
+
onToolResult: config?.onToolResult,
|
|
10784
|
+
onThemeChange: config?.onThemeChange,
|
|
10785
|
+
onTeardown: config?.onTeardown,
|
|
10786
|
+
onWidgetStateChange: config?.onWidgetStateChange
|
|
10591
10787
|
});
|
|
10592
|
-
|
|
10788
|
+
useEffect2(() => {
|
|
10593
10789
|
callbacksRef.current = {
|
|
10594
|
-
onToolInput: config
|
|
10595
|
-
onToolResult: config
|
|
10596
|
-
onThemeChange: config
|
|
10597
|
-
onTeardown: config
|
|
10598
|
-
onWidgetStateChange: config
|
|
10790
|
+
onToolInput: config?.onToolInput,
|
|
10791
|
+
onToolResult: config?.onToolResult,
|
|
10792
|
+
onThemeChange: config?.onThemeChange,
|
|
10793
|
+
onTeardown: config?.onTeardown,
|
|
10794
|
+
onWidgetStateChange: config?.onWidgetStateChange
|
|
10599
10795
|
};
|
|
10600
10796
|
});
|
|
10601
|
-
|
|
10797
|
+
useEffect2(() => {
|
|
10602
10798
|
const unsubs = [];
|
|
10603
10799
|
unsubs.push(
|
|
10604
10800
|
client.on("tool-input", (args) => callbacksRef.current.onToolInput?.(args))
|
|
@@ -10618,38 +10814,42 @@ function useHost(config) {
|
|
|
10618
10814
|
(widgetState) => callbacksRef.current.onWidgetStateChange?.(widgetState)
|
|
10619
10815
|
)
|
|
10620
10816
|
);
|
|
10621
|
-
|
|
10817
|
+
if (!useContext2) {
|
|
10818
|
+
client.connect();
|
|
10819
|
+
}
|
|
10622
10820
|
return () => {
|
|
10623
10821
|
unsubs.forEach((unsub) => unsub());
|
|
10624
|
-
|
|
10822
|
+
if (!useContext2) {
|
|
10823
|
+
client.disconnect();
|
|
10824
|
+
}
|
|
10625
10825
|
};
|
|
10626
|
-
}, [client]);
|
|
10826
|
+
}, [client, useContext2]);
|
|
10627
10827
|
return {
|
|
10628
10828
|
isReady: state.isReady,
|
|
10629
10829
|
environment: state.environment,
|
|
10630
10830
|
widgetState: state.widgetState,
|
|
10631
|
-
callTool
|
|
10632
|
-
|
|
10633
|
-
setWidgetState: boundMethods.setWidgetState,
|
|
10634
|
-
setTitle: boundMethods.setTitle,
|
|
10635
|
-
requestDisplayMode: boundMethods.requestDisplayMode,
|
|
10831
|
+
callTool,
|
|
10832
|
+
requestDisplayMode,
|
|
10636
10833
|
log,
|
|
10637
10834
|
// Host detection properties (may change after connection for MCP Apps)
|
|
10638
10835
|
adapterKind: client.adapterKind,
|
|
10639
10836
|
isCreature: client.isCreature,
|
|
10640
|
-
hostContext: client.getHostContext()
|
|
10837
|
+
hostContext: client.getHostContext(),
|
|
10838
|
+
// Experimental APIs (non-spec extensions)
|
|
10839
|
+
experimental,
|
|
10840
|
+
experimental_widgetState
|
|
10641
10841
|
};
|
|
10642
10842
|
}
|
|
10643
10843
|
|
|
10644
10844
|
// src/react/useToolResult.ts
|
|
10645
|
-
import { useState as useState2, useCallback } from "react";
|
|
10845
|
+
import { useState as useState2, useCallback as useCallback2 } from "react";
|
|
10646
10846
|
function useToolResult() {
|
|
10647
10847
|
const [data, setData] = useState2(null);
|
|
10648
10848
|
const [instanceId, setInstanceId] = useState2(null);
|
|
10649
10849
|
const [title, setTitle] = useState2(null);
|
|
10650
10850
|
const [isError, setIsError] = useState2(false);
|
|
10651
10851
|
const [text, setText] = useState2(null);
|
|
10652
|
-
const onToolResult =
|
|
10852
|
+
const onToolResult = useCallback2((result) => {
|
|
10653
10853
|
const structured = result.structuredContent;
|
|
10654
10854
|
if (structured) {
|
|
10655
10855
|
const { title: resultTitle, instanceId: resultInstanceId, ...rest } = structured;
|
|
@@ -10666,7 +10866,7 @@ function useToolResult() {
|
|
|
10666
10866
|
setText(result.content[0].text);
|
|
10667
10867
|
}
|
|
10668
10868
|
}, []);
|
|
10669
|
-
const reset =
|
|
10869
|
+
const reset = useCallback2(() => {
|
|
10670
10870
|
setData(null);
|
|
10671
10871
|
setInstanceId(null);
|
|
10672
10872
|
setTitle(null);
|
|
@@ -10685,23 +10885,23 @@ function useToolResult() {
|
|
|
10685
10885
|
}
|
|
10686
10886
|
|
|
10687
10887
|
// src/react/useWebSocket.ts
|
|
10688
|
-
import { useEffect as
|
|
10888
|
+
import { useEffect as useEffect3, useRef as useRef3, useMemo as useMemo2, useCallback as useCallback3, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
10689
10889
|
function useWebSocket(url, config = {}) {
|
|
10690
10890
|
const { onMessage, enabled = true } = config;
|
|
10691
|
-
const onMessageRef =
|
|
10891
|
+
const onMessageRef = useRef3(onMessage);
|
|
10692
10892
|
onMessageRef.current = onMessage;
|
|
10693
|
-
const stateRef =
|
|
10694
|
-
const listenersRef =
|
|
10695
|
-
const clientRef =
|
|
10696
|
-
const subscribe =
|
|
10893
|
+
const stateRef = useRef3({ status: "disconnected", error: void 0 });
|
|
10894
|
+
const listenersRef = useRef3(/* @__PURE__ */ new Set());
|
|
10895
|
+
const clientRef = useRef3(null);
|
|
10896
|
+
const subscribe = useCallback3((listener) => {
|
|
10697
10897
|
listenersRef.current.add(listener);
|
|
10698
10898
|
return () => {
|
|
10699
10899
|
listenersRef.current.delete(listener);
|
|
10700
10900
|
};
|
|
10701
10901
|
}, []);
|
|
10702
|
-
const getSnapshot =
|
|
10902
|
+
const getSnapshot = useCallback3(() => stateRef.current, []);
|
|
10703
10903
|
const state = useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
|
|
10704
|
-
|
|
10904
|
+
useEffect3(() => {
|
|
10705
10905
|
if (!url || !enabled) {
|
|
10706
10906
|
if (clientRef.current) {
|
|
10707
10907
|
clientRef.current.disconnect();
|
|
@@ -10738,8 +10938,8 @@ function useWebSocket(url, config = {}) {
|
|
|
10738
10938
|
}
|
|
10739
10939
|
|
|
10740
10940
|
// src/react/CreatureIcon.tsx
|
|
10741
|
-
import { useState as useState3, useEffect as
|
|
10742
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10941
|
+
import { useState as useState3, useEffect as useEffect4, useRef as useRef4 } from "react";
|
|
10942
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
10743
10943
|
function CreatureIcon({
|
|
10744
10944
|
isDarkMode,
|
|
10745
10945
|
showEyes = true,
|
|
@@ -10750,8 +10950,8 @@ function CreatureIcon({
|
|
|
10750
10950
|
}) {
|
|
10751
10951
|
const fillColor = isDarkMode ? "#F8F7F6" : "#0D0D0C";
|
|
10752
10952
|
const [isBlinking, setIsBlinking] = useState3(false);
|
|
10753
|
-
const timeoutRef =
|
|
10754
|
-
|
|
10953
|
+
const timeoutRef = useRef4(null);
|
|
10954
|
+
useEffect4(() => {
|
|
10755
10955
|
if (!enableBlink || !showEyes) {
|
|
10756
10956
|
return;
|
|
10757
10957
|
}
|
|
@@ -10782,7 +10982,7 @@ function CreatureIcon({
|
|
|
10782
10982
|
xmlns: "http://www.w3.org/2000/svg",
|
|
10783
10983
|
className,
|
|
10784
10984
|
children: [
|
|
10785
|
-
/* @__PURE__ */
|
|
10985
|
+
/* @__PURE__ */ jsx2(
|
|
10786
10986
|
"path",
|
|
10787
10987
|
{
|
|
10788
10988
|
fillRule: "evenodd",
|
|
@@ -10792,7 +10992,7 @@ function CreatureIcon({
|
|
|
10792
10992
|
}
|
|
10793
10993
|
),
|
|
10794
10994
|
showEyes && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10795
|
-
/* @__PURE__ */
|
|
10995
|
+
/* @__PURE__ */ jsx2(
|
|
10796
10996
|
"g",
|
|
10797
10997
|
{
|
|
10798
10998
|
style: {
|
|
@@ -10800,7 +11000,7 @@ function CreatureIcon({
|
|
|
10800
11000
|
transform: isBlinking ? "scaleY(0.1)" : "scaleY(1)",
|
|
10801
11001
|
transition: "transform 0.1s ease-out"
|
|
10802
11002
|
},
|
|
10803
|
-
children: /* @__PURE__ */
|
|
11003
|
+
children: /* @__PURE__ */ jsx2(
|
|
10804
11004
|
"path",
|
|
10805
11005
|
{
|
|
10806
11006
|
d: "M65.6051 34.48C66.4951 32.97 66.6051 31.3799 65.8451 30.9299C65.0851 30.4899 63.7451 31.3499 62.8551 32.8699C61.9651 34.3799 61.8551 35.97 62.6151 36.42C63.3751 36.86 64.7151 36 65.6051 34.48Z",
|
|
@@ -10809,7 +11009,7 @@ function CreatureIcon({
|
|
|
10809
11009
|
)
|
|
10810
11010
|
}
|
|
10811
11011
|
),
|
|
10812
|
-
/* @__PURE__ */
|
|
11012
|
+
/* @__PURE__ */ jsx2(
|
|
10813
11013
|
"g",
|
|
10814
11014
|
{
|
|
10815
11015
|
style: {
|
|
@@ -10817,7 +11017,7 @@ function CreatureIcon({
|
|
|
10817
11017
|
transform: isBlinking ? "scaleY(0.1)" : "scaleY(1)",
|
|
10818
11018
|
transition: "transform 0.1s ease-out"
|
|
10819
11019
|
},
|
|
10820
|
-
children: /* @__PURE__ */
|
|
11020
|
+
children: /* @__PURE__ */ jsx2(
|
|
10821
11021
|
"path",
|
|
10822
11022
|
{
|
|
10823
11023
|
d: "M71.7651 37.0999C72.6951 35.1499 72.6551 33.1899 71.6751 32.73C70.6951 32.27 69.1551 33.4799 68.2351 35.4299C67.3051 37.3799 67.3451 39.3399 68.3251 39.7999C69.3051 40.2599 70.8451 39.0499 71.7651 37.0999Z",
|
|
@@ -10831,10 +11031,50 @@ function CreatureIcon({
|
|
|
10831
11031
|
}
|
|
10832
11032
|
);
|
|
10833
11033
|
}
|
|
11034
|
+
|
|
11035
|
+
// src/react/experimental.ts
|
|
11036
|
+
import { useState as useState4, useEffect as useEffect5, useCallback as useCallback4, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
11037
|
+
function experimental_useWidgetState() {
|
|
11038
|
+
const client = useHostClient();
|
|
11039
|
+
const state = useSyncExternalStore3(
|
|
11040
|
+
(onStoreChange) => client.subscribe(onStoreChange),
|
|
11041
|
+
() => client.getState().widgetState,
|
|
11042
|
+
() => client.getState().widgetState
|
|
11043
|
+
);
|
|
11044
|
+
const setState = useCallback4(
|
|
11045
|
+
(newState) => {
|
|
11046
|
+
client.experimental.setWidgetState(newState);
|
|
11047
|
+
},
|
|
11048
|
+
[client]
|
|
11049
|
+
);
|
|
11050
|
+
return [state, setState];
|
|
11051
|
+
}
|
|
11052
|
+
function experimental_useTitle() {
|
|
11053
|
+
const client = useHostClient();
|
|
11054
|
+
const setTitle = useCallback4(
|
|
11055
|
+
(title) => {
|
|
11056
|
+
client.experimental.setTitle(title);
|
|
11057
|
+
},
|
|
11058
|
+
[client]
|
|
11059
|
+
);
|
|
11060
|
+
return setTitle;
|
|
11061
|
+
}
|
|
11062
|
+
function experimental_useCreatureStyles() {
|
|
11063
|
+
const client = useHostClient();
|
|
11064
|
+
const [styles, setStyles] = useState4(() => client.experimental.getCreatureStyles());
|
|
11065
|
+
useEffect5(() => {
|
|
11066
|
+
const unsub = client.on("theme-change", () => {
|
|
11067
|
+
setStyles(client.experimental.getCreatureStyles());
|
|
11068
|
+
});
|
|
11069
|
+
return unsub;
|
|
11070
|
+
}, [client]);
|
|
11071
|
+
return styles;
|
|
11072
|
+
}
|
|
10834
11073
|
export {
|
|
10835
11074
|
ChatGptAdapter,
|
|
10836
11075
|
CreatureAdapter,
|
|
10837
11076
|
CreatureIcon,
|
|
11077
|
+
HostProvider,
|
|
10838
11078
|
KNOWN_HOSTS,
|
|
10839
11079
|
McpAppsAdapter,
|
|
10840
11080
|
StandaloneAdapter,
|
|
@@ -10846,11 +11086,16 @@ export {
|
|
|
10846
11086
|
createHostAsync,
|
|
10847
11087
|
createWebSocket,
|
|
10848
11088
|
detectEnvironment,
|
|
11089
|
+
experimental_useCreatureStyles,
|
|
11090
|
+
experimental_useTitle,
|
|
11091
|
+
experimental_useWidgetState,
|
|
10849
11092
|
VU as getDocumentTheme,
|
|
10850
11093
|
getHostIdentity,
|
|
10851
11094
|
isHost,
|
|
10852
11095
|
parseHostUserAgent,
|
|
10853
11096
|
useHost,
|
|
11097
|
+
useHostClient,
|
|
11098
|
+
useHostClientOptional,
|
|
10854
11099
|
useToolResult,
|
|
10855
11100
|
useWebSocket
|
|
10856
11101
|
};
|