@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.
@@ -9328,8 +9328,11 @@ var Subscribable = class {
9328
9328
  }
9329
9329
  };
9330
9330
 
9331
- // src/core/McpHostClient.ts
9332
- var McpHostClient = class extends Subscribable {
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: textContent,
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/ChatGPTHostClient.ts
9568
- var ChatGPTHostClient = class extends Subscribable {
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
- setState(partial) {
9586
- const prev = this.state;
9587
- this.state = { ...this.state, ...partial };
9588
- this.notifyStateChange(this.state, prev);
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
- processInitialData() {
9605
- if (this.hasProcessedInitialData) return;
9606
- const openai = window.openai;
9607
- if (!openai) {
9608
- console.warn("[SDK] window.openai not available");
9609
- return;
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 McpHostClient.
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/AppSession.ts
9702
- var AppSession = class {
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("[Channel] Already connected/connecting to:", url);
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("[Channel] Connecting to:", url);
9811
+ console.log("[WebSocket] Connecting to:", url);
9843
9812
  try {
9844
9813
  ws = new WebSocket(url);
9845
9814
  } catch (e2) {
9846
- console.error("[Channel] Failed to create WebSocket:", e2);
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("[Channel] Connected to:", url);
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("[Channel] Received message:", message);
9828
+ console.log("[WebSocket] Received message:", message);
9860
9829
  onMessage?.(message);
9861
9830
  } catch (e2) {
9862
- console.error("[Channel] Failed to parse message:", e2);
9831
+ console.error("[WebSocket] Failed to parse message:", e2);
9863
9832
  }
9864
9833
  };
9865
9834
  ws.onerror = (e2) => {
9866
- console.error("[Channel] WebSocket error:", e2);
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", "AppSession channel not found");
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 ChatGPTHostClient(config);
9893
+ return new ChatGptAppHostClient(config);
9925
9894
  }
9926
- return new McpHostClient(config);
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/useChannel.ts
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 useChannel(url, config = {}) {
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 = createChannel(url, {
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 useEffect5, useRef as useRef4 } from "react";
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 = useRef4(null);
10196
- useEffect5(() => {
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
- AppSession,
10278
- ChatGPTHostClient,
10217
+ ChatGptAppHostClient,
10279
10218
  CreatureIcon,
10280
- McpHostClient,
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