@creature-ai/sdk 0.1.2 → 0.1.3
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 +299 -72
- package/dist/core/index.js +235 -267
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.d.ts +47 -51
- package/dist/react/index.js +249 -311
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.d.ts +187 -218
- package/dist/server/index.js +567 -521
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/types-JBEuUzEi.d.ts +0 -186
package/dist/react/index.js
CHANGED
|
@@ -9328,8 +9328,11 @@ var Subscribable = class {
|
|
|
9328
9328
|
}
|
|
9329
9329
|
};
|
|
9330
9330
|
|
|
9331
|
-
// src/core/
|
|
9332
|
-
var
|
|
9331
|
+
// src/core/McpAppHostClient.ts
|
|
9332
|
+
var McpAppHostClient = class extends Subscribable {
|
|
9333
|
+
// ============================================================================
|
|
9334
|
+
// Private Properties
|
|
9335
|
+
// ============================================================================
|
|
9333
9336
|
state = {
|
|
9334
9337
|
isReady: false,
|
|
9335
9338
|
environment: "mcp-apps",
|
|
@@ -9338,18 +9341,22 @@ var McpHostClient = class extends Subscribable {
|
|
|
9338
9341
|
config;
|
|
9339
9342
|
app = null;
|
|
9340
9343
|
connected = false;
|
|
9344
|
+
// ============================================================================
|
|
9345
|
+
// Constructor
|
|
9346
|
+
// ============================================================================
|
|
9341
9347
|
constructor(config) {
|
|
9342
9348
|
super();
|
|
9343
9349
|
this.config = config;
|
|
9344
9350
|
}
|
|
9351
|
+
// ============================================================================
|
|
9352
|
+
// Public API
|
|
9353
|
+
// ============================================================================
|
|
9354
|
+
/**
|
|
9355
|
+
* Get the current client state.
|
|
9356
|
+
*/
|
|
9345
9357
|
getState() {
|
|
9346
9358
|
return this.state;
|
|
9347
9359
|
}
|
|
9348
|
-
setState(partial) {
|
|
9349
|
-
const prev = this.state;
|
|
9350
|
-
this.state = { ...this.state, ...partial };
|
|
9351
|
-
this.notifyStateChange(this.state, prev);
|
|
9352
|
-
}
|
|
9353
9360
|
/**
|
|
9354
9361
|
* Connect to the MCP Apps host.
|
|
9355
9362
|
*
|
|
@@ -9371,90 +9378,6 @@ var McpHostClient = class extends Subscribable {
|
|
|
9371
9378
|
this.setupHandlers();
|
|
9372
9379
|
this.initiateConnection();
|
|
9373
9380
|
}
|
|
9374
|
-
/**
|
|
9375
|
-
* Set up notification handlers on the App instance.
|
|
9376
|
-
*
|
|
9377
|
-
* Maps the official SDK's callback pattern to our event emitter pattern,
|
|
9378
|
-
* allowing consumers to use `.on("tool-result", ...)` etc.
|
|
9379
|
-
*/
|
|
9380
|
-
setupHandlers() {
|
|
9381
|
-
if (!this.app) return;
|
|
9382
|
-
this.app.ontoolinput = (params) => {
|
|
9383
|
-
console.debug(`[${this.config.name}] Received tool-input`, { args: params.arguments });
|
|
9384
|
-
this.emit("tool-input", params.arguments || {});
|
|
9385
|
-
};
|
|
9386
|
-
this.app.ontoolresult = (params) => {
|
|
9387
|
-
console.log(`[McpHostClient] ontoolresult called`, {
|
|
9388
|
-
isError: params.isError,
|
|
9389
|
-
source: params.source,
|
|
9390
|
-
hasContent: !!params.content,
|
|
9391
|
-
hasStructuredContent: !!params.structuredContent,
|
|
9392
|
-
structuredContent: params.structuredContent
|
|
9393
|
-
});
|
|
9394
|
-
const textContent = params.content?.filter((item) => item.type === "text").map((item) => ({ type: item.type, text: item.text }));
|
|
9395
|
-
const result = {
|
|
9396
|
-
content: textContent,
|
|
9397
|
-
structuredContent: params.structuredContent,
|
|
9398
|
-
isError: params.isError,
|
|
9399
|
-
source: params.source
|
|
9400
|
-
};
|
|
9401
|
-
console.log(`[McpHostClient] Emitting tool-result event`, result);
|
|
9402
|
-
this.emit("tool-result", result);
|
|
9403
|
-
};
|
|
9404
|
-
this.app.onhostcontextchanged = (params) => {
|
|
9405
|
-
console.debug(`[${this.config.name}] Host context changed`, { theme: params.theme });
|
|
9406
|
-
if (params.theme) {
|
|
9407
|
-
YU(params.theme);
|
|
9408
|
-
this.emit("theme-change", params.theme);
|
|
9409
|
-
}
|
|
9410
|
-
if (params.styles?.variables) {
|
|
9411
|
-
QU(params.styles.variables);
|
|
9412
|
-
}
|
|
9413
|
-
if (params.styles?.css?.fonts) {
|
|
9414
|
-
qU(params.styles.css.fonts);
|
|
9415
|
-
}
|
|
9416
|
-
};
|
|
9417
|
-
this.app.onteardown = async (_params, _extra) => {
|
|
9418
|
-
console.debug(`[${this.config.name}] Teardown requested`);
|
|
9419
|
-
await this.emit("teardown");
|
|
9420
|
-
return {};
|
|
9421
|
-
};
|
|
9422
|
-
}
|
|
9423
|
-
/**
|
|
9424
|
-
* Initiate connection using PostMessageTransport.
|
|
9425
|
-
*
|
|
9426
|
-
* The SDK's App.connect() handles the protocol handshake correctly:
|
|
9427
|
-
* the guest (App) sends `ui/initialize` to the host.
|
|
9428
|
-
*/
|
|
9429
|
-
async initiateConnection() {
|
|
9430
|
-
if (!this.app) {
|
|
9431
|
-
return;
|
|
9432
|
-
}
|
|
9433
|
-
try {
|
|
9434
|
-
const transport = new Yn(window.parent, window.parent);
|
|
9435
|
-
await this.app.connect(transport);
|
|
9436
|
-
const hostContext = this.app.getHostContext();
|
|
9437
|
-
console.debug(`[${this.config.name}] Connected to host`, { theme: hostContext?.theme });
|
|
9438
|
-
if (hostContext?.theme) {
|
|
9439
|
-
YU(hostContext.theme);
|
|
9440
|
-
this.emit("theme-change", hostContext.theme);
|
|
9441
|
-
}
|
|
9442
|
-
if (hostContext?.styles?.variables) {
|
|
9443
|
-
QU(hostContext.styles.variables);
|
|
9444
|
-
}
|
|
9445
|
-
if (hostContext?.styles?.css?.fonts) {
|
|
9446
|
-
qU(hostContext.styles.css.fonts);
|
|
9447
|
-
}
|
|
9448
|
-
const widgetState = hostContext?.widgetState;
|
|
9449
|
-
if (widgetState) {
|
|
9450
|
-
this.setState({ widgetState });
|
|
9451
|
-
this.emit("widget-state-change", widgetState);
|
|
9452
|
-
}
|
|
9453
|
-
this.setState({ isReady: true });
|
|
9454
|
-
} catch (error) {
|
|
9455
|
-
console.error(`[${this.config.name}] Connection failed`, { error });
|
|
9456
|
-
}
|
|
9457
|
-
}
|
|
9458
9381
|
/**
|
|
9459
9382
|
* Disconnect from the host.
|
|
9460
9383
|
*
|
|
@@ -9487,9 +9410,8 @@ var McpHostClient = class extends Subscribable {
|
|
|
9487
9410
|
name: toolName,
|
|
9488
9411
|
arguments: args
|
|
9489
9412
|
});
|
|
9490
|
-
const textContent = sdkResult.content?.filter((item) => item.type === "text").map((item) => ({ type: item.type, text: item.text }));
|
|
9491
9413
|
const result = {
|
|
9492
|
-
content:
|
|
9414
|
+
content: this.extractTextContent(sdkResult.content),
|
|
9493
9415
|
structuredContent: sdkResult.structuredContent,
|
|
9494
9416
|
isError: sdkResult.isError
|
|
9495
9417
|
};
|
|
@@ -9544,8 +9466,6 @@ var McpHostClient = class extends Subscribable {
|
|
|
9544
9466
|
* to the host. Logs appear in the unified DevConsole alongside server logs,
|
|
9545
9467
|
* with appropriate color coding based on level.
|
|
9546
9468
|
*
|
|
9547
|
-
* The logger name is automatically set to the app name from config.
|
|
9548
|
-
*
|
|
9549
9469
|
* @param level - Log severity level (debug, info, notice, warning, error)
|
|
9550
9470
|
* @param message - Log message
|
|
9551
9471
|
* @param data - Optional structured data to include with the log
|
|
@@ -9562,10 +9482,113 @@ var McpHostClient = class extends Subscribable {
|
|
|
9562
9482
|
data: data ? { message, ...data } : message
|
|
9563
9483
|
});
|
|
9564
9484
|
}
|
|
9485
|
+
// ============================================================================
|
|
9486
|
+
// Private Methods
|
|
9487
|
+
// ============================================================================
|
|
9488
|
+
/**
|
|
9489
|
+
* Update internal state and notify listeners.
|
|
9490
|
+
*/
|
|
9491
|
+
setState(partial) {
|
|
9492
|
+
const prev = this.state;
|
|
9493
|
+
this.state = { ...this.state, ...partial };
|
|
9494
|
+
this.notifyStateChange(this.state, prev);
|
|
9495
|
+
}
|
|
9496
|
+
/**
|
|
9497
|
+
* Set up notification handlers on the App instance.
|
|
9498
|
+
*
|
|
9499
|
+
* Maps the official SDK's callback pattern to our event emitter pattern,
|
|
9500
|
+
* allowing consumers to use `.on("tool-result", ...)` etc.
|
|
9501
|
+
*/
|
|
9502
|
+
setupHandlers() {
|
|
9503
|
+
if (!this.app) return;
|
|
9504
|
+
this.app.ontoolinput = (params) => {
|
|
9505
|
+
console.debug(`[${this.config.name}] Received tool-input`, { args: params.arguments });
|
|
9506
|
+
this.emit("tool-input", params.arguments || {});
|
|
9507
|
+
};
|
|
9508
|
+
this.app.ontoolresult = (params) => {
|
|
9509
|
+
console.log(`[McpAppHostClient] ontoolresult called`, {
|
|
9510
|
+
isError: params.isError,
|
|
9511
|
+
source: params.source,
|
|
9512
|
+
hasContent: !!params.content,
|
|
9513
|
+
hasStructuredContent: !!params.structuredContent,
|
|
9514
|
+
structuredContent: params.structuredContent
|
|
9515
|
+
});
|
|
9516
|
+
const result = {
|
|
9517
|
+
content: this.extractTextContent(params.content),
|
|
9518
|
+
structuredContent: params.structuredContent,
|
|
9519
|
+
isError: params.isError,
|
|
9520
|
+
source: params.source
|
|
9521
|
+
};
|
|
9522
|
+
console.log(`[McpAppHostClient] Emitting tool-result event`, result);
|
|
9523
|
+
this.emit("tool-result", result);
|
|
9524
|
+
};
|
|
9525
|
+
this.app.onhostcontextchanged = (params) => {
|
|
9526
|
+
console.debug(`[${this.config.name}] Host context changed`, { theme: params.theme });
|
|
9527
|
+
this.applyHostContext(params);
|
|
9528
|
+
};
|
|
9529
|
+
this.app.onteardown = async (_params, _extra) => {
|
|
9530
|
+
console.debug(`[${this.config.name}] Teardown requested`);
|
|
9531
|
+
await this.emit("teardown");
|
|
9532
|
+
return {};
|
|
9533
|
+
};
|
|
9534
|
+
}
|
|
9535
|
+
/**
|
|
9536
|
+
* Initiate connection using PostMessageTransport.
|
|
9537
|
+
*
|
|
9538
|
+
* The SDK's App.connect() handles the protocol handshake correctly:
|
|
9539
|
+
* the guest (App) sends `ui/initialize` to the host.
|
|
9540
|
+
*/
|
|
9541
|
+
async initiateConnection() {
|
|
9542
|
+
if (!this.app) {
|
|
9543
|
+
return;
|
|
9544
|
+
}
|
|
9545
|
+
try {
|
|
9546
|
+
const transport = new Yn(window.parent, window.parent);
|
|
9547
|
+
await this.app.connect(transport);
|
|
9548
|
+
const hostContext = this.app.getHostContext();
|
|
9549
|
+
console.debug(`[${this.config.name}] Connected to host`, { theme: hostContext?.theme });
|
|
9550
|
+
if (hostContext) {
|
|
9551
|
+
this.applyHostContext(hostContext);
|
|
9552
|
+
const widgetState = hostContext.widgetState;
|
|
9553
|
+
if (widgetState) {
|
|
9554
|
+
this.setState({ widgetState });
|
|
9555
|
+
this.emit("widget-state-change", widgetState);
|
|
9556
|
+
}
|
|
9557
|
+
}
|
|
9558
|
+
this.setState({ isReady: true });
|
|
9559
|
+
} catch (error) {
|
|
9560
|
+
console.error(`[${this.config.name}] Connection failed`, { error });
|
|
9561
|
+
}
|
|
9562
|
+
}
|
|
9563
|
+
/**
|
|
9564
|
+
* Apply theme, styles, and fonts from host context.
|
|
9565
|
+
*/
|
|
9566
|
+
applyHostContext(context) {
|
|
9567
|
+
if (context.theme) {
|
|
9568
|
+
YU(context.theme);
|
|
9569
|
+
this.emit("theme-change", context.theme);
|
|
9570
|
+
}
|
|
9571
|
+
if (context.styles?.variables) {
|
|
9572
|
+
QU(context.styles.variables);
|
|
9573
|
+
}
|
|
9574
|
+
if (context.styles?.css?.fonts) {
|
|
9575
|
+
qU(context.styles.css.fonts);
|
|
9576
|
+
}
|
|
9577
|
+
}
|
|
9578
|
+
/**
|
|
9579
|
+
* Extract text content from SDK result content array.
|
|
9580
|
+
* Filters to only include text items since our ToolResult type expects text.
|
|
9581
|
+
*/
|
|
9582
|
+
extractTextContent(content) {
|
|
9583
|
+
return content?.filter((item) => item.type === "text").map((item) => ({ type: item.type, text: item.text }));
|
|
9584
|
+
}
|
|
9565
9585
|
};
|
|
9566
9586
|
|
|
9567
|
-
// src/core/
|
|
9568
|
-
var
|
|
9587
|
+
// src/core/ChatGptAppHostClient.ts
|
|
9588
|
+
var ChatGptAppHostClient = class extends Subscribable {
|
|
9589
|
+
// ============================================================================
|
|
9590
|
+
// Private Properties
|
|
9591
|
+
// ============================================================================
|
|
9569
9592
|
state = {
|
|
9570
9593
|
isReady: false,
|
|
9571
9594
|
environment: "chatgpt",
|
|
@@ -9575,24 +9598,39 @@ var ChatGPTHostClient = class extends Subscribable {
|
|
|
9575
9598
|
connected = false;
|
|
9576
9599
|
hasProcessedInitialData = false;
|
|
9577
9600
|
globalsHandler = null;
|
|
9601
|
+
// ============================================================================
|
|
9602
|
+
// Constructor
|
|
9603
|
+
// ============================================================================
|
|
9578
9604
|
constructor(config) {
|
|
9579
9605
|
super();
|
|
9580
9606
|
this.config = config;
|
|
9581
9607
|
}
|
|
9608
|
+
// ============================================================================
|
|
9609
|
+
// Public API
|
|
9610
|
+
// ============================================================================
|
|
9611
|
+
/**
|
|
9612
|
+
* Get the current client state.
|
|
9613
|
+
*/
|
|
9582
9614
|
getState() {
|
|
9583
9615
|
return this.state;
|
|
9584
9616
|
}
|
|
9585
|
-
|
|
9586
|
-
|
|
9587
|
-
|
|
9588
|
-
|
|
9589
|
-
|
|
9617
|
+
/**
|
|
9618
|
+
* Connect to the ChatGPT host.
|
|
9619
|
+
*
|
|
9620
|
+
* Processes initial data from `window.openai` and sets up a listener
|
|
9621
|
+
* for subsequent `openai:set_globals` events.
|
|
9622
|
+
*/
|
|
9590
9623
|
connect() {
|
|
9591
9624
|
if (this.connected) return;
|
|
9592
9625
|
this.connected = true;
|
|
9593
9626
|
this.processInitialData();
|
|
9594
9627
|
this.setupGlobalsListener();
|
|
9595
9628
|
}
|
|
9629
|
+
/**
|
|
9630
|
+
* Disconnect from the host.
|
|
9631
|
+
*
|
|
9632
|
+
* Removes the globals event listener.
|
|
9633
|
+
*/
|
|
9596
9634
|
disconnect() {
|
|
9597
9635
|
if (!this.connected) return;
|
|
9598
9636
|
this.connected = false;
|
|
@@ -9601,39 +9639,13 @@ var ChatGPTHostClient = class extends Subscribable {
|
|
|
9601
9639
|
this.globalsHandler = null;
|
|
9602
9640
|
}
|
|
9603
9641
|
}
|
|
9604
|
-
|
|
9605
|
-
|
|
9606
|
-
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
this.hasProcessedInitialData = true;
|
|
9612
|
-
this.setState({ isReady: true });
|
|
9613
|
-
if (openai.toolOutput) {
|
|
9614
|
-
this.emit("tool-input", openai.toolOutput);
|
|
9615
|
-
this.emit("tool-result", { structuredContent: openai.toolOutput });
|
|
9616
|
-
}
|
|
9617
|
-
if (openai.widgetState) {
|
|
9618
|
-
this.setState({ widgetState: openai.widgetState });
|
|
9619
|
-
this.emit("widget-state-change", openai.widgetState);
|
|
9620
|
-
}
|
|
9621
|
-
}
|
|
9622
|
-
setupGlobalsListener() {
|
|
9623
|
-
this.globalsHandler = (event) => {
|
|
9624
|
-
const customEvent = event;
|
|
9625
|
-
const globals = customEvent.detail?.globals;
|
|
9626
|
-
if (globals?.toolOutput) {
|
|
9627
|
-
this.emit("tool-input", globals.toolOutput);
|
|
9628
|
-
this.emit("tool-result", { structuredContent: globals.toolOutput });
|
|
9629
|
-
}
|
|
9630
|
-
if (globals?.widgetState !== void 0) {
|
|
9631
|
-
this.setState({ widgetState: globals.widgetState });
|
|
9632
|
-
this.emit("widget-state-change", globals.widgetState);
|
|
9633
|
-
}
|
|
9634
|
-
};
|
|
9635
|
-
window.addEventListener("openai:set_globals", this.globalsHandler, { passive: true });
|
|
9636
|
-
}
|
|
9642
|
+
/**
|
|
9643
|
+
* Call a tool on the MCP server via the ChatGPT bridge.
|
|
9644
|
+
*
|
|
9645
|
+
* @param toolName - Name of the tool to call
|
|
9646
|
+
* @param args - Arguments to pass to the tool
|
|
9647
|
+
* @returns Tool result with content and structuredContent
|
|
9648
|
+
*/
|
|
9637
9649
|
async callTool(toolName, args) {
|
|
9638
9650
|
const openai = window.openai;
|
|
9639
9651
|
if (!openai?.callTool) {
|
|
@@ -9651,8 +9663,18 @@ var ChatGPTHostClient = class extends Subscribable {
|
|
|
9651
9663
|
this.emit("tool-result", result);
|
|
9652
9664
|
return result;
|
|
9653
9665
|
}
|
|
9666
|
+
/**
|
|
9667
|
+
* Send a notification to the host.
|
|
9668
|
+
*
|
|
9669
|
+
* No-op on ChatGPT — notifications are not supported.
|
|
9670
|
+
*/
|
|
9654
9671
|
sendNotification(_method, _params) {
|
|
9655
9672
|
}
|
|
9673
|
+
/**
|
|
9674
|
+
* Set widget state and sync with the ChatGPT host.
|
|
9675
|
+
*
|
|
9676
|
+
* @param state - New widget state (or null to clear)
|
|
9677
|
+
*/
|
|
9656
9678
|
setWidgetState(state) {
|
|
9657
9679
|
this.setState({ widgetState: state });
|
|
9658
9680
|
if (window.openai?.setWidgetState) {
|
|
@@ -9664,7 +9686,7 @@ var ChatGPTHostClient = class extends Subscribable {
|
|
|
9664
9686
|
* Log a message to the console.
|
|
9665
9687
|
*
|
|
9666
9688
|
* ChatGPT doesn't have a DevConsole, so logs go to browser console only.
|
|
9667
|
-
* This provides API parity with
|
|
9689
|
+
* This provides API parity with McpAppHostClient.
|
|
9668
9690
|
*
|
|
9669
9691
|
* @param level - Log severity level
|
|
9670
9692
|
* @param message - Log message
|
|
@@ -9674,6 +9696,68 @@ var ChatGPTHostClient = class extends Subscribable {
|
|
|
9674
9696
|
const consoleMethod = level === "error" ? "error" : level === "warning" ? "warn" : "log";
|
|
9675
9697
|
console[consoleMethod](`[${this.config.name}]`, message, data ?? "");
|
|
9676
9698
|
}
|
|
9699
|
+
// ============================================================================
|
|
9700
|
+
// Private Methods
|
|
9701
|
+
// ============================================================================
|
|
9702
|
+
/**
|
|
9703
|
+
* Update internal state and notify listeners.
|
|
9704
|
+
*/
|
|
9705
|
+
setState(partial) {
|
|
9706
|
+
const prev = this.state;
|
|
9707
|
+
this.state = { ...this.state, ...partial };
|
|
9708
|
+
this.notifyStateChange(this.state, prev);
|
|
9709
|
+
}
|
|
9710
|
+
/**
|
|
9711
|
+
* Process initial data from `window.openai`.
|
|
9712
|
+
*
|
|
9713
|
+
* Called once on connect to handle any tool output or widget state
|
|
9714
|
+
* that was set before the client connected.
|
|
9715
|
+
*/
|
|
9716
|
+
processInitialData() {
|
|
9717
|
+
if (this.hasProcessedInitialData) return;
|
|
9718
|
+
const openai = window.openai;
|
|
9719
|
+
if (!openai) {
|
|
9720
|
+
console.warn("[SDK] window.openai not available");
|
|
9721
|
+
return;
|
|
9722
|
+
}
|
|
9723
|
+
this.hasProcessedInitialData = true;
|
|
9724
|
+
this.setState({ isReady: true });
|
|
9725
|
+
if (openai.toolOutput) {
|
|
9726
|
+
this.emit("tool-input", openai.toolOutput);
|
|
9727
|
+
this.emit("tool-result", { structuredContent: openai.toolOutput });
|
|
9728
|
+
}
|
|
9729
|
+
if (openai.widgetState) {
|
|
9730
|
+
this.setState({ widgetState: openai.widgetState });
|
|
9731
|
+
this.emit("widget-state-change", openai.widgetState);
|
|
9732
|
+
}
|
|
9733
|
+
}
|
|
9734
|
+
/**
|
|
9735
|
+
* Set up listener for `openai:set_globals` events.
|
|
9736
|
+
*
|
|
9737
|
+
* ChatGPT dispatches this event when tool output or widget state
|
|
9738
|
+
* changes after initial load.
|
|
9739
|
+
*/
|
|
9740
|
+
setupGlobalsListener() {
|
|
9741
|
+
this.globalsHandler = (event) => {
|
|
9742
|
+
const customEvent = event;
|
|
9743
|
+
const globals = customEvent.detail?.globals;
|
|
9744
|
+
if (globals?.toolOutput) {
|
|
9745
|
+
this.emit("tool-input", globals.toolOutput);
|
|
9746
|
+
this.emit("tool-result", { structuredContent: globals.toolOutput });
|
|
9747
|
+
}
|
|
9748
|
+
if (globals?.widgetState !== void 0) {
|
|
9749
|
+
this.setState({ widgetState: globals.widgetState });
|
|
9750
|
+
this.emit("widget-state-change", globals.widgetState);
|
|
9751
|
+
}
|
|
9752
|
+
};
|
|
9753
|
+
window.addEventListener("openai:set_globals", this.globalsHandler, { passive: true });
|
|
9754
|
+
}
|
|
9755
|
+
/**
|
|
9756
|
+
* Request a display mode change from the ChatGPT host.
|
|
9757
|
+
*
|
|
9758
|
+
* @param params - Display mode to request
|
|
9759
|
+
* @returns The resulting display mode
|
|
9760
|
+
*/
|
|
9677
9761
|
async requestDisplayMode(params) {
|
|
9678
9762
|
const openai = window.openai;
|
|
9679
9763
|
if (openai?.requestDisplayMode) {
|
|
@@ -9698,123 +9782,8 @@ function detectEnvironment() {
|
|
|
9698
9782
|
return "standalone";
|
|
9699
9783
|
}
|
|
9700
9784
|
|
|
9701
|
-
// src/core/
|
|
9702
|
-
|
|
9703
|
-
id;
|
|
9704
|
-
_state;
|
|
9705
|
-
listeners = /* @__PURE__ */ new Set();
|
|
9706
|
-
hostClient = null;
|
|
9707
|
-
hostUnsubscribe = null;
|
|
9708
|
-
constructor(initialState = {}, options = {}) {
|
|
9709
|
-
this.id = options.id ?? this.generateId();
|
|
9710
|
-
this._state = {
|
|
9711
|
-
internal: initialState.internal ?? {},
|
|
9712
|
-
backend: initialState.backend ?? {},
|
|
9713
|
-
ui: initialState.ui ?? null
|
|
9714
|
-
};
|
|
9715
|
-
}
|
|
9716
|
-
generateId() {
|
|
9717
|
-
return `session_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
9718
|
-
}
|
|
9719
|
-
get state() {
|
|
9720
|
-
return this._state;
|
|
9721
|
-
}
|
|
9722
|
-
get internal() {
|
|
9723
|
-
return this._state.internal;
|
|
9724
|
-
}
|
|
9725
|
-
get backend() {
|
|
9726
|
-
return this._state.backend;
|
|
9727
|
-
}
|
|
9728
|
-
get ui() {
|
|
9729
|
-
return this._state.ui;
|
|
9730
|
-
}
|
|
9731
|
-
subscribe(listener) {
|
|
9732
|
-
this.listeners.add(listener);
|
|
9733
|
-
return () => {
|
|
9734
|
-
this.listeners.delete(listener);
|
|
9735
|
-
};
|
|
9736
|
-
}
|
|
9737
|
-
notify(prevState) {
|
|
9738
|
-
this.listeners.forEach((listener) => listener(this._state, prevState));
|
|
9739
|
-
}
|
|
9740
|
-
setState(partial) {
|
|
9741
|
-
const prev = this._state;
|
|
9742
|
-
this._state = {
|
|
9743
|
-
internal: partial.internal !== void 0 ? { ...prev.internal, ...partial.internal } : prev.internal,
|
|
9744
|
-
backend: partial.backend !== void 0 ? { ...prev.backend, ...partial.backend } : prev.backend,
|
|
9745
|
-
ui: partial.ui !== void 0 ? partial.ui : prev.ui
|
|
9746
|
-
};
|
|
9747
|
-
this.notify(prev);
|
|
9748
|
-
}
|
|
9749
|
-
setInternal(internal) {
|
|
9750
|
-
const prev = this._state;
|
|
9751
|
-
this._state = {
|
|
9752
|
-
...prev,
|
|
9753
|
-
internal: { ...prev.internal, ...internal }
|
|
9754
|
-
};
|
|
9755
|
-
this.notify(prev);
|
|
9756
|
-
}
|
|
9757
|
-
setBackend(backend) {
|
|
9758
|
-
const prev = this._state;
|
|
9759
|
-
this._state = {
|
|
9760
|
-
...prev,
|
|
9761
|
-
backend: { ...prev.backend, ...backend }
|
|
9762
|
-
};
|
|
9763
|
-
this.notify(prev);
|
|
9764
|
-
}
|
|
9765
|
-
setUi(ui2) {
|
|
9766
|
-
console.log(`[AppSession:${this.id}] setUi`, ui2);
|
|
9767
|
-
const prev = this._state;
|
|
9768
|
-
this._state = { ...prev, ui: ui2 };
|
|
9769
|
-
this.notify(prev);
|
|
9770
|
-
if (this.hostClient) {
|
|
9771
|
-
this.hostClient.setWidgetState(ui2);
|
|
9772
|
-
}
|
|
9773
|
-
}
|
|
9774
|
-
updateUi(partial) {
|
|
9775
|
-
const prev = this._state;
|
|
9776
|
-
const newUi = prev.ui !== null ? { ...prev.ui, ...partial } : partial;
|
|
9777
|
-
this._state = { ...prev, ui: newUi };
|
|
9778
|
-
this.notify(prev);
|
|
9779
|
-
if (this.hostClient) {
|
|
9780
|
-
this.hostClient.setWidgetState(newUi);
|
|
9781
|
-
}
|
|
9782
|
-
}
|
|
9783
|
-
bindHost(host) {
|
|
9784
|
-
this.hostClient = host;
|
|
9785
|
-
console.log(`[AppSession:${this.id}] Binding to host`);
|
|
9786
|
-
const currentHostState = host.getState();
|
|
9787
|
-
if (currentHostState.widgetState !== null && currentHostState.widgetState !== void 0) {
|
|
9788
|
-
console.log(`[AppSession:${this.id}] Restoring UI state from host`, currentHostState.widgetState);
|
|
9789
|
-
const prev = this._state;
|
|
9790
|
-
this._state = { ...prev, ui: currentHostState.widgetState };
|
|
9791
|
-
this.notify(prev);
|
|
9792
|
-
}
|
|
9793
|
-
this.hostUnsubscribe = host.on("widget-state-change", (widgetState) => {
|
|
9794
|
-
console.log(`[AppSession:${this.id}] Host widget state changed`, widgetState);
|
|
9795
|
-
const prev = this._state;
|
|
9796
|
-
this._state = { ...prev, ui: widgetState };
|
|
9797
|
-
this.notify(prev);
|
|
9798
|
-
});
|
|
9799
|
-
return () => {
|
|
9800
|
-
this.unbindHost();
|
|
9801
|
-
};
|
|
9802
|
-
}
|
|
9803
|
-
unbindHost() {
|
|
9804
|
-
console.log(`[AppSession:${this.id}] Unbinding from host`);
|
|
9805
|
-
if (this.hostUnsubscribe) {
|
|
9806
|
-
this.hostUnsubscribe();
|
|
9807
|
-
this.hostUnsubscribe = null;
|
|
9808
|
-
}
|
|
9809
|
-
this.hostClient = null;
|
|
9810
|
-
}
|
|
9811
|
-
injectAppSessionId(data) {
|
|
9812
|
-
return { ...data, appSessionId: this.id };
|
|
9813
|
-
}
|
|
9814
|
-
};
|
|
9815
|
-
|
|
9816
|
-
// src/core/channel.ts
|
|
9817
|
-
function createChannel(url, config = {}) {
|
|
9785
|
+
// src/core/websocket.ts
|
|
9786
|
+
function createWebSocket(url, config = {}) {
|
|
9818
9787
|
const {
|
|
9819
9788
|
onMessage,
|
|
9820
9789
|
onStatusChange,
|
|
@@ -9834,36 +9803,36 @@ function createChannel(url, config = {}) {
|
|
|
9834
9803
|
};
|
|
9835
9804
|
const connect = () => {
|
|
9836
9805
|
if (ws?.readyState === WebSocket.OPEN || ws?.readyState === WebSocket.CONNECTING) {
|
|
9837
|
-
console.log("[
|
|
9806
|
+
console.log("[WebSocket] Already connected/connecting to:", url);
|
|
9838
9807
|
return;
|
|
9839
9808
|
}
|
|
9840
9809
|
intentionalClose = false;
|
|
9841
9810
|
setStatus("connecting");
|
|
9842
|
-
console.log("[
|
|
9811
|
+
console.log("[WebSocket] Connecting to:", url);
|
|
9843
9812
|
try {
|
|
9844
9813
|
ws = new WebSocket(url);
|
|
9845
9814
|
} catch (e2) {
|
|
9846
|
-
console.error("[
|
|
9815
|
+
console.error("[WebSocket] Failed to create WebSocket:", e2);
|
|
9847
9816
|
setStatus("error", "Failed to create WebSocket");
|
|
9848
9817
|
scheduleReconnect();
|
|
9849
9818
|
return;
|
|
9850
9819
|
}
|
|
9851
9820
|
ws.onopen = () => {
|
|
9852
|
-
console.log("[
|
|
9821
|
+
console.log("[WebSocket] Connected to:", url);
|
|
9853
9822
|
reconnectAttempts = 0;
|
|
9854
9823
|
setStatus("connected");
|
|
9855
9824
|
};
|
|
9856
9825
|
ws.onmessage = (event) => {
|
|
9857
9826
|
try {
|
|
9858
9827
|
const message = JSON.parse(event.data);
|
|
9859
|
-
console.log("[
|
|
9828
|
+
console.log("[WebSocket] Received message:", message);
|
|
9860
9829
|
onMessage?.(message);
|
|
9861
9830
|
} catch (e2) {
|
|
9862
|
-
console.error("[
|
|
9831
|
+
console.error("[WebSocket] Failed to parse message:", e2);
|
|
9863
9832
|
}
|
|
9864
9833
|
};
|
|
9865
9834
|
ws.onerror = (e2) => {
|
|
9866
|
-
console.error("[
|
|
9835
|
+
console.error("[WebSocket] Error:", e2);
|
|
9867
9836
|
setStatus("error", "Connection error");
|
|
9868
9837
|
};
|
|
9869
9838
|
ws.onclose = (event) => {
|
|
@@ -9873,7 +9842,7 @@ function createChannel(url, config = {}) {
|
|
|
9873
9842
|
return;
|
|
9874
9843
|
}
|
|
9875
9844
|
if (event.code === 4004) {
|
|
9876
|
-
setStatus("error", "
|
|
9845
|
+
setStatus("error", "Instance WebSocket not found");
|
|
9877
9846
|
return;
|
|
9878
9847
|
}
|
|
9879
9848
|
scheduleReconnect();
|
|
@@ -9921,9 +9890,9 @@ function createChannel(url, config = {}) {
|
|
|
9921
9890
|
function createHost(config) {
|
|
9922
9891
|
const environment = detectEnvironment();
|
|
9923
9892
|
if (environment === "chatgpt") {
|
|
9924
|
-
return new
|
|
9893
|
+
return new ChatGptAppHostClient(config);
|
|
9925
9894
|
}
|
|
9926
|
-
return new
|
|
9895
|
+
return new McpAppHostClient(config);
|
|
9927
9896
|
}
|
|
9928
9897
|
|
|
9929
9898
|
// src/react/useHost.ts
|
|
@@ -10026,17 +9995,21 @@ function useHost(config) {
|
|
|
10026
9995
|
import { useState, useCallback } from "react";
|
|
10027
9996
|
function useToolResult() {
|
|
10028
9997
|
const [data, setData] = useState(null);
|
|
9998
|
+
const [instanceId, setInstanceId] = useState(null);
|
|
10029
9999
|
const [title, setTitle] = useState(null);
|
|
10030
10000
|
const [isError, setIsError] = useState(false);
|
|
10031
10001
|
const [text, setText] = useState(null);
|
|
10032
10002
|
const onToolResult = useCallback((result) => {
|
|
10033
10003
|
const structured = result.structuredContent;
|
|
10034
10004
|
if (structured) {
|
|
10035
|
-
const { title: resultTitle, ...rest } = structured;
|
|
10005
|
+
const { title: resultTitle, instanceId: resultInstanceId, ...rest } = structured;
|
|
10036
10006
|
setData(rest);
|
|
10037
10007
|
if (resultTitle) {
|
|
10038
10008
|
setTitle(resultTitle);
|
|
10039
10009
|
}
|
|
10010
|
+
if (resultInstanceId) {
|
|
10011
|
+
setInstanceId(resultInstanceId);
|
|
10012
|
+
}
|
|
10040
10013
|
}
|
|
10041
10014
|
setIsError(result.isError || false);
|
|
10042
10015
|
if (result.content?.[0]?.text) {
|
|
@@ -10045,12 +10018,14 @@ function useToolResult() {
|
|
|
10045
10018
|
}, []);
|
|
10046
10019
|
const reset = useCallback(() => {
|
|
10047
10020
|
setData(null);
|
|
10021
|
+
setInstanceId(null);
|
|
10048
10022
|
setTitle(null);
|
|
10049
10023
|
setIsError(false);
|
|
10050
10024
|
setText(null);
|
|
10051
10025
|
}, []);
|
|
10052
10026
|
return {
|
|
10053
10027
|
data,
|
|
10028
|
+
instanceId,
|
|
10054
10029
|
title,
|
|
10055
10030
|
isError,
|
|
10056
10031
|
text,
|
|
@@ -10091,9 +10066,9 @@ function useWidgetState(initialState) {
|
|
|
10091
10066
|
return [localState, setState];
|
|
10092
10067
|
}
|
|
10093
10068
|
|
|
10094
|
-
// src/react/
|
|
10069
|
+
// src/react/useWebSocket.ts
|
|
10095
10070
|
import { useEffect as useEffect3, useRef as useRef2, useMemo as useMemo2, useCallback as useCallback3, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
10096
|
-
function
|
|
10071
|
+
function useWebSocket(url, config = {}) {
|
|
10097
10072
|
const { onMessage, enabled = true } = config;
|
|
10098
10073
|
const onMessageRef = useRef2(onMessage);
|
|
10099
10074
|
onMessageRef.current = onMessage;
|
|
@@ -10118,7 +10093,7 @@ function useChannel(url, config = {}) {
|
|
|
10118
10093
|
}
|
|
10119
10094
|
return;
|
|
10120
10095
|
}
|
|
10121
|
-
const client =
|
|
10096
|
+
const client = createWebSocket(url, {
|
|
10122
10097
|
onMessage: (msg) => onMessageRef.current?.(msg),
|
|
10123
10098
|
onStatusChange: (status, error) => {
|
|
10124
10099
|
stateRef.current = { status, error };
|
|
@@ -10144,43 +10119,8 @@ function useChannel(url, config = {}) {
|
|
|
10144
10119
|
};
|
|
10145
10120
|
}
|
|
10146
10121
|
|
|
10147
|
-
// src/react/useAppSession.ts
|
|
10148
|
-
import { useRef as useRef3, useEffect as useEffect4, useSyncExternalStore as useSyncExternalStore3, useCallback as useCallback4 } from "react";
|
|
10149
|
-
function useAppSession(config = {}) {
|
|
10150
|
-
const { hostClient, initialState, id } = config;
|
|
10151
|
-
const sessionRef = useRef3(null);
|
|
10152
|
-
if (!sessionRef.current) {
|
|
10153
|
-
sessionRef.current = new AppSession(initialState, { id });
|
|
10154
|
-
}
|
|
10155
|
-
const session = sessionRef.current;
|
|
10156
|
-
useEffect4(() => {
|
|
10157
|
-
if (hostClient) {
|
|
10158
|
-
const unbind = session.bindHost(hostClient);
|
|
10159
|
-
return unbind;
|
|
10160
|
-
}
|
|
10161
|
-
}, [session, hostClient]);
|
|
10162
|
-
const subscribe = useCallback4(
|
|
10163
|
-
(onStoreChange) => session.subscribe(onStoreChange),
|
|
10164
|
-
[session]
|
|
10165
|
-
);
|
|
10166
|
-
const getSnapshot = useCallback4(() => session.state, [session]);
|
|
10167
|
-
const state = useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
|
|
10168
|
-
const setUi = useCallback4((ui2) => session.setUi(ui2), [session]);
|
|
10169
|
-
const updateUi = useCallback4(
|
|
10170
|
-
(partial) => session.updateUi(partial),
|
|
10171
|
-
[session]
|
|
10172
|
-
);
|
|
10173
|
-
return {
|
|
10174
|
-
session,
|
|
10175
|
-
state,
|
|
10176
|
-
ui: state.ui,
|
|
10177
|
-
setUi,
|
|
10178
|
-
updateUi
|
|
10179
|
-
};
|
|
10180
|
-
}
|
|
10181
|
-
|
|
10182
10122
|
// src/react/CreatureIcon.tsx
|
|
10183
|
-
import { useState as useState3, useEffect as
|
|
10123
|
+
import { useState as useState3, useEffect as useEffect4, useRef as useRef3 } from "react";
|
|
10184
10124
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10185
10125
|
function CreatureIcon({
|
|
10186
10126
|
isDarkMode,
|
|
@@ -10192,8 +10132,8 @@ function CreatureIcon({
|
|
|
10192
10132
|
}) {
|
|
10193
10133
|
const fillColor = isDarkMode ? "#F8F7F6" : "#0D0D0C";
|
|
10194
10134
|
const [isBlinking, setIsBlinking] = useState3(false);
|
|
10195
|
-
const timeoutRef =
|
|
10196
|
-
|
|
10135
|
+
const timeoutRef = useRef3(null);
|
|
10136
|
+
useEffect4(() => {
|
|
10197
10137
|
if (!enableBlink || !showEyes) {
|
|
10198
10138
|
return;
|
|
10199
10139
|
}
|
|
@@ -10274,22 +10214,20 @@ function CreatureIcon({
|
|
|
10274
10214
|
);
|
|
10275
10215
|
}
|
|
10276
10216
|
export {
|
|
10277
|
-
|
|
10278
|
-
ChatGPTHostClient,
|
|
10217
|
+
ChatGptAppHostClient,
|
|
10279
10218
|
CreatureIcon,
|
|
10280
|
-
|
|
10219
|
+
McpAppHostClient,
|
|
10281
10220
|
WidgetStateContext,
|
|
10282
10221
|
YU as applyDocumentTheme,
|
|
10283
10222
|
qU as applyHostFonts,
|
|
10284
10223
|
QU as applyHostStyleVariables,
|
|
10285
|
-
createChannel,
|
|
10286
10224
|
createHost,
|
|
10225
|
+
createWebSocket,
|
|
10287
10226
|
detectEnvironment,
|
|
10288
10227
|
VU as getDocumentTheme,
|
|
10289
|
-
useAppSession,
|
|
10290
|
-
useChannel,
|
|
10291
10228
|
useHost,
|
|
10292
10229
|
useToolResult,
|
|
10230
|
+
useWebSocket,
|
|
10293
10231
|
useWidgetState
|
|
10294
10232
|
};
|
|
10295
10233
|
//# sourceMappingURL=index.js.map
|