@noodleseed/assistant 1.5.0 → 1.7.0

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/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { e as AssistantViewAvailableDetail, c as AssistantClientEvent, a as AssistantContext, b as AssistantModelContextUpdate, A as AssistantPageContext, f as AssistantInteractionResponse } from './client-9kup0-ws.cjs';
2
- export { d as AssistantErrorDetail, g as AssistantEvent, h as AssistantViewAvailableEvent } from './client-9kup0-ws.cjs';
1
+ import { e as AssistantViewAvailableDetail, c as AssistantClientEvent, a as AssistantContext, b as AssistantModelContextUpdate, A as AssistantPageContext, f as AssistantInteractionResponse } from './client-D2Y9UFh3.cjs';
2
+ export { d as AssistantErrorDetail, g as AssistantEvent, h as AssistantViewAvailableEvent } from './client-D2Y9UFh3.cjs';
3
3
  import './appearance-DowzFJjh.cjs';
4
4
 
5
5
  interface AssistantSurfaceAppearance {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { e as AssistantViewAvailableDetail, c as AssistantClientEvent, a as AssistantContext, b as AssistantModelContextUpdate, A as AssistantPageContext, f as AssistantInteractionResponse } from './client-BRjZMXlk.js';
2
- export { d as AssistantErrorDetail, g as AssistantEvent, h as AssistantViewAvailableEvent } from './client-BRjZMXlk.js';
1
+ import { e as AssistantViewAvailableDetail, c as AssistantClientEvent, a as AssistantContext, b as AssistantModelContextUpdate, A as AssistantPageContext, f as AssistantInteractionResponse } from './client-DBuETUVD.js';
2
+ export { d as AssistantErrorDetail, g as AssistantEvent, h as AssistantViewAvailableEvent } from './client-DBuETUVD.js';
3
3
  import './appearance-DowzFJjh.js';
4
4
 
5
5
  interface AssistantSurfaceAppearance {
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  ASSISTANT_TAG_NAME,
3
3
  NoodleAssistantElement,
4
4
  registerNoodleAssistant
5
- } from "./chunk-ZKXOX67J.js";
6
- import "./chunk-GTYYQNGT.js";
5
+ } from "./chunk-35A7REQX.js";
6
+ import "./chunk-7E5HINN4.js";
7
7
  import "./chunk-UXPKSCID.js";
8
8
  import "./chunk-NSBPE2FW.js";
9
9
 
package/dist/react.cjs CHANGED
@@ -18194,10 +18194,17 @@ function GX(X2, Y) {
18194
18194
  // src/app-host.ts
18195
18195
  var PROXY_DOCUMENT = `<!doctype html><meta charset="utf-8"><style>html,body,iframe{border:0;margin:0;width:100%;height:100%;overflow:hidden}body{background:transparent}</style><script>
18196
18196
  let inner;
18197
+ const ready={jsonrpc:'2.0',method:'ui/notifications/sandbox-proxy-ready',params:{}};
18198
+ // Re-announce until the host acknowledges with the resource: when this document is hosted
18199
+ // cross-origin, the first announcement can arrive before the host's load handler is listening.
18200
+ const announce=setInterval(()=>parent.postMessage(ready,'*'),120);
18201
+ setTimeout(()=>clearInterval(announce),15000);
18197
18202
  addEventListener('message',(event)=>{
18198
18203
  if(event.source===parent){
18199
18204
  const message=event.data;
18200
18205
  if(message?.method==='ui/notifications/sandbox-resource-ready'){
18206
+ clearInterval(announce);
18207
+ if(inner)return;
18201
18208
  inner=document.createElement('iframe');
18202
18209
  inner.setAttribute('sandbox',message.params?.sandbox||'allow-scripts');
18203
18210
  inner.setAttribute('referrerpolicy','no-referrer');
@@ -18210,7 +18217,7 @@ addEventListener('message',(event)=>{
18210
18217
  parent.postMessage(event.data,'*');
18211
18218
  }
18212
18219
  });
18213
- parent.postMessage({jsonrpc:'2.0',method:'ui/notifications/sandbox-proxy-ready',params:{}},'*');
18220
+ parent.postMessage(ready,'*');
18214
18221
  </script>`;
18215
18222
  function isAllowedAppLink(value, allowedDomains, baseUrl) {
18216
18223
  try {
@@ -18228,7 +18235,17 @@ function isAllowedAppLink(value, allowedDomains, baseUrl) {
18228
18235
  return void 0;
18229
18236
  }
18230
18237
  }
18231
- function mountAssistantApp(detail, actions) {
18238
+ var APP_RENDER_TIMEOUT_MS = 1e4;
18239
+ function resolveSandboxUrl(value) {
18240
+ if (!value) return void 0;
18241
+ try {
18242
+ const parsed = new URL(value);
18243
+ return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.href : void 0;
18244
+ } catch {
18245
+ return void 0;
18246
+ }
18247
+ }
18248
+ function mountAssistantApp(detail, actions, options = {}) {
18232
18249
  if (!detail.html) return void 0;
18233
18250
  const card = document.createElement("section");
18234
18251
  card.className = "noodle-app-card";
@@ -18243,8 +18260,19 @@ function mountAssistantApp(detail, actions) {
18243
18260
  frame.title = detail.title ?? detail.tool;
18244
18261
  frame.setAttribute("sandbox", "allow-scripts");
18245
18262
  frame.setAttribute("referrerpolicy", "no-referrer");
18246
- frame.srcdoc = PROXY_DOCUMENT;
18263
+ const sandboxUrl = resolveSandboxUrl(options.sandboxUrl);
18264
+ if (sandboxUrl) frame.src = sandboxUrl;
18265
+ else frame.srcdoc = PROXY_DOCUMENT;
18247
18266
  card.append(frame);
18267
+ let initialized = false;
18268
+ const renderTimer = setTimeout(() => {
18269
+ if (initialized || !frame.isConnected) return;
18270
+ const note = document.createElement("div");
18271
+ note.className = "noodle-app-fallback";
18272
+ note.textContent = "This app view could not be displayed.";
18273
+ frame.replaceWith(note);
18274
+ options.onRenderFailure?.({ code: "view_render_timeout", retryable: false });
18275
+ }, APP_RENDER_TIMEOUT_MS);
18248
18276
  frame.addEventListener(
18249
18277
  "load",
18250
18278
  () => {
@@ -18310,13 +18338,18 @@ function mountAssistantApp(detail, actions) {
18310
18338
  bridge.onlistresources = async (params) => await actions.client.requestApp("resources/list", params ?? {});
18311
18339
  bridge.onreadresource = async (params) => await actions.client.requestApp("resources/read", params);
18312
18340
  bridge.oninitialized = () => {
18341
+ initialized = true;
18342
+ clearTimeout(renderTimer);
18313
18343
  void bridge.sendToolInput({ arguments: detail.arguments ?? {} });
18314
18344
  void bridge.sendToolResult({
18315
18345
  content: [{ type: "text", text: JSON.stringify(detail.result) }],
18316
18346
  ...typeof detail.result === "object" && detail.result !== null && !Array.isArray(detail.result) ? { structuredContent: detail.result } : {}
18317
18347
  });
18318
18348
  };
18319
- void bridge.connect(new E(target, target)).catch(() => card.remove());
18349
+ void bridge.connect(new E(target, target)).catch(() => {
18350
+ clearTimeout(renderTimer);
18351
+ card.remove();
18352
+ });
18320
18353
  },
18321
18354
  { once: true }
18322
18355
  );
@@ -19066,6 +19099,9 @@ var DefaultAssistantClient = class {
19066
19099
  }
19067
19100
  return response.json();
19068
19101
  }
19102
+ appSandboxUrl() {
19103
+ return this.#session?.endpoints.sandbox;
19104
+ }
19069
19105
  resetSession() {
19070
19106
  this.#session = void 0;
19071
19107
  this.#emit({ event: "session_reset", data: {} });
@@ -19267,7 +19303,8 @@ function parseSession(value) {
19267
19303
  }
19268
19304
  const interactions = value.endpoints.interactions;
19269
19305
  const apps = value.endpoints.apps;
19270
- if (typeof value.token !== "string" || typeof value.expiresAt !== "string" || typeof value.endpoints.turns !== "string" || typeof value.endpoints.toolConfirmations !== "string" || interactions !== void 0 && typeof interactions !== "string" || apps !== void 0 && typeof apps !== "string") {
19306
+ const sandbox = value.endpoints.sandbox;
19307
+ if (typeof value.token !== "string" || typeof value.expiresAt !== "string" || typeof value.endpoints.turns !== "string" || typeof value.endpoints.toolConfirmations !== "string" || interactions !== void 0 && typeof interactions !== "string" || apps !== void 0 && typeof apps !== "string" || sandbox !== void 0 && typeof sandbox !== "string") {
19271
19308
  throw clientError("session_failed", "Assistant session response is invalid", true);
19272
19309
  }
19273
19310
  return {
@@ -19277,7 +19314,8 @@ function parseSession(value) {
19277
19314
  turns: value.endpoints.turns,
19278
19315
  toolConfirmations: value.endpoints.toolConfirmations,
19279
19316
  ...typeof interactions === "string" ? { interactions } : {},
19280
- ...typeof apps === "string" ? { apps } : {}
19317
+ ...typeof apps === "string" ? { apps } : {},
19318
+ ...typeof sandbox === "string" ? { sandbox } : {}
19281
19319
  },
19282
19320
  ...isRecord3(value.configuration) ? { configuration: value.configuration } : {}
19283
19321
  };
@@ -22745,6 +22783,7 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
22745
22783
  .noodle-app-card { position: relative; display: grid; gap: 8px; width: 100%; margin: 4px 0 16px; overflow: hidden; color: var(--ns-assistant-app-text, inherit); border: 1px solid var(--ns-assistant-app-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: var(--ns-assistant-app, var(--ns-assistant-elevated, var(--ns-assistant-default-elevated))); }
22746
22784
  .noodle-app-title { padding: 10px 12px 0; font-size: .86em; font-weight: 650; }
22747
22785
  .noodle-app-frame { display: block; width: 100%; min-height: 120px; border: 0; background: transparent; }
22786
+ .noodle-app-fallback { padding: 14px 16px; font-size: 13px; color: var(--ns-assistant-muted, var(--ns-assistant-default-muted, #6b7280)); }
22748
22787
  .noodle-app-card[data-fullscreen] { position: fixed; inset: 0; z-index: 2; margin: 0; border-radius: 0; background: var(--ns-assistant-panel, var(--ns-assistant-default-panel)); }
22749
22788
  .noodle-app-card[data-fullscreen] .noodle-app-frame { height: 100% !important; }
22750
22789
  form { display: flex; flex: 0 0 auto; gap: 8px; align-items: center; min-height: 56px; margin: 8px 16px 16px; padding: 6px 6px 6px 16px; color: var(--ns-assistant-composer-text, inherit); border: 1px solid var(--ns-assistant-composer-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-input-radius, 14px); background: var(--ns-assistant-composer, var(--ns-assistant-input, var(--ns-assistant-default-input))); box-shadow: 0 1px 2px rgba(0,0,0,.04); transition: border-color .15s ease, box-shadow .15s ease; }
@@ -23310,11 +23349,19 @@ var NoodleAssistantElement = class extends HTMLElementBase {
23310
23349
  const messages = this.#messages;
23311
23350
  const client = this.#client;
23312
23351
  if (!messages || !client) return;
23313
- const view = mountAssistantApp(detail, {
23314
- client,
23315
- sendMessage: (message) => this.sendMessage(message),
23316
- updateModelContext: (update) => this.updateModelContext(update)
23317
- });
23352
+ const sandboxUrl = client.appSandboxUrl?.();
23353
+ const view = mountAssistantApp(
23354
+ detail,
23355
+ {
23356
+ client,
23357
+ sendMessage: (message) => this.sendMessage(message),
23358
+ updateModelContext: (update) => this.updateModelContext(update)
23359
+ },
23360
+ {
23361
+ ...sandboxUrl === void 0 ? {} : { sandboxUrl },
23362
+ onRenderFailure: (failure) => this.#dispatchError(failure)
23363
+ }
23364
+ );
23318
23365
  if (!view) return;
23319
23366
  messages.append(view);
23320
23367
  this.setAttribute("has-messages", "");