@noodleseed/assistant 1.7.0 → 1.9.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/README.md +101 -22
- package/dist/{appearance-DowzFJjh.d.cts → appearance-Cc-eqSbp.d.cts} +1 -1
- package/dist/{appearance-DowzFJjh.d.ts → appearance-Cc-eqSbp.d.ts} +1 -1
- package/dist/{chunk-UXPKSCID.js → chunk-3YYTUJPJ.js} +2 -2
- package/dist/{chunk-35A7REQX.js → chunk-4B3XXGRP.js} +256 -91
- package/dist/chunk-4B3XXGRP.js.map +1 -0
- package/dist/{chunk-NSBPE2FW.js → chunk-5FUTL2UF.js} +6 -1
- package/dist/chunk-BLMJHF7U.js +544 -0
- package/dist/chunk-BLMJHF7U.js.map +1 -0
- package/dist/chunk-RYQBXTLR.js +9089 -0
- package/dist/chunk-RYQBXTLR.js.map +1 -0
- package/dist/{client-D2Y9UFh3.d.cts → client-B803xZVn.d.ts} +44 -2
- package/dist/{client-DBuETUVD.d.ts → client-CsmtpD1z.d.cts} +44 -2
- package/dist/client.cjs +22976 -92
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +3 -2
- package/dist/client.d.ts +3 -2
- package/dist/client.js +3 -2
- package/dist/index.cjs +10750 -2212
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -4
- package/dist/react/client.cjs +23688 -0
- package/dist/react/client.cjs.map +1 -0
- package/dist/react/client.d.cts +24 -0
- package/dist/react/client.d.ts +24 -0
- package/dist/react/client.js +76 -0
- package/dist/react/client.js.map +1 -0
- package/dist/react.cjs +10803 -2215
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +23 -4
- package/dist/react.d.ts +23 -4
- package/dist/react.js +64 -14
- package/dist/react.js.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/token-Y6KCR3JT.js +70 -0
- package/dist/token-Y6KCR3JT.js.map +1 -0
- package/dist/token-util-XFYMRPAB.js +6 -0
- package/dist/{v4-2UXPDMWJ.js → v4-KBRL3YLO.js} +3 -3
- package/dist/v4-KBRL3YLO.js.map +1 -0
- package/package.json +14 -3
- package/dist/chunk-35A7REQX.js.map +0 -1
- package/dist/chunk-7E5HINN4.js +0 -713
- package/dist/chunk-7E5HINN4.js.map +0 -1
- /package/dist/{chunk-UXPKSCID.js.map → chunk-3YYTUJPJ.js.map} +0 -0
- /package/dist/{chunk-NSBPE2FW.js.map → chunk-5FUTL2UF.js.map} +0 -0
- /package/dist/{v4-2UXPDMWJ.js.map → token-util-XFYMRPAB.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
AssistantClientError,
|
|
3
3
|
copyAssistantModelContext,
|
|
4
4
|
createAssistantClient
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RYQBXTLR.js";
|
|
6
6
|
import {
|
|
7
7
|
_enum,
|
|
8
8
|
_null,
|
|
@@ -24,10 +24,10 @@ import {
|
|
|
24
24
|
string,
|
|
25
25
|
union,
|
|
26
26
|
unknown
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-3YYTUJPJ.js";
|
|
28
28
|
import {
|
|
29
29
|
__require
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-5FUTL2UF.js";
|
|
31
31
|
|
|
32
32
|
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@4.4.3/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
33
33
|
var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
|
|
@@ -3063,7 +3063,17 @@ function isAllowedAppLink(value, allowedDomains, baseUrl) {
|
|
|
3063
3063
|
return void 0;
|
|
3064
3064
|
}
|
|
3065
3065
|
}
|
|
3066
|
+
function createAssistantAppHostContext(theme) {
|
|
3067
|
+
return {
|
|
3068
|
+
theme,
|
|
3069
|
+
displayMode: "inline",
|
|
3070
|
+
availableDisplayModes: ["inline", "fullscreen"],
|
|
3071
|
+
platform: "web"
|
|
3072
|
+
};
|
|
3073
|
+
}
|
|
3066
3074
|
var APP_RENDER_TIMEOUT_MS = 1e4;
|
|
3075
|
+
var APP_TEARDOWN_TIMEOUT_MS = 1e3;
|
|
3076
|
+
var mountedApps = /* @__PURE__ */ new WeakMap();
|
|
3067
3077
|
function resolveSandboxUrl(value) {
|
|
3068
3078
|
if (!value) return void 0;
|
|
3069
3079
|
try {
|
|
@@ -3092,7 +3102,11 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3092
3102
|
if (sandboxUrl) frame.src = sandboxUrl;
|
|
3093
3103
|
else frame.srcdoc = PROXY_DOCUMENT;
|
|
3094
3104
|
card.append(frame);
|
|
3105
|
+
let mountedBridge;
|
|
3106
|
+
let mountedTransport;
|
|
3107
|
+
let destroyed = false;
|
|
3095
3108
|
let initialized = false;
|
|
3109
|
+
let destroyPromise;
|
|
3096
3110
|
const renderTimer = setTimeout(() => {
|
|
3097
3111
|
if (initialized || !frame.isConnected) return;
|
|
3098
3112
|
const note = document.createElement("div");
|
|
@@ -3104,6 +3118,7 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3104
3118
|
frame.addEventListener(
|
|
3105
3119
|
"load",
|
|
3106
3120
|
() => {
|
|
3121
|
+
if (destroyed) return;
|
|
3107
3122
|
const target = frame.contentWindow;
|
|
3108
3123
|
if (!target) return;
|
|
3109
3124
|
const bridge = new DX(
|
|
@@ -3117,26 +3132,27 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3117
3132
|
message: { text: {} }
|
|
3118
3133
|
},
|
|
3119
3134
|
{
|
|
3120
|
-
hostContext:
|
|
3121
|
-
displayMode: "inline",
|
|
3122
|
-
availableDisplayModes: ["inline", "fullscreen"],
|
|
3123
|
-
platform: "web"
|
|
3124
|
-
}
|
|
3135
|
+
hostContext: createAssistantAppHostContext(actions.theme)
|
|
3125
3136
|
}
|
|
3126
3137
|
);
|
|
3138
|
+
mountedBridge = bridge;
|
|
3127
3139
|
bridge.onsandboxready = () => {
|
|
3140
|
+
if (destroyed) return;
|
|
3141
|
+
const current = options.getDetail?.() ?? detail;
|
|
3128
3142
|
void bridge.sendSandboxResourceReady({
|
|
3129
|
-
html:
|
|
3143
|
+
html: current.html,
|
|
3130
3144
|
sandbox: "allow-scripts allow-forms",
|
|
3131
|
-
...
|
|
3145
|
+
...current.resourceMeta ?? {}
|
|
3132
3146
|
});
|
|
3133
3147
|
};
|
|
3134
3148
|
bridge.onsizechange = ({ height }) => {
|
|
3149
|
+
if (destroyed) return;
|
|
3135
3150
|
if (typeof height === "number" && Number.isFinite(height)) {
|
|
3136
3151
|
frame.style.height = `${Math.min(1200, Math.max(120, Math.ceil(height)))}px`;
|
|
3137
3152
|
}
|
|
3138
3153
|
};
|
|
3139
3154
|
bridge.onmessage = async ({ content }) => {
|
|
3155
|
+
if (destroyed) return {};
|
|
3140
3156
|
const text2 = content.flatMap(
|
|
3141
3157
|
(part) => part.type === "text" && typeof part.text === "string" ? [part.text] : []
|
|
3142
3158
|
).join("\n").trim();
|
|
@@ -3144,13 +3160,16 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3144
3160
|
return {};
|
|
3145
3161
|
};
|
|
3146
3162
|
bridge.onupdatemodelcontext = async (update) => {
|
|
3163
|
+
if (destroyed) return {};
|
|
3147
3164
|
actions.updateModelContext(update);
|
|
3148
3165
|
return {};
|
|
3149
3166
|
};
|
|
3150
3167
|
bridge.onopenlink = async ({ url }) => {
|
|
3168
|
+
if (destroyed) return { isError: true };
|
|
3169
|
+
const current = options.getDetail?.() ?? detail;
|
|
3151
3170
|
const allowed = isAllowedAppLink(
|
|
3152
3171
|
url,
|
|
3153
|
-
|
|
3172
|
+
current.allowedOpenDomains ?? [],
|
|
3154
3173
|
globalThis.location?.href ?? "https://invalid.example"
|
|
3155
3174
|
);
|
|
3156
3175
|
if (!allowed) return { isError: true };
|
|
@@ -3159,30 +3178,74 @@ function mountAssistantApp(detail, actions, options = {}) {
|
|
|
3159
3178
|
};
|
|
3160
3179
|
bridge.onrequestdisplaymode = async ({ mode }) => {
|
|
3161
3180
|
const accepted = mode === "fullscreen" ? "fullscreen" : "inline";
|
|
3181
|
+
if (destroyed) return { mode: accepted };
|
|
3162
3182
|
card.toggleAttribute("data-fullscreen", accepted === "fullscreen");
|
|
3163
3183
|
return { mode: accepted };
|
|
3164
3184
|
};
|
|
3165
|
-
bridge.oncalltool = async (params) =>
|
|
3166
|
-
|
|
3167
|
-
|
|
3185
|
+
bridge.oncalltool = async (params) => {
|
|
3186
|
+
if (destroyed) {
|
|
3187
|
+
return {
|
|
3188
|
+
content: [{ type: "text", text: "App view is closing." }],
|
|
3189
|
+
isError: true
|
|
3190
|
+
};
|
|
3191
|
+
}
|
|
3192
|
+
return await actions.client.requestApp("tools/call", params);
|
|
3193
|
+
};
|
|
3194
|
+
bridge.onlistresources = async (params) => {
|
|
3195
|
+
if (destroyed) {
|
|
3196
|
+
return { resources: [] };
|
|
3197
|
+
}
|
|
3198
|
+
return await actions.client.requestApp("resources/list", params ?? {});
|
|
3199
|
+
};
|
|
3200
|
+
bridge.onreadresource = async (params) => {
|
|
3201
|
+
if (destroyed) {
|
|
3202
|
+
return { contents: [] };
|
|
3203
|
+
}
|
|
3204
|
+
return await actions.client.requestApp("resources/read", params);
|
|
3205
|
+
};
|
|
3168
3206
|
bridge.oninitialized = () => {
|
|
3207
|
+
if (destroyed) return;
|
|
3169
3208
|
initialized = true;
|
|
3170
3209
|
clearTimeout(renderTimer);
|
|
3171
|
-
|
|
3210
|
+
const current = options.getDetail?.() ?? detail;
|
|
3211
|
+
void bridge.sendToolInput({ arguments: current.arguments ?? {} });
|
|
3172
3212
|
void bridge.sendToolResult({
|
|
3173
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
3174
|
-
...typeof
|
|
3213
|
+
content: [{ type: "text", text: JSON.stringify(current.result) }],
|
|
3214
|
+
...typeof current.result === "object" && current.result !== null && !Array.isArray(current.result) ? { structuredContent: current.result } : {}
|
|
3175
3215
|
});
|
|
3176
3216
|
};
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3217
|
+
const transport = new E(target, target);
|
|
3218
|
+
mountedTransport = transport;
|
|
3219
|
+
void bridge.connect(transport).catch(() => {
|
|
3220
|
+
void destroy();
|
|
3180
3221
|
});
|
|
3181
3222
|
},
|
|
3182
3223
|
{ once: true }
|
|
3183
3224
|
);
|
|
3225
|
+
const destroy = () => {
|
|
3226
|
+
if (destroyPromise) return destroyPromise;
|
|
3227
|
+
destroyed = true;
|
|
3228
|
+
clearTimeout(renderTimer);
|
|
3229
|
+
destroyPromise = (async () => {
|
|
3230
|
+
try {
|
|
3231
|
+
if (initialized) {
|
|
3232
|
+
await mountedBridge?.teardownResource({}, { timeout: APP_TEARDOWN_TIMEOUT_MS });
|
|
3233
|
+
}
|
|
3234
|
+
} catch {
|
|
3235
|
+
}
|
|
3236
|
+
await mountedTransport?.close().catch(() => {
|
|
3237
|
+
});
|
|
3238
|
+
card.remove();
|
|
3239
|
+
mountedApps.delete(card);
|
|
3240
|
+
})();
|
|
3241
|
+
return destroyPromise;
|
|
3242
|
+
};
|
|
3243
|
+
mountedApps.set(card, { destroy });
|
|
3184
3244
|
return card;
|
|
3185
3245
|
}
|
|
3246
|
+
function unmountAssistantApp(card) {
|
|
3247
|
+
return mountedApps.get(card)?.destroy() ?? Promise.resolve();
|
|
3248
|
+
}
|
|
3186
3249
|
|
|
3187
3250
|
// src/appearance.ts
|
|
3188
3251
|
var common = {
|
|
@@ -3191,10 +3254,10 @@ var common = {
|
|
|
3191
3254
|
baseFontSize: 15,
|
|
3192
3255
|
messageFontSize: 15,
|
|
3193
3256
|
lineHeight: 1.5,
|
|
3194
|
-
panelRadius:
|
|
3195
|
-
cardRadius:
|
|
3196
|
-
inputRadius:
|
|
3197
|
-
buttonRadius:
|
|
3257
|
+
panelRadius: 24,
|
|
3258
|
+
cardRadius: 16,
|
|
3259
|
+
inputRadius: 999,
|
|
3260
|
+
buttonRadius: 999,
|
|
3198
3261
|
launcherRadius: 999,
|
|
3199
3262
|
spacing: 8,
|
|
3200
3263
|
backdropBlur: 18,
|
|
@@ -3301,7 +3364,7 @@ var DEFAULT_APPEARANCE = {
|
|
|
3301
3364
|
},
|
|
3302
3365
|
presentation: {
|
|
3303
3366
|
panel: {
|
|
3304
|
-
surface: "
|
|
3367
|
+
surface: "glass",
|
|
3305
3368
|
elevation: "soft",
|
|
3306
3369
|
border: "subtle"
|
|
3307
3370
|
},
|
|
@@ -6608,8 +6671,7 @@ var AssistantElementEventController = class {
|
|
|
6608
6671
|
if (name === "message_started") {
|
|
6609
6672
|
this.#startStream("message");
|
|
6610
6673
|
const body = this.#host.appendMessage("user", String(data.message ?? ""));
|
|
6611
|
-
|
|
6612
|
-
if (body && messages) this.#revealLatestMessage(messages);
|
|
6674
|
+
if (body) this.#host.revealLatest();
|
|
6613
6675
|
this.#host.element.dispatchEvent(new CustomEvent("assistant-message-started"));
|
|
6614
6676
|
return;
|
|
6615
6677
|
}
|
|
@@ -6675,6 +6737,7 @@ var AssistantElementEventController = class {
|
|
|
6675
6737
|
this.#clearStream();
|
|
6676
6738
|
this.#completedTool = void 0;
|
|
6677
6739
|
this.#host.element.removeAttribute("has-messages");
|
|
6740
|
+
this.#host.revealLatest();
|
|
6678
6741
|
this.#host.element.dispatchEvent(new CustomEvent("assistant-session-reset"));
|
|
6679
6742
|
}
|
|
6680
6743
|
#finishInteraction(id, action) {
|
|
@@ -6685,6 +6748,7 @@ var AssistantElementEventController = class {
|
|
|
6685
6748
|
messages.append(
|
|
6686
6749
|
createResultCard(this.#completedTool.result, labels.completed, labels.redacted)
|
|
6687
6750
|
);
|
|
6751
|
+
this.#host.revealLatest();
|
|
6688
6752
|
}
|
|
6689
6753
|
}
|
|
6690
6754
|
this.#proposalCards.get(id)?.remove();
|
|
@@ -6722,7 +6786,7 @@ var AssistantElementEventController = class {
|
|
|
6722
6786
|
});
|
|
6723
6787
|
messages.append(card);
|
|
6724
6788
|
this.#proposalCards.set(id, card);
|
|
6725
|
-
this.#
|
|
6789
|
+
this.#host.revealLatest();
|
|
6726
6790
|
this.#host.element.dispatchEvent(
|
|
6727
6791
|
new CustomEvent("assistant-tool-proposed", {
|
|
6728
6792
|
detail: { id, tool, title, description, arguments: arguments_, reviewSchema }
|
|
@@ -6746,7 +6810,7 @@ var AssistantElementEventController = class {
|
|
|
6746
6810
|
});
|
|
6747
6811
|
messages.append(card);
|
|
6748
6812
|
this.#proposalCards.set(id, card);
|
|
6749
|
-
this.#
|
|
6813
|
+
this.#host.revealLatest();
|
|
6750
6814
|
this.#host.element.dispatchEvent(
|
|
6751
6815
|
new CustomEvent("assistant-input-requested", {
|
|
6752
6816
|
detail: { id, message, requestedSchema }
|
|
@@ -6759,6 +6823,7 @@ var AssistantElementEventController = class {
|
|
|
6759
6823
|
this.#streamKind = kind;
|
|
6760
6824
|
}
|
|
6761
6825
|
#clearStream() {
|
|
6826
|
+
this.#assistantBody?.parentElement?.classList.remove("streaming");
|
|
6762
6827
|
this.#assistantBody = void 0;
|
|
6763
6828
|
this.#assistantText = "";
|
|
6764
6829
|
this.#streamKind = void 0;
|
|
@@ -6771,20 +6836,10 @@ var AssistantElementEventController = class {
|
|
|
6771
6836
|
const body = this.#assistantBody ?? this.#host.appendMessage("assistant", "");
|
|
6772
6837
|
this.#assistantBody = body;
|
|
6773
6838
|
if (!body) return;
|
|
6839
|
+
body.parentElement?.classList.add("streaming");
|
|
6774
6840
|
body.innerHTML = html2;
|
|
6775
|
-
const messages = this.#host.messages();
|
|
6776
|
-
if (messages) this.#revealLatestMessage(messages);
|
|
6777
|
-
}
|
|
6778
|
-
#revealLatestMessage(messages) {
|
|
6779
6841
|
this.#host.element.setAttribute("has-messages", "");
|
|
6780
|
-
|
|
6781
|
-
const control = this.#host.element.shadowRoot?.querySelector(".new-messages");
|
|
6782
|
-
if (distance <= 160) {
|
|
6783
|
-
messages.scrollTop = messages.scrollHeight;
|
|
6784
|
-
if (control) control.hidden = true;
|
|
6785
|
-
} else if (control) {
|
|
6786
|
-
control.hidden = false;
|
|
6787
|
-
}
|
|
6842
|
+
this.#host.revealLatest();
|
|
6788
6843
|
}
|
|
6789
6844
|
};
|
|
6790
6845
|
function isRecord(value) {
|
|
@@ -6809,6 +6864,107 @@ function queryRequired(root, selector) {
|
|
|
6809
6864
|
return element;
|
|
6810
6865
|
}
|
|
6811
6866
|
|
|
6867
|
+
// src/element-scroll-controller.ts
|
|
6868
|
+
var AssistantElementScrollController = class {
|
|
6869
|
+
#region;
|
|
6870
|
+
#messages;
|
|
6871
|
+
#control;
|
|
6872
|
+
#mutationObserver;
|
|
6873
|
+
#resizeObserver;
|
|
6874
|
+
#syncScheduled = false;
|
|
6875
|
+
#followingLatest = true;
|
|
6876
|
+
#lastScrollTop = 0;
|
|
6877
|
+
connect(elements) {
|
|
6878
|
+
this.disconnect();
|
|
6879
|
+
this.#region = elements.region;
|
|
6880
|
+
this.#messages = elements.messages;
|
|
6881
|
+
this.#control = elements.control;
|
|
6882
|
+
this.#lastScrollTop = elements.messages.scrollTop;
|
|
6883
|
+
this.#followingLatest = this.#distanceFromBottom() <= 30;
|
|
6884
|
+
elements.messages.addEventListener("scroll", this.#handleScroll, { passive: true });
|
|
6885
|
+
elements.control.addEventListener("click", this.#handleControlClick);
|
|
6886
|
+
if (globalThis.MutationObserver) {
|
|
6887
|
+
this.#mutationObserver = new MutationObserver(() => this.#scheduleContentSync());
|
|
6888
|
+
this.#mutationObserver.observe(elements.messages, {
|
|
6889
|
+
childList: true,
|
|
6890
|
+
subtree: true,
|
|
6891
|
+
attributes: true,
|
|
6892
|
+
attributeFilter: ["style"]
|
|
6893
|
+
});
|
|
6894
|
+
}
|
|
6895
|
+
if (globalThis.ResizeObserver) {
|
|
6896
|
+
this.#resizeObserver = new ResizeObserver(() => this.#scheduleContentSync());
|
|
6897
|
+
this.#resizeObserver.observe(elements.messages);
|
|
6898
|
+
}
|
|
6899
|
+
this.sync();
|
|
6900
|
+
}
|
|
6901
|
+
disconnect() {
|
|
6902
|
+
this.#messages?.removeEventListener("scroll", this.#handleScroll);
|
|
6903
|
+
this.#control?.removeEventListener("click", this.#handleControlClick);
|
|
6904
|
+
this.#mutationObserver?.disconnect();
|
|
6905
|
+
this.#resizeObserver?.disconnect();
|
|
6906
|
+
this.#region?.removeAttribute("data-can-scroll-up");
|
|
6907
|
+
this.#region?.removeAttribute("data-can-scroll-down");
|
|
6908
|
+
this.#region = void 0;
|
|
6909
|
+
this.#messages = void 0;
|
|
6910
|
+
this.#control = void 0;
|
|
6911
|
+
this.#mutationObserver = void 0;
|
|
6912
|
+
this.#resizeObserver = void 0;
|
|
6913
|
+
this.#syncScheduled = false;
|
|
6914
|
+
this.#followingLatest = true;
|
|
6915
|
+
this.#lastScrollTop = 0;
|
|
6916
|
+
}
|
|
6917
|
+
revealLatest() {
|
|
6918
|
+
if (!this.#messages) return;
|
|
6919
|
+
if (this.#followingLatest || this.#distanceFromBottom() <= 160) {
|
|
6920
|
+
this.scrollToBottom();
|
|
6921
|
+
return;
|
|
6922
|
+
}
|
|
6923
|
+
this.sync();
|
|
6924
|
+
}
|
|
6925
|
+
scrollToBottom() {
|
|
6926
|
+
if (!this.#messages) return;
|
|
6927
|
+
this.#followingLatest = true;
|
|
6928
|
+
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
6929
|
+
this.sync();
|
|
6930
|
+
}
|
|
6931
|
+
sync() {
|
|
6932
|
+
if (!this.#messages || !this.#region || !this.#control) return;
|
|
6933
|
+
const distance = this.#distanceFromBottom();
|
|
6934
|
+
this.#region.toggleAttribute("data-can-scroll-up", this.#messages.scrollTop > 20);
|
|
6935
|
+
this.#region.toggleAttribute("data-can-scroll-down", distance > 20);
|
|
6936
|
+
this.#control.hidden = distance <= 100;
|
|
6937
|
+
}
|
|
6938
|
+
#handleScroll = () => {
|
|
6939
|
+
if (!this.#messages) return;
|
|
6940
|
+
const distance = this.#distanceFromBottom();
|
|
6941
|
+
const movedUp = this.#messages.scrollTop < this.#lastScrollTop - 5;
|
|
6942
|
+
this.#lastScrollTop = this.#messages.scrollTop;
|
|
6943
|
+
if (movedUp && distance > 50) this.#followingLatest = false;
|
|
6944
|
+
if (distance < 30) this.#followingLatest = true;
|
|
6945
|
+
this.sync();
|
|
6946
|
+
};
|
|
6947
|
+
#handleControlClick = () => {
|
|
6948
|
+
this.scrollToBottom();
|
|
6949
|
+
};
|
|
6950
|
+
#distanceFromBottom() {
|
|
6951
|
+
if (!this.#messages) return 0;
|
|
6952
|
+
return this.#messages.scrollHeight - this.#messages.scrollTop - this.#messages.clientHeight;
|
|
6953
|
+
}
|
|
6954
|
+
#scheduleContentSync() {
|
|
6955
|
+
if (this.#syncScheduled) return;
|
|
6956
|
+
this.#syncScheduled = true;
|
|
6957
|
+
queueMicrotask(() => {
|
|
6958
|
+
this.#syncScheduled = false;
|
|
6959
|
+
if (this.#followingLatest) {
|
|
6960
|
+
this.scrollToBottom();
|
|
6961
|
+
} else {
|
|
6962
|
+
this.sync();
|
|
6963
|
+
}
|
|
6964
|
+
});
|
|
6965
|
+
}
|
|
6966
|
+
};
|
|
6967
|
+
|
|
6812
6968
|
// src/element-styles.ts
|
|
6813
6969
|
var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
6814
6970
|
*, *::before, *::after { box-sizing: border-box; }
|
|
@@ -6822,40 +6978,48 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
|
6822
6978
|
.launcher { display: grid; place-items: center; width: 48px; height: 48px; border: 1px solid var(--ns-assistant-launcher-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: 999px; color: var(--ns-assistant-launcher-text, var(--ns-assistant-text, var(--ns-assistant-default-text))); background: var(--ns-assistant-launcher, var(--ns-assistant-panel, var(--ns-assistant-default-panel))); box-shadow: 0 8px 28px rgba(0,0,0,.14); cursor: pointer; transition: transform .24s cubic-bezier(.25,1,.5,1), box-shadow .2s ease; }
|
|
6823
6979
|
.launcher:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 8px 26px rgba(0,0,0,.16); }
|
|
6824
6980
|
.launcher img { width: 28px; height: 28px; border-radius: 50%; object-fit: contain; }
|
|
6825
|
-
.panel { display: none; flex-direction: column; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 40px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 40px)); overflow: hidden; color: var(--ns-assistant-panel-text, var(--ns-assistant-text, var(--ns-assistant-default-text))); background: var(--ns-assistant-panel, var(--ns-assistant-default-panel)); border: 1px solid var(--ns-assistant-panel-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); transform-origin: bottom right; animation: halo-panel-in .28s cubic-bezier(.23,1,.32,1) both; }
|
|
6981
|
+
.panel { display: none; flex-direction: column; width: min(var(--ns-assistant-panel-width, var(--ns-assistant-default-panel-width)), calc(100vw - 40px)); min-height: var(--ns-assistant-min-height, var(--ns-assistant-default-min-height)); max-height: min(var(--ns-assistant-max-height, var(--ns-assistant-default-max-height)), calc(100vh - 40px)); overflow: hidden; color: var(--ns-assistant-panel-text, var(--ns-assistant-text, var(--ns-assistant-default-text))); background: var(--ns-assistant-panel, var(--ns-assistant-default-panel)); border: 1px solid var(--ns-assistant-panel-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-default-panel-radius)); box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-default-shadow)); transform-origin: bottom right; isolation: isolate; animation: halo-panel-in .28s cubic-bezier(.23,1,.32,1) both; }
|
|
6826
6982
|
:host([open]) .panel { display: flex; }
|
|
6827
6983
|
.panel { position: relative; }
|
|
6828
6984
|
:host([open]) .launcher { display: none; }
|
|
6829
|
-
header { display: flex; flex: 0 0 auto; gap: 10px; align-items: center; min-height: 64px; padding: 12px 18px; color: var(--ns-assistant-header-text, inherit); background: var(--ns-assistant-header, transparent); border-bottom: 1px solid var(--ns-assistant-header-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); }
|
|
6830
|
-
header strong { flex: 1; font-size: 16px; font-weight: 600; letter-spacing:
|
|
6985
|
+
header { display: flex; flex: 0 0 auto; gap: 10px; align-items: center; min-height: 64px; padding: 12px 18px; color: var(--ns-assistant-header-text, inherit); background: var(--ns-assistant-header, transparent); border-bottom: 1px solid color-mix(in srgb, var(--ns-assistant-header-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))) 78%, transparent); }
|
|
6986
|
+
header strong { flex: 1; font-size: 16px; font-weight: 600; letter-spacing: 0; }
|
|
6831
6987
|
.brand-logo { display: block; max-width: 120px; max-height: 28px; object-fit: contain; }
|
|
6832
|
-
.close, .send { display: grid; place-items: center; border: 0; border-radius:
|
|
6833
|
-
.close { width: 44px; height: 44px; padding: 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent;
|
|
6988
|
+
.close, .send { display: grid; place-items: center; border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); cursor: pointer; }
|
|
6989
|
+
.close { position: relative; width: 44px; height: 44px; padding: 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; transition: background .15s ease, color .15s ease, transform .15s ease; }
|
|
6990
|
+
.close::before { content: ''; width: 18px; height: 18px; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 6 12 12M18 6 6 18' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 6 12 12M18 6 6 18' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat; }
|
|
6834
6991
|
.close:hover { color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); }
|
|
6992
|
+
.close:active { transform: scale(.96); }
|
|
6835
6993
|
.welcome { flex: 0 0 auto; padding: 30px 22px 18px; }
|
|
6836
|
-
.welcome h2 { margin: 0; font-size: 1.
|
|
6994
|
+
.welcome h2 { margin: 0; font-size: 1.35em; line-height: 1.25; letter-spacing: 0; }
|
|
6837
6995
|
.welcome p { max-width: 42ch; margin: 7px 0 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
|
|
6838
6996
|
:host([has-messages]) .welcome, :host([has-messages]) .suggested-prompts { display: none; }
|
|
6839
6997
|
.suggested-prompts { display: flex; flex: 0 0 auto; flex-wrap: wrap; gap: 8px; padding: 0 20px 16px; }
|
|
6840
6998
|
.suggested-prompts:empty { display: none; }
|
|
6841
|
-
.suggested-prompts button { min-height: 44px; padding:
|
|
6999
|
+
.suggested-prompts button { min-height: 44px; padding: 8px 14px; color: var(--ns-assistant-suggestion-text, var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text))); background: var(--ns-assistant-suggestion, color-mix(in srgb, var(--ns-assistant-input, var(--ns-assistant-default-input)) 58%, transparent)); border: 1px solid var(--ns-assistant-suggestion-border, color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 82%, transparent)); border-radius: 999px; cursor: pointer; font-size: .86em; transition: background .2s ease, color .2s ease, border-color .2s ease, transform .2s ease; }
|
|
6842
7000
|
.suggested-prompts button:hover { color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-elevated, var(--ns-assistant-default-elevated)); transform: translateY(-1px); }
|
|
6843
|
-
.messages {
|
|
7001
|
+
.messages-region { position: relative; display: flex; flex: 1 1 auto; min-height: 0; overflow: hidden; }
|
|
7002
|
+
.messages-region::before, .messages-region::after { content: ''; position: absolute; right: 0; left: 0; z-index: 1; height: 18px; pointer-events: none; opacity: 0; transition: opacity .18s ease; }
|
|
7003
|
+
.messages-region::before { top: 0; background: linear-gradient(to bottom, color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 92%, transparent), transparent); }
|
|
7004
|
+
.messages-region::after { bottom: 0; background: linear-gradient(to top, color-mix(in srgb, var(--ns-assistant-panel, var(--ns-assistant-default-panel)) 92%, transparent), transparent); }
|
|
7005
|
+
.messages-region[data-can-scroll-up]::before, .messages-region[data-can-scroll-down]::after { opacity: 1; }
|
|
7006
|
+
.messages { flex: 1 1 auto; width: 100%; min-height: 0; padding: 18px 20px 24px; overflow-y: auto; background: var(--ns-assistant-canvas, transparent); overscroll-behavior: contain; scroll-behavior: smooth; }
|
|
6844
7007
|
.messages::-webkit-scrollbar { width: 6px; }
|
|
6845
7008
|
.messages::-webkit-scrollbar-thumb { background: var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: 999px; }
|
|
6846
7009
|
.message { width: fit-content; max-width: 88%; margin: 0 0 14px; padding: 0; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: transparent; white-space: pre-wrap; animation: halo-message-in .2s ease both; }
|
|
6847
7010
|
.message > span, .message > .markdown { overflow-wrap: anywhere; }
|
|
6848
7011
|
.message .avatar { float: left; width: 24px; height: 24px; margin-right: 9px; border-radius: 50%; object-fit: cover; }
|
|
6849
7012
|
.message time { display: block; margin-top: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .75em; line-height: 1.2; }
|
|
6850
|
-
.message-copy { min-width: 44px; min-height: 32px; margin-top: 6px; padding: 4px
|
|
7013
|
+
.message-copy { min-width: 44px; min-height: 32px; margin-top: 6px; padding: 4px 10px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); background: transparent; border: 0; border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); cursor: pointer; font-size: .78em; opacity: 0; transition: opacity .15s ease, background .15s ease; }
|
|
6851
7014
|
.message:hover .message-copy, .message:focus-within .message-copy { opacity: 1; }
|
|
6852
7015
|
.conversation-status { margin: 4px auto 14px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .82em; text-align: center; }
|
|
6853
|
-
.conversation-error { display: flex; gap: 12px; align-items: center; justify-content: space-between; margin: 8px 0 16px; padding: 12px 14px; color: var(--ns-assistant-danger, var(--ns-assistant-default-danger)); border: 1px solid color-mix(in srgb, var(--ns-assistant-danger, var(--ns-assistant-default-danger)) 28%, transparent); border-radius:
|
|
7016
|
+
.conversation-error { display: flex; gap: 12px; align-items: center; justify-content: space-between; margin: 8px 0 16px; padding: 12px 14px; color: var(--ns-assistant-danger, var(--ns-assistant-default-danger)); border: 1px solid color-mix(in srgb, var(--ns-assistant-danger, var(--ns-assistant-default-danger)) 28%, transparent); border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); background: color-mix(in srgb, var(--ns-assistant-danger, var(--ns-assistant-default-danger)) 7%, transparent); }
|
|
6854
7017
|
.conversation-error p { margin: 0; }
|
|
6855
|
-
.conversation-error button { min-height: 44px; padding: 8px
|
|
6856
|
-
.new-messages { position: absolute; left: 50%; bottom:
|
|
6857
|
-
.
|
|
6858
|
-
.message.
|
|
7018
|
+
.conversation-error button { min-height: 44px; padding: 8px 14px; color: var(--ns-assistant-secondary-button-text, inherit); background: var(--ns-assistant-secondary-button, var(--ns-assistant-elevated, var(--ns-assistant-default-elevated))); border: 1px solid var(--ns-assistant-secondary-button-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); cursor: pointer; font-weight: 600; }
|
|
7019
|
+
.new-messages { position: absolute; left: 50%; bottom: 14px; z-index: 2; width: 44px; height: 44px; padding: 0; color: var(--ns-assistant-secondary-button-text, var(--ns-assistant-text, var(--ns-assistant-default-text))); background: var(--ns-assistant-secondary-button, color-mix(in srgb, var(--ns-assistant-input, var(--ns-assistant-default-input)) 92%, transparent)); border: 1px solid var(--ns-assistant-secondary-button-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); box-shadow: 0 8px 24px rgba(0,0,0,.12); transform: translateX(-50%); cursor: pointer; }
|
|
7020
|
+
.new-messages::before { content: ''; display: block; width: 18px; height: 18px; margin: auto; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 9 6 6 6-6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 9 6 6 6-6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
|
|
7021
|
+
.message.assistant { max-width: 100%; color: var(--ns-assistant-assistant-message-text, inherit); background: var(--ns-assistant-assistant-message, transparent); border: 1px solid var(--ns-assistant-assistant-message-border, transparent); }
|
|
7022
|
+
.message.user { display: grid; max-width: 85%; justify-items: start; gap: 3px; margin-left: auto; padding: 10px 16px 8px; color: var(--ns-assistant-user-message-text, var(--ns-assistant-text, var(--ns-assistant-default-text))); background: var(--ns-assistant-user-message, var(--ns-assistant-elevated, var(--ns-assistant-default-elevated))); border: 1px solid var(--ns-assistant-user-message-border, transparent); border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); font-size: .94em; }
|
|
6859
7023
|
.message.user time { margin-top: 0; }
|
|
6860
7024
|
.markdown { white-space: normal; }
|
|
6861
7025
|
.markdown p { margin: 0 0 8px; }
|
|
@@ -6870,13 +7034,14 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
|
6870
7034
|
.markdown ul, .markdown ol { margin: 8px 0; padding-left: 22px; }
|
|
6871
7035
|
.markdown li { margin: 3px 0; }
|
|
6872
7036
|
.markdown blockquote { margin: 10px 0; padding-left: 12px; border-left: 3px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
|
|
6873
|
-
.markdown h1, .markdown h2, .markdown h3, .markdown h4, .markdown h5, .markdown h6 { margin: 14px 0 7px; line-height: 1.25; letter-spacing:
|
|
7037
|
+
.markdown h1, .markdown h2, .markdown h3, .markdown h4, .markdown h5, .markdown h6 { margin: 14px 0 7px; line-height: 1.25; letter-spacing: 0; }
|
|
6874
7038
|
.markdown h1:first-child, .markdown h2:first-child, .markdown h3:first-child { margin-top: 0; }
|
|
6875
7039
|
.markdown h1 { font-size: 1.3em; } .markdown h2 { font-size: 1.18em; } .markdown h3 { font-size: 1.08em; }
|
|
7040
|
+
.message.assistant.streaming .markdown::after { content: ''; display: inline-block; width: 2px; height: 1em; margin-left: 3px; border-radius: 999px; background: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); vertical-align: -.14em; animation: halo-caret-blink 1s steps(2, start) infinite; }
|
|
6876
7041
|
.message.thinking > span { display: inline-block; color: transparent; background: linear-gradient(90deg, var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)) 25%, var(--ns-assistant-text, var(--ns-assistant-default-text)) 50%, var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)) 75%); background-size: 300% 100%; background-clip: text; -webkit-background-clip: text; font-style: italic; font-weight: 500; animation: halo-shimmer 2s linear infinite; }
|
|
6877
7042
|
.tool-proposal { display: grid; gap: 12px; align-items: start; margin: 8px 0 16px; padding: 18px; color: var(--ns-assistant-confirmation-text, inherit); border: 1px solid var(--ns-assistant-confirmation-border, var(--ns-assistant-divider, var(--ns-assistant-default-divider))); border-radius: var(--ns-assistant-card-radius, 14px); background: var(--ns-assistant-confirmation, var(--ns-assistant-input, var(--ns-assistant-default-input))); animation: halo-message-in .2s ease both; }
|
|
6878
7043
|
.proposal-eyebrow { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .75em; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
|
|
6879
|
-
.tool-proposal h3 { margin: -4px 0 0; font-size: 1.08em; line-height: 1.3; letter-spacing:
|
|
7044
|
+
.tool-proposal h3 { margin: -4px 0 0; font-size: 1.08em; line-height: 1.3; letter-spacing: 0; }
|
|
6880
7045
|
.proposal-description { margin: -4px 0 0; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
|
|
6881
7046
|
.proposal-arguments { display: grid; grid-template-columns: minmax(100px, .7fr) minmax(0, 1.3fr); gap: 8px 14px; margin: 0; padding: 12px 0; border-block: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); font-size: .9em; }
|
|
6882
7047
|
.proposal-arguments .proposal-arguments { grid-column: 1 / -1; padding: 4px 0 0; border: 0; }
|
|
@@ -6887,7 +7052,7 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
|
6887
7052
|
.proposal-details summary { min-height: 36px; padding: 8px 0; cursor: pointer; font-weight: 600; }
|
|
6888
7053
|
.proposal-details .proposal-arguments { margin-top: 4px; }
|
|
6889
7054
|
.proposal-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: end; }
|
|
6890
|
-
.tool-proposal button { min-height: 44px; padding: 9px
|
|
7055
|
+
.tool-proposal button { min-height: 44px; padding: 9px 16px; border: 1px solid var(--ns-assistant-secondary-button-border, transparent); border-radius: var(--ns-assistant-button-radius, var(--ns-assistant-default-button-radius)); color: var(--ns-assistant-secondary-button-text, var(--ns-assistant-text, var(--ns-assistant-default-text))); background: var(--ns-assistant-secondary-button, var(--ns-assistant-elevated, var(--ns-assistant-default-elevated))); cursor: pointer; font-weight: 600; }
|
|
6891
7056
|
.tool-proposal .proposal-accept { color: var(--ns-assistant-primary-button-text, var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text))); background: var(--ns-assistant-primary-button, var(--ns-assistant-accent, var(--ns-assistant-default-accent))); border-color: var(--ns-assistant-primary-button-border, transparent); }
|
|
6892
7057
|
.tool-proposal button:disabled { opacity: .55; cursor: not-allowed; }
|
|
6893
7058
|
.tool-proposal button { min-height: 45px; }
|
|
@@ -6896,9 +7061,9 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
|
6896
7061
|
.input-request form { display: grid; gap: 10px; align-items: stretch; min-height: 0; margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
|
|
6897
7062
|
.input-request form:focus-within { box-shadow: none; }
|
|
6898
7063
|
.input-request label { display: grid; gap: 4px; color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); font-size: .9em; }
|
|
6899
|
-
.input-request input, .input-request select { width: 100%; padding: 8px
|
|
6900
|
-
.input-request select[multiple] { min-height: 88px; }
|
|
6901
|
-
.input-request input[type="checkbox"] { width: auto; justify-self: start; accent-color: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
|
|
7064
|
+
.input-request input, .input-request select { width: 100%; min-height: 44px; padding: 8px 14px; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: var(--ns-assistant-input, var(--ns-assistant-default-input)); border: 1px solid var(--ns-assistant-divider, var(--ns-assistant-default-divider)); border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); outline: 0; font: inherit; }
|
|
7065
|
+
.input-request select[multiple] { min-height: 88px; border-radius: var(--ns-assistant-card-radius, var(--ns-assistant-default-card-radius)); }
|
|
7066
|
+
.input-request input[type="checkbox"] { width: auto; min-height: auto; justify-self: start; accent-color: var(--ns-assistant-accent, var(--ns-assistant-default-accent)); }
|
|
6902
7067
|
.input-request input:focus-visible, .input-request select:focus-visible { border-color: var(--ns-assistant-focus, var(--ns-assistant-default-focus)); box-shadow: 0 0 0 2px var(--ns-assistant-focus, var(--ns-assistant-default-focus)); }
|
|
6903
7068
|
.input-request .proposal-actions { margin-top: 2px; }
|
|
6904
7069
|
.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))); }
|
|
@@ -6907,15 +7072,15 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
|
6907
7072
|
.noodle-app-fallback { padding: 14px 16px; font-size: 13px; color: var(--ns-assistant-muted, var(--ns-assistant-default-muted, #6b7280)); }
|
|
6908
7073
|
.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)); }
|
|
6909
7074
|
.noodle-app-card[data-fullscreen] .noodle-app-frame { height: 100% !important; }
|
|
6910
|
-
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,
|
|
7075
|
+
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, color-mix(in srgb, var(--ns-assistant-divider, var(--ns-assistant-default-divider)) 86%, transparent)); border-radius: var(--ns-assistant-input-radius, var(--ns-assistant-default-input-radius)); background: var(--ns-assistant-composer, color-mix(in srgb, var(--ns-assistant-input, var(--ns-assistant-default-input)) 92%, transparent)); box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.035); transition: border-color .15s ease, box-shadow .15s ease; }
|
|
6911
7076
|
form:focus-within { box-shadow: inset 0 0 0 1px var(--ns-assistant-focus, var(--ns-assistant-default-focus)), 0 0 0 2px var(--ns-assistant-focus, var(--ns-assistant-default-focus)); }
|
|
6912
7077
|
textarea { flex: 1; min-height: 24px; max-height: 120px; resize: none; padding: 0; color: var(--ns-assistant-text, var(--ns-assistant-default-text)); background: transparent; border: 0; border-radius: 0; outline: 0; box-shadow: none; appearance: none; -webkit-appearance: none; font: inherit; font-size: 16px; line-height: 24px; }
|
|
6913
7078
|
textarea::placeholder { color: var(--ns-assistant-muted-text, var(--ns-assistant-default-muted-text)); }
|
|
6914
7079
|
textarea:focus, textarea:focus-visible { outline: none; box-shadow: none; }
|
|
6915
7080
|
button:focus-visible { outline: 3px solid var(--ns-assistant-focus, var(--ns-assistant-default-focus)); outline-offset: 2px; }
|
|
6916
|
-
.send { position: relative; display: block; width: 44px; height: 44px; flex: 0 0 44px; padding: 0; overflow: hidden; color: transparent; background: var(--ns-assistant-primary-button, var(--ns-assistant-accent, var(--ns-assistant-default-accent))); font-size: 0; line-height: 0; transition: transform .15s ease, background .15s ease; }
|
|
7081
|
+
.send { position: relative; display: block; width: 44px; height: 44px; flex: 0 0 44px; padding: 0; overflow: hidden; color: transparent; border-radius: 999px; background: var(--ns-assistant-primary-button, var(--ns-assistant-accent, var(--ns-assistant-default-accent))); font-size: 0; line-height: 0; transition: transform .15s ease, background .15s ease; }
|
|
6917
7082
|
.send::before { content: ''; position: absolute; top: 50%; left: 50%; width: 17px; height: 17px; background: var(--ns-assistant-primary-button-text, var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text))); transform: translate(-50%, -50%); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 19V5M5 12l7-7 7 7' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 19V5M5 12l7-7 7 7' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
|
|
6918
|
-
.send:hover { transform: scale(1.05); background: var(--ns-assistant-hover, var(--ns-assistant-default-
|
|
7083
|
+
.send:hover { transform: scale(1.05); background: var(--ns-assistant-hover, color-mix(in srgb, var(--ns-assistant-primary-button, var(--ns-assistant-accent, var(--ns-assistant-default-accent))) 88%, var(--ns-assistant-primary-button-text, var(--ns-assistant-accent-text, var(--ns-assistant-default-accent-text))) 12%)); }
|
|
6919
7084
|
:host([busy]) .send::before { width: 13px; height: 13px; border-radius: 3px; -webkit-mask: none; mask: none; }
|
|
6920
7085
|
.send:disabled, textarea:disabled { opacity: .55; cursor: not-allowed; }
|
|
6921
7086
|
.legal { display: flex; gap: 12px; justify-content: center; padding: 0 12px 9px; font-size: .75em; }
|
|
@@ -6925,9 +7090,10 @@ var ASSISTANT_ELEMENT_STYLES = `<style>
|
|
|
6925
7090
|
@keyframes halo-panel-in { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
|
|
6926
7091
|
@keyframes halo-message-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
|
|
6927
7092
|
@keyframes halo-shimmer { from { background-position: 100% center; } to { background-position: 0 center; } }
|
|
7093
|
+
@keyframes halo-caret-blink { 50% { opacity: 0; } }
|
|
6928
7094
|
:host([data-density="compact"]) .welcome { padding: 20px 18px 12px; }
|
|
6929
|
-
@media (max-width: 640px) { :host([mobile-fullscreen][open]) { inset: 0; } :host([mobile-fullscreen][open]) .panel { width: 100vw; min-height: 100vh; max-height: 100vh; border: 0; border-radius: 0; } }
|
|
6930
|
-
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } .messages { scroll-behavior: auto; } }
|
|
7095
|
+
@media (max-width: 640px) { :host([mobile-fullscreen][open]) { inset: 0; } :host([mobile-fullscreen][open]) .panel { width: 100vw; min-height: 100vh; max-height: 100vh; border: 0; border-radius: 0; } :host([mobile-fullscreen]) header { padding-top: max(12px, env(safe-area-inset-top)); padding-right: max(18px, env(safe-area-inset-right)); padding-left: max(18px, env(safe-area-inset-left)); } :host([mobile-fullscreen]) form { margin-right: max(16px, env(safe-area-inset-right)); margin-bottom: max(16px, env(safe-area-inset-bottom)); margin-left: max(16px, env(safe-area-inset-left)); } :host([mobile-fullscreen]) .legal, :host([mobile-fullscreen]) ::slotted([slot="conversation-footer"]) { padding-bottom: max(10px, env(safe-area-inset-bottom)); } }
|
|
7096
|
+
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } .messages { scroll-behavior: auto; } .message.assistant.streaming .markdown::after { animation: none; } }
|
|
6931
7097
|
@media (forced-colors: active) { .message.thinking > span { color: CanvasText; background: none; } }
|
|
6932
7098
|
@media (hover: none) { .message-copy { opacity: 1; } }
|
|
6933
7099
|
@media (max-width: 560px) { :host([data-mode="floating"]) { inset: auto 12px 12px; } :host([open]) .panel { width: calc(100vw - 24px); max-height: calc(100vh - 24px); } }
|
|
@@ -7246,6 +7412,8 @@ var presentationStyles = `<style>
|
|
|
7246
7412
|
border: var(--ns-assistant-panel-border, var(--ns-assistant-presentation-border));
|
|
7247
7413
|
border-radius: var(--ns-assistant-panel-radius, var(--ns-assistant-presentation-panel-radius, var(--ns-assistant-default-panel-radius)));
|
|
7248
7414
|
box-shadow: var(--ns-assistant-shadow, var(--ns-assistant-presentation-shadow));
|
|
7415
|
+
backdrop-filter: blur(var(--ns-assistant-backdrop-blur, var(--ns-assistant-default-backdrop-blur)));
|
|
7416
|
+
-webkit-backdrop-filter: blur(var(--ns-assistant-backdrop-blur, var(--ns-assistant-default-backdrop-blur)));
|
|
7249
7417
|
}
|
|
7250
7418
|
:host([data-panel-surface="solid"]) .panel {
|
|
7251
7419
|
backdrop-filter: none;
|
|
@@ -7439,6 +7607,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7439
7607
|
#hostAppearance;
|
|
7440
7608
|
#appearanceWarningKeys = /* @__PURE__ */ new Set();
|
|
7441
7609
|
#appearanceStyleSnapshot = /* @__PURE__ */ new Map();
|
|
7610
|
+
#scroll = new AssistantElementScrollController();
|
|
7442
7611
|
sessionEndpoint = "";
|
|
7443
7612
|
get appearance() {
|
|
7444
7613
|
return this.#hostAppearance;
|
|
@@ -7466,6 +7635,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7466
7635
|
labels: () => this.#appearance.labels,
|
|
7467
7636
|
respond: (id, response) => this.respond(id, response),
|
|
7468
7637
|
dispatchError: (detail) => this.#dispatchError(detail),
|
|
7638
|
+
revealLatest: () => this.#revealLatest(),
|
|
7469
7639
|
renderView: (detail) => {
|
|
7470
7640
|
const messages = this.#messages;
|
|
7471
7641
|
const client = this.#client;
|
|
@@ -7476,7 +7646,8 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7476
7646
|
{
|
|
7477
7647
|
client,
|
|
7478
7648
|
sendMessage: (message) => this.sendMessage(message),
|
|
7479
|
-
updateModelContext: (update) => this.updateModelContext(update)
|
|
7649
|
+
updateModelContext: (update) => this.updateModelContext(update),
|
|
7650
|
+
theme: this.#resolvedMode()
|
|
7480
7651
|
},
|
|
7481
7652
|
{
|
|
7482
7653
|
...sandboxUrl === void 0 ? {} : { sandboxUrl },
|
|
@@ -7486,7 +7657,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7486
7657
|
if (!view) return;
|
|
7487
7658
|
messages.append(view);
|
|
7488
7659
|
this.setAttribute("has-messages", "");
|
|
7489
|
-
|
|
7660
|
+
this.#revealLatest();
|
|
7490
7661
|
}
|
|
7491
7662
|
});
|
|
7492
7663
|
connectedCallback() {
|
|
@@ -7509,6 +7680,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7509
7680
|
this.#clientEndpoint = "";
|
|
7510
7681
|
this.#unsubscribeClient = void 0;
|
|
7511
7682
|
this.#sessionBootstrap = void 0;
|
|
7683
|
+
this.#scroll.disconnect();
|
|
7512
7684
|
this.#setBusy(false);
|
|
7513
7685
|
this.#media?.removeEventListener("change", this.#handleSystemTheme);
|
|
7514
7686
|
document.removeEventListener("keydown", this.#handleDocumentKeydown);
|
|
@@ -7791,18 +7963,10 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7791
7963
|
this.#messages.append(status);
|
|
7792
7964
|
}
|
|
7793
7965
|
#scrollToBottom() {
|
|
7794
|
-
|
|
7966
|
+
this.#scroll.scrollToBottom();
|
|
7795
7967
|
}
|
|
7796
7968
|
#revealLatest() {
|
|
7797
|
-
|
|
7798
|
-
const distance = this.#messages.scrollHeight - this.#messages.scrollTop - this.#messages.clientHeight;
|
|
7799
|
-
const control = this.shadowRoot?.querySelector(".new-messages");
|
|
7800
|
-
if (distance <= 160) {
|
|
7801
|
-
this.#scrollToBottom();
|
|
7802
|
-
if (control) control.hidden = true;
|
|
7803
|
-
} else if (control) {
|
|
7804
|
-
control.hidden = false;
|
|
7805
|
-
}
|
|
7969
|
+
this.#scroll.revealLatest();
|
|
7806
7970
|
}
|
|
7807
7971
|
#dispatchError(detail) {
|
|
7808
7972
|
this.dispatchEvent(new CustomEvent("assistant-error", { detail }));
|
|
@@ -7919,6 +8083,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7919
8083
|
}
|
|
7920
8084
|
#render() {
|
|
7921
8085
|
if (!this.shadowRoot) return;
|
|
8086
|
+
this.#scroll.disconnect();
|
|
7922
8087
|
const conversation = this.#messages ? [...this.#messages.childNodes] : [];
|
|
7923
8088
|
const appearance = this.#appearance;
|
|
7924
8089
|
this.setAttribute("role", "complementary");
|
|
@@ -7932,11 +8097,13 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7932
8097
|
this.shadowRoot.innerHTML = `${ASSISTANT_ELEMENT_STYLES}${presentationStyles}
|
|
7933
8098
|
<button class="launcher" type="button" aria-label="${escapeAttribute(appearance.labels.open)}" aria-controls="assistant-panel" aria-expanded="${String(this.hasAttribute("open"))}"><slot name="launcher-icon"></slot><span class="visually-hidden" data-session-status aria-live="polite" hidden></span></button>
|
|
7934
8099
|
<section class="panel" id="assistant-panel" role="dialog" aria-label="${escapeAttribute(appearance.brand.name)}">
|
|
7935
|
-
<header><slot name="header-leading"></slot><img class="brand-logo" alt=""><strong></strong><slot name="header-actions"></slot><button class="close" type="button" aria-label="${escapeAttribute(appearance.labels.close)}"
|
|
8100
|
+
<header><slot name="header-leading"></slot><img class="brand-logo" alt=""><strong></strong><slot name="header-actions"></slot><button class="close" type="button" aria-label="${escapeAttribute(appearance.labels.close)}"></button></header>
|
|
7936
8101
|
<div class="welcome"><slot name="empty-state"></slot></div>
|
|
7937
8102
|
<div class="suggested-prompts"></div>
|
|
7938
|
-
<div class="messages
|
|
7939
|
-
|
|
8103
|
+
<div class="messages-region">
|
|
8104
|
+
<div class="messages" aria-live="polite"></div>
|
|
8105
|
+
<button class="new-messages" type="button" aria-label="${escapeAttribute(appearance.labels.newMessages)}" hidden></button>
|
|
8106
|
+
</div>
|
|
7940
8107
|
<form><slot name="composer-leading"></slot><textarea rows="1"></textarea><button class="send" type="submit"></button><slot name="composer-trailing"></slot></form>
|
|
7941
8108
|
<nav class="legal" aria-label="Legal"></nav>
|
|
7942
8109
|
<slot name="conversation-footer"></slot>
|
|
@@ -7998,15 +8165,11 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
7998
8165
|
form.requestSubmit();
|
|
7999
8166
|
});
|
|
8000
8167
|
const newMessages = queryRequired(this.shadowRoot, ".new-messages");
|
|
8001
|
-
newMessages.
|
|
8002
|
-
|
|
8003
|
-
this
|
|
8004
|
-
|
|
8005
|
-
|
|
8006
|
-
this.#messages?.addEventListener("scroll", () => {
|
|
8007
|
-
if (this.#messages && this.#messages.scrollHeight - this.#messages.scrollTop - this.#messages.clientHeight < 48) {
|
|
8008
|
-
newMessages.hidden = true;
|
|
8009
|
-
}
|
|
8168
|
+
newMessages.setAttribute("aria-label", appearance.labels.newMessages);
|
|
8169
|
+
this.#scroll.connect({
|
|
8170
|
+
region: queryRequired(this.shadowRoot, ".messages-region"),
|
|
8171
|
+
messages: queryRequired(this.shadowRoot, ".messages"),
|
|
8172
|
+
control: newMessages
|
|
8010
8173
|
});
|
|
8011
8174
|
this.#applyTheme();
|
|
8012
8175
|
}
|
|
@@ -8032,6 +8195,8 @@ function registerNoodleAssistant() {
|
|
|
8032
8195
|
}
|
|
8033
8196
|
|
|
8034
8197
|
export {
|
|
8198
|
+
mountAssistantApp,
|
|
8199
|
+
unmountAssistantApp,
|
|
8035
8200
|
ASSISTANT_TAG_NAME,
|
|
8036
8201
|
NoodleAssistantElement,
|
|
8037
8202
|
registerNoodleAssistant
|
|
@@ -8041,4 +8206,4 @@ export {
|
|
|
8041
8206
|
dompurify/dist/purify.es.mjs:
|
|
8042
8207
|
(*! @license DOMPurify 3.4.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.11/LICENSE *)
|
|
8043
8208
|
*/
|
|
8044
|
-
//# sourceMappingURL=chunk-
|
|
8209
|
+
//# sourceMappingURL=chunk-4B3XXGRP.js.map
|