@noodleseed/assistant 1.25.0 → 1.25.1
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/README.md +9 -4
- package/dist/{app-view-element-BM4lral-.d.ts → app-view-element-BNkQab1B.d.ts} +1 -2
- package/dist/{app-view-element-9ojWWYov.d.cts → app-view-element-DhuiNW_x.d.cts} +1 -2
- package/dist/app-view.cjs +36 -208
- package/dist/app-view.cjs.map +1 -1
- package/dist/app-view.d.cts +1 -1
- package/dist/app-view.d.ts +1 -1
- package/dist/app-view.js +2 -2
- package/dist/{chunk-LNBUYHL7.js → chunk-5TYS2Q6S.js} +2 -2
- package/dist/chunk-5TYS2Q6S.js.map +1 -0
- package/dist/{chunk-P32MAR4K.js → chunk-CF2SCDLF.js} +37 -209
- package/dist/chunk-CF2SCDLF.js.map +1 -0
- package/dist/{chunk-SGMECNNU.js → chunk-FJYPE4GC.js} +2 -2
- package/dist/embed.global.js +91 -124
- package/dist/index.cjs +58 -230
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/react.cjs +58 -230
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-LNBUYHL7.js.map +0 -1
- package/dist/chunk-P32MAR4K.js.map +0 -1
- /package/dist/{chunk-SGMECNNU.js.map → chunk-FJYPE4GC.js.map} +0 -0
package/README.md
CHANGED
|
@@ -35,8 +35,8 @@ troubleshooting) lives at <https://docs.noodleseed.dev/guides/embedded-assistant
|
|
|
35
35
|
the server itself is `@noodleseed/one` (`npm install -g @noodleseed/one`).
|
|
36
36
|
|
|
37
37
|
If your page sends a `Content-Security-Policy`, allow the Noodle service origin in `connect-src` (turns and
|
|
38
|
-
event streams) and
|
|
39
|
-
|
|
38
|
+
event streams) **and** `frame-src` (app widgets render inside a hosted sandbox document served from the
|
|
39
|
+
service origin, `endpoints.sandbox`, so your `script-src` can stay strict). Details are in the guide's
|
|
40
40
|
"Content-Security-Policy on your page" section.
|
|
41
41
|
|
|
42
42
|
## Quick start
|
|
@@ -410,8 +410,13 @@ import "@noodleseed/assistant/app-view";
|
|
|
410
410
|
</template>
|
|
411
411
|
```
|
|
412
412
|
|
|
413
|
-
|
|
414
|
-
[
|
|
413
|
+
Configure Vue's `isCustomElement` for `noodle-app-view`. Angular uses the same element with `[client]`,
|
|
414
|
+
`[view]`, and `[theme]` property bindings. Do not serialize `client` or `view` into attributes.
|
|
415
|
+
|
|
416
|
+
`<noodle-app-view>` is the canonical host; `NoodleAppView` delegates to it. Both use the
|
|
417
|
+
service-advertised sandbox URL, route App calls through the supplied client, publish theme changes without
|
|
418
|
+
replacing the iframe, and request standard teardown on semantic replacement, disconnect, or an App teardown
|
|
419
|
+
request.
|
|
415
420
|
|
|
416
421
|
The App document owns its action intent: it calls standard `tools/call` after connecting and never relies on
|
|
417
422
|
native form navigation. If that call needs input or confirmation, the same `client` publishes the normal
|
|
@@ -2,9 +2,8 @@ import { A as AssistantClient, a as AssistantViewAvailableDetail, e as Assistant
|
|
|
2
2
|
|
|
3
3
|
declare const APP_VIEW_TAG_NAME = "noodle-app-view";
|
|
4
4
|
interface AssistantAppViewErrorDetail {
|
|
5
|
-
readonly code: 'view_render_timeout'
|
|
5
|
+
readonly code: 'view_render_timeout';
|
|
6
6
|
readonly retryable: false;
|
|
7
|
-
readonly stage: 'sandbox_load' | 'sandbox_proxy' | 'app_initialize';
|
|
8
7
|
}
|
|
9
8
|
declare global {
|
|
10
9
|
interface HTMLElementTagNameMap {
|
|
@@ -2,9 +2,8 @@ import { A as AssistantClient, a as AssistantViewAvailableDetail, e as Assistant
|
|
|
2
2
|
|
|
3
3
|
declare const APP_VIEW_TAG_NAME = "noodle-app-view";
|
|
4
4
|
interface AssistantAppViewErrorDetail {
|
|
5
|
-
readonly code: 'view_render_timeout'
|
|
5
|
+
readonly code: 'view_render_timeout';
|
|
6
6
|
readonly retryable: false;
|
|
7
|
-
readonly stage: 'sandbox_load' | 'sandbox_proxy' | 'app_initialize';
|
|
8
7
|
}
|
|
9
8
|
declare global {
|
|
10
9
|
interface HTMLElementTagNameMap {
|
package/dist/app-view.cjs
CHANGED
|
@@ -17922,15 +17922,6 @@ var E = class {
|
|
|
17922
17922
|
sessionId;
|
|
17923
17923
|
setProtocolVersion;
|
|
17924
17924
|
};
|
|
17925
|
-
function AZ(X) {
|
|
17926
|
-
if (!X) return "";
|
|
17927
|
-
let Y = [];
|
|
17928
|
-
if (X.camera) Y.push("camera");
|
|
17929
|
-
if (X.microphone) Y.push("microphone");
|
|
17930
|
-
if (X.geolocation) Y.push("geolocation");
|
|
17931
|
-
if (X.clipboardWrite) Y.push("clipboard-write");
|
|
17932
|
-
return Y.join("; ");
|
|
17933
|
-
}
|
|
17934
17925
|
var KX = [j];
|
|
17935
17926
|
var DX = class extends _ {
|
|
17936
17927
|
_client;
|
|
@@ -18201,131 +18192,34 @@ function GX(X, Y) {
|
|
|
18201
18192
|
return JSON.stringify(X) === JSON.stringify(Y);
|
|
18202
18193
|
}
|
|
18203
18194
|
|
|
18204
|
-
// src/app-sandbox-policy.ts
|
|
18205
|
-
var MAX_DOMAINS_PER_DIRECTIVE = 32;
|
|
18206
|
-
function isRecord(value) {
|
|
18207
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18208
|
-
}
|
|
18209
|
-
function isLoopback(hostname3) {
|
|
18210
|
-
return hostname3 === "localhost" || hostname3 === "127.0.0.1" || hostname3 === "[::1]";
|
|
18211
|
-
}
|
|
18212
|
-
function normalizeDomain(value, connect) {
|
|
18213
|
-
if (value.length > 512 || /[;\r\n'"\s]/u.test(value)) return void 0;
|
|
18214
|
-
try {
|
|
18215
|
-
const parsed = new URL(value);
|
|
18216
|
-
const secure = parsed.protocol === "https:" || connect && parsed.protocol === "wss:";
|
|
18217
|
-
const local = isLoopback(parsed.hostname) && (parsed.protocol === "http:" || connect && parsed.protocol === "ws:");
|
|
18218
|
-
if (!secure && !local) return void 0;
|
|
18219
|
-
if (parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
18220
|
-
return void 0;
|
|
18221
|
-
}
|
|
18222
|
-
return parsed.origin;
|
|
18223
|
-
} catch {
|
|
18224
|
-
return void 0;
|
|
18225
|
-
}
|
|
18226
|
-
}
|
|
18227
|
-
function normalizeDomains(values, connect) {
|
|
18228
|
-
const normalized = [
|
|
18229
|
-
...new Set(
|
|
18230
|
-
values.slice(0, MAX_DOMAINS_PER_DIRECTIVE).map((value) => typeof value === "string" ? normalizeDomain(value, connect) : void 0).filter((value) => value !== void 0)
|
|
18231
|
-
)
|
|
18232
|
-
];
|
|
18233
|
-
return normalized;
|
|
18234
|
-
}
|
|
18235
|
-
function resolveAssistantAppSandboxPolicy(resourceMeta) {
|
|
18236
|
-
if (!isRecord(resourceMeta)) return {};
|
|
18237
|
-
const rawCsp = resourceMeta.csp;
|
|
18238
|
-
const csp = isRecord(rawCsp) ? {
|
|
18239
|
-
...Array.isArray(rawCsp.connectDomains) ? { connectDomains: normalizeDomains(rawCsp.connectDomains, true) } : {},
|
|
18240
|
-
...Array.isArray(rawCsp.resourceDomains) ? { resourceDomains: normalizeDomains(rawCsp.resourceDomains, false) } : {},
|
|
18241
|
-
...Array.isArray(rawCsp.frameDomains) ? { frameDomains: normalizeDomains(rawCsp.frameDomains, false) } : {},
|
|
18242
|
-
...Array.isArray(rawCsp.baseUriDomains) ? { baseUriDomains: normalizeDomains(rawCsp.baseUriDomains, false) } : {}
|
|
18243
|
-
} : void 0;
|
|
18244
|
-
const rawPermissions = resourceMeta.permissions;
|
|
18245
|
-
const permissions = isRecord(rawPermissions) ? {
|
|
18246
|
-
...isRecord(rawPermissions.camera) ? { camera: {} } : {},
|
|
18247
|
-
...isRecord(rawPermissions.microphone) ? { microphone: {} } : {},
|
|
18248
|
-
...isRecord(rawPermissions.geolocation) ? { geolocation: {} } : {},
|
|
18249
|
-
...isRecord(rawPermissions.clipboardWrite) ? { clipboardWrite: {} } : {}
|
|
18250
|
-
} : void 0;
|
|
18251
|
-
const allowAttribute = AZ(permissions);
|
|
18252
|
-
return {
|
|
18253
|
-
...csp === void 0 ? {} : { csp },
|
|
18254
|
-
...permissions === void 0 ? {} : { permissions },
|
|
18255
|
-
...allowAttribute ? { allowAttribute } : {}
|
|
18256
|
-
};
|
|
18257
|
-
}
|
|
18258
|
-
function assistantAppSandboxUrl(sandboxUrl, policy) {
|
|
18259
|
-
const parsed = new URL(sandboxUrl);
|
|
18260
|
-
if (policy.csp) parsed.searchParams.set("csp", JSON.stringify(policy.csp));
|
|
18261
|
-
const parentOrigin = globalThis.location?.origin;
|
|
18262
|
-
if (parentOrigin && parentOrigin !== "null") {
|
|
18263
|
-
parsed.hash = new URLSearchParams({ parentOrigin }).toString();
|
|
18264
|
-
}
|
|
18265
|
-
return parsed.href;
|
|
18266
|
-
}
|
|
18267
|
-
|
|
18268
18195
|
// src/app-host.ts
|
|
18269
|
-
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><
|
|
18270
|
-
let inner
|
|
18271
|
-
if(self===top)throw new Error('The assistant sandbox relay must be embedded');
|
|
18272
|
-
const standardSandbox='allow-scripts allow-same-origin allow-forms';
|
|
18273
|
-
const rawParentOrigin=new URLSearchParams(location.hash.slice(1)).get('parentOrigin');
|
|
18274
|
-
let expectedParentOrigin;
|
|
18275
|
-
try{const parsed=new URL(rawParentOrigin||'');if(parsed.origin===rawParentOrigin&&/^https?:$/.test(parsed.protocol))expectedParentOrigin=parsed.origin}catch{}
|
|
18276
|
-
const parentTarget=expectedParentOrigin||'*';
|
|
18277
|
-
const ownOrigin=self.origin;
|
|
18196
|
+
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>
|
|
18197
|
+
let inner;
|
|
18278
18198
|
const ready={jsonrpc:'2.0',method:'ui/notifications/sandbox-proxy-ready',params:{}};
|
|
18279
18199
|
// Re-announce until the host acknowledges with the resource: when this document is hosted
|
|
18280
18200
|
// cross-origin, the first announcement can arrive before the host's load handler is listening.
|
|
18281
|
-
const announce=setInterval(()=>parent.postMessage(ready,
|
|
18201
|
+
const announce=setInterval(()=>parent.postMessage(ready,'*'),120);
|
|
18282
18202
|
setTimeout(()=>clearInterval(announce),15000);
|
|
18283
18203
|
addEventListener('message',(event)=>{
|
|
18284
18204
|
if(event.source===parent){
|
|
18285
|
-
if(expectedParentOrigin&&event.origin!==expectedParentOrigin)return;
|
|
18286
18205
|
const message=event.data;
|
|
18287
18206
|
if(message?.method==='ui/notifications/sandbox-resource-ready'){
|
|
18288
18207
|
clearInterval(announce);
|
|
18289
|
-
if(
|
|
18290
|
-
loaded=true;
|
|
18291
|
-
const requestedSandbox=message.params?.sandbox;
|
|
18208
|
+
if(inner)return;
|
|
18292
18209
|
inner=document.createElement('iframe');
|
|
18293
|
-
inner.setAttribute('sandbox',
|
|
18210
|
+
inner.setAttribute('sandbox',message.params?.sandbox||'allow-scripts');
|
|
18294
18211
|
inner.setAttribute('referrerpolicy','no-referrer');
|
|
18295
|
-
|
|
18296
|
-
|
|
18297
|
-
if(permissions?.camera)allow.push('camera');
|
|
18298
|
-
if(permissions?.microphone)allow.push('microphone');
|
|
18299
|
-
if(permissions?.geolocation)allow.push('geolocation');
|
|
18300
|
-
if(permissions?.clipboardWrite)allow.push('clipboard-write');
|
|
18301
|
-
if(allow.length)inner.setAttribute('allow',allow.join('; '));
|
|
18302
|
-
document.body.append(inner);
|
|
18303
|
-
let html=String(message.params?.html||'');
|
|
18304
|
-
const csp=message.params?.csp;
|
|
18305
|
-
if(csp&&typeof csp==='object'){
|
|
18306
|
-
const list=(value,fallback)=>Array.isArray(value)&&value.length?value.join(' '):fallback;
|
|
18307
|
-
const resources=Array.isArray(csp.resourceDomains)?csp.resourceDomains:[];
|
|
18308
|
-
const suffix=resources.length?' '+resources.join(' '):'';
|
|
18309
|
-
const policy=["default-src 'none'","script-src 'unsafe-inline'"+suffix,"style-src 'unsafe-inline'"+suffix,'img-src data: blob:'+suffix,'font-src data: blob:'+suffix,'media-src data: blob:'+suffix,'worker-src blob:'+suffix,'connect-src '+list(csp.connectDomains,"'none'"),'frame-src '+list(csp.frameDomains,"'none'"),"object-src 'none'","form-action 'none'",'base-uri '+list(csp.baseUriDomains,"'none'")].join('; ');
|
|
18310
|
-
const meta='<meta http-equiv="Content-Security-Policy" content="'+policy.replace(/&/g,'&').replace(/"/g,'"')+'">';
|
|
18311
|
-
const doctype=html.match(/^\\s*<!doctype[^>]*>/i);
|
|
18312
|
-
html=doctype?html.slice(0,doctype[0].length)+meta+html.slice(doctype[0].length):meta+html;
|
|
18313
|
-
}
|
|
18314
|
-
try{
|
|
18315
|
-
const doc=inner.contentDocument||inner.contentWindow?.document;
|
|
18316
|
-
if(!doc)throw new Error('document unavailable');
|
|
18317
|
-
doc.open();doc.write(html);doc.close();
|
|
18318
|
-
}catch{inner.srcdoc=html}
|
|
18212
|
+
inner.srcdoc=String(message.params?.html||'');
|
|
18213
|
+
document.body.replaceChildren(inner);
|
|
18319
18214
|
return;
|
|
18320
18215
|
}
|
|
18321
18216
|
inner?.contentWindow?.postMessage(message,'*');
|
|
18322
18217
|
} else if(inner && event.source===inner.contentWindow) {
|
|
18323
|
-
|
|
18324
|
-
parent.postMessage(event.data,parentTarget);
|
|
18218
|
+
parent.postMessage(event.data,'*');
|
|
18325
18219
|
}
|
|
18326
18220
|
});
|
|
18327
|
-
parent.postMessage(ready,
|
|
18328
|
-
</script
|
|
18221
|
+
parent.postMessage(ready,'*');
|
|
18222
|
+
</script>`;
|
|
18329
18223
|
function isAllowedAppLink(value, allowedDomains, baseUrl) {
|
|
18330
18224
|
try {
|
|
18331
18225
|
const parsed = new URL(value, baseUrl);
|
|
@@ -18352,42 +18246,16 @@ function createAssistantAppHostContext(theme, allowFullscreen = false, displayMo
|
|
|
18352
18246
|
}
|
|
18353
18247
|
var APP_RENDER_TIMEOUT_MS = 1e4;
|
|
18354
18248
|
var APP_TEARDOWN_TIMEOUT_MS = 1e3;
|
|
18355
|
-
var STANDARD_SANDBOX = "allow-scripts allow-same-origin allow-forms";
|
|
18356
18249
|
var mountedApps = /* @__PURE__ */ new WeakMap();
|
|
18357
18250
|
function resolveSandboxUrl(value) {
|
|
18358
18251
|
if (!value) return void 0;
|
|
18359
18252
|
try {
|
|
18360
18253
|
const parsed = new URL(value);
|
|
18361
|
-
|
|
18362
|
-
const permittedProtocol = parsed.protocol === "https:" || parsed.protocol === "http:" && loopback;
|
|
18363
|
-
const embedderOrigin = globalThis.location?.origin;
|
|
18364
|
-
if (!permittedProtocol || embedderOrigin && embedderOrigin !== "null" && parsed.origin === embedderOrigin) {
|
|
18365
|
-
return void 0;
|
|
18366
|
-
}
|
|
18367
|
-
return parsed.href;
|
|
18254
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.href : void 0;
|
|
18368
18255
|
} catch {
|
|
18369
18256
|
return void 0;
|
|
18370
18257
|
}
|
|
18371
18258
|
}
|
|
18372
|
-
function copyAppJson(value, depth = 0) {
|
|
18373
|
-
if (depth > 64) throw new Error("App payload nesting exceeds the host limit");
|
|
18374
|
-
if (value === null || typeof value === "string" || typeof value === "boolean") return value;
|
|
18375
|
-
if (typeof value === "number") {
|
|
18376
|
-
if (!Number.isFinite(value)) throw new Error("App payload numbers must be finite");
|
|
18377
|
-
return value;
|
|
18378
|
-
}
|
|
18379
|
-
if (Array.isArray(value)) return value.map((entry) => copyAppJson(entry, depth + 1));
|
|
18380
|
-
const copied = {};
|
|
18381
|
-
for (const [key, entry] of Object.entries(value)) {
|
|
18382
|
-
Object.defineProperty(copied, key, {
|
|
18383
|
-
value: copyAppJson(entry, depth + 1),
|
|
18384
|
-
enumerable: true,
|
|
18385
|
-
configurable: true,
|
|
18386
|
-
writable: true
|
|
18387
|
-
});
|
|
18388
|
-
}
|
|
18389
|
-
return copied;
|
|
18390
|
-
}
|
|
18391
18259
|
function mountAssistantApp(detail, actions, options = {}) {
|
|
18392
18260
|
if (!detail.html) return void 0;
|
|
18393
18261
|
const card = document.createElement("section");
|
|
@@ -18408,25 +18276,16 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
18408
18276
|
const frame = document.createElement("iframe");
|
|
18409
18277
|
frame.className = "noodle-app-frame";
|
|
18410
18278
|
frame.title = detail.title ?? detail.tool;
|
|
18411
|
-
|
|
18279
|
+
frame.setAttribute("sandbox", "allow-scripts");
|
|
18412
18280
|
frame.setAttribute("referrerpolicy", "no-referrer");
|
|
18413
18281
|
const sandboxUrl = resolveSandboxUrl(options.sandboxUrl);
|
|
18414
|
-
|
|
18415
|
-
|
|
18416
|
-
frame.setAttribute("sandbox", STANDARD_SANDBOX);
|
|
18417
|
-
if (policy.allowAttribute) frame.setAttribute("allow", policy.allowAttribute);
|
|
18418
|
-
frame.src = assistantAppSandboxUrl(sandboxUrl, policy);
|
|
18419
|
-
} else {
|
|
18420
|
-
frame.setAttribute("sandbox", "allow-scripts");
|
|
18421
|
-
frame.srcdoc = PROXY_DOCUMENT;
|
|
18422
|
-
}
|
|
18282
|
+
if (sandboxUrl) frame.src = sandboxUrl;
|
|
18283
|
+
else frame.srcdoc = PROXY_DOCUMENT;
|
|
18423
18284
|
card.append(frame);
|
|
18424
18285
|
let mountedBridge;
|
|
18425
18286
|
let mountedTransport;
|
|
18426
18287
|
let destroyed = false;
|
|
18427
18288
|
let initialized = false;
|
|
18428
|
-
let renderFailed = false;
|
|
18429
|
-
let renderStage = "sandbox_load";
|
|
18430
18289
|
let currentTheme = actions.theme;
|
|
18431
18290
|
let displayMode = "inline";
|
|
18432
18291
|
let hostContext = createAssistantAppHostContext(
|
|
@@ -18435,15 +18294,6 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
18435
18294
|
displayMode
|
|
18436
18295
|
);
|
|
18437
18296
|
let destroyPromise;
|
|
18438
|
-
let transportClosePromise;
|
|
18439
|
-
let renderTimer;
|
|
18440
|
-
const closeTransport = () => {
|
|
18441
|
-
if (transportClosePromise) return transportClosePromise;
|
|
18442
|
-
const closing = mountedTransport?.close().catch(() => {
|
|
18443
|
-
}) ?? Promise.resolve();
|
|
18444
|
-
transportClosePromise = closing;
|
|
18445
|
-
return closing;
|
|
18446
|
-
};
|
|
18447
18297
|
const applyDisplayMode = (requestedMode) => {
|
|
18448
18298
|
displayMode = requestedMode === "fullscreen" && options.allowFullscreen === true ? "fullscreen" : "inline";
|
|
18449
18299
|
card.toggleAttribute("data-fullscreen", displayMode === "fullscreen");
|
|
@@ -18461,26 +18311,18 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
18461
18311
|
applyDisplayMode("inline");
|
|
18462
18312
|
frame.focus();
|
|
18463
18313
|
});
|
|
18464
|
-
const
|
|
18465
|
-
if (
|
|
18466
|
-
return;
|
|
18467
|
-
renderFailed = true;
|
|
18468
|
-
clearTimeout(renderTimer);
|
|
18314
|
+
const renderTimer = setTimeout(() => {
|
|
18315
|
+
if (initialized || !frame.isConnected) return;
|
|
18469
18316
|
const note = document.createElement("div");
|
|
18470
18317
|
note.className = "noodle-app-fallback";
|
|
18471
18318
|
note.textContent = "This app view could not be displayed.";
|
|
18472
18319
|
frame.replaceWith(note);
|
|
18473
|
-
options.onRenderFailure?.({ code, retryable: false
|
|
18474
|
-
void closeTransport();
|
|
18475
|
-
};
|
|
18476
|
-
renderTimer = setTimeout(() => {
|
|
18477
|
-
showRenderFailure("view_render_timeout");
|
|
18320
|
+
options.onRenderFailure?.({ code: "view_render_timeout", retryable: false });
|
|
18478
18321
|
}, APP_RENDER_TIMEOUT_MS);
|
|
18479
18322
|
frame.addEventListener(
|
|
18480
18323
|
"load",
|
|
18481
18324
|
() => {
|
|
18482
|
-
if (destroyed
|
|
18483
|
-
renderStage = "sandbox_proxy";
|
|
18325
|
+
if (destroyed) return;
|
|
18484
18326
|
const target = frame.contentWindow;
|
|
18485
18327
|
if (!target) return;
|
|
18486
18328
|
const bridge = new DX(
|
|
@@ -18491,11 +18333,7 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
18491
18333
|
serverTools: {},
|
|
18492
18334
|
serverResources: {},
|
|
18493
18335
|
updateModelContext: { text: {}, structuredContent: {} },
|
|
18494
|
-
message: { text: {} }
|
|
18495
|
-
sandbox: {
|
|
18496
|
-
...appliedPolicy.csp === void 0 ? {} : { csp: appliedPolicy.csp },
|
|
18497
|
-
...appliedPolicy.permissions === void 0 ? {} : { permissions: appliedPolicy.permissions }
|
|
18498
|
-
}
|
|
18336
|
+
message: { text: {} }
|
|
18499
18337
|
},
|
|
18500
18338
|
{
|
|
18501
18339
|
hostContext
|
|
@@ -18503,15 +18341,13 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
18503
18341
|
);
|
|
18504
18342
|
mountedBridge = bridge;
|
|
18505
18343
|
bridge.onsandboxready = () => {
|
|
18506
|
-
if (destroyed
|
|
18507
|
-
renderStage = "app_initialize";
|
|
18344
|
+
if (destroyed) return;
|
|
18508
18345
|
const current = options.getDetail?.() ?? detail;
|
|
18509
18346
|
void bridge.sendSandboxResourceReady({
|
|
18510
18347
|
html: current.html,
|
|
18511
|
-
sandbox:
|
|
18512
|
-
...
|
|
18513
|
-
|
|
18514
|
-
}).catch(() => showRenderFailure("view_bridge_error"));
|
|
18348
|
+
sandbox: "allow-scripts",
|
|
18349
|
+
...current.resourceMeta ?? {}
|
|
18350
|
+
});
|
|
18515
18351
|
};
|
|
18516
18352
|
bridge.onsizechange = ({ height }) => {
|
|
18517
18353
|
if (destroyed) return;
|
|
@@ -18575,30 +18411,21 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
18575
18411
|
return await actions.client.requestApp("resources/read", params);
|
|
18576
18412
|
};
|
|
18577
18413
|
bridge.oninitialized = () => {
|
|
18578
|
-
if (destroyed
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18583
|
-
|
|
18584
|
-
|
|
18585
|
-
|
|
18586
|
-
|
|
18587
|
-
|
|
18588
|
-
bridge.sendToolInput({ arguments: argumentsRecord }),
|
|
18589
|
-
bridge.sendToolResult({
|
|
18590
|
-
content: [{ type: "text", text: JSON.stringify(copiedResult) }],
|
|
18591
|
-
...typeof copiedResult === "object" && copiedResult !== null && !Array.isArray(copiedResult) ? { structuredContent: copiedResult } : {}
|
|
18592
|
-
})
|
|
18593
|
-
]).catch(() => showRenderFailure("view_bridge_error"));
|
|
18594
|
-
} catch {
|
|
18595
|
-
showRenderFailure("view_bridge_error");
|
|
18596
|
-
}
|
|
18414
|
+
if (destroyed) return;
|
|
18415
|
+
initialized = true;
|
|
18416
|
+
clearTimeout(renderTimer);
|
|
18417
|
+
bridge.setHostContext(hostContext);
|
|
18418
|
+
const current = options.getDetail?.() ?? detail;
|
|
18419
|
+
void bridge.sendToolInput({ arguments: current.arguments ?? {} });
|
|
18420
|
+
void bridge.sendToolResult({
|
|
18421
|
+
content: [{ type: "text", text: JSON.stringify(current.result) }],
|
|
18422
|
+
...typeof current.result === "object" && current.result !== null && !Array.isArray(current.result) ? { structuredContent: current.result } : {}
|
|
18423
|
+
});
|
|
18597
18424
|
};
|
|
18598
18425
|
const transport = new E(target, target);
|
|
18599
18426
|
mountedTransport = transport;
|
|
18600
18427
|
void bridge.connect(transport).catch(() => {
|
|
18601
|
-
|
|
18428
|
+
void destroy();
|
|
18602
18429
|
});
|
|
18603
18430
|
},
|
|
18604
18431
|
{ once: true }
|
|
@@ -18624,7 +18451,8 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
18624
18451
|
}
|
|
18625
18452
|
} catch {
|
|
18626
18453
|
}
|
|
18627
|
-
await
|
|
18454
|
+
await mountedTransport?.close().catch(() => {
|
|
18455
|
+
});
|
|
18628
18456
|
card.remove();
|
|
18629
18457
|
mountedApps.delete(card);
|
|
18630
18458
|
})();
|