@noodleseed/assistant 1.18.0 → 1.20.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 +68 -0
- package/dist/{chunk-RIKRQFKS.js → chunk-52XT7BLR.js} +10 -4
- package/dist/{chunk-RIKRQFKS.js.map → chunk-52XT7BLR.js.map} +1 -1
- package/dist/{chunk-MZNENVFY.js → chunk-DLUINP4W.js} +165 -13
- package/dist/chunk-DLUINP4W.js.map +1 -0
- package/dist/{client-BQ30Fq-c.d.cts → client-7o7n2nqw.d.cts} +6 -4
- package/dist/{client-B6pnBmF8.d.ts → client-CysBQBdd.d.ts} +6 -4
- package/dist/client.cjs +8 -3
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/embed.global.js +57 -57
- package/dist/index.cjs +283 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/react/client.cjs +8 -3
- package/dist/react/client.cjs.map +1 -1
- package/dist/react/client.d.cts +1 -1
- package/dist/react/client.d.ts +1 -1
- package/dist/react/client.js +1 -1
- package/dist/react.cjs +283 -127
- 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 +2 -2
- package/dist/server.cjs +47 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +60 -7
- package/dist/server.d.ts +60 -7
- package/dist/server.js +45 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-MZNENVFY.js.map +0 -1
package/dist/react/client.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AssistantPageContext, a as AssistantContext, C as CreateAssistantClientOptions, b as AssistantChatState, c as AssistantClient } from '../client-
|
|
1
|
+
import { A as AssistantPageContext, a as AssistantContext, C as CreateAssistantClientOptions, b as AssistantChatState, c as AssistantClient } from '../client-7o7n2nqw.cjs';
|
|
2
2
|
import '../appearance-Cc-eqSbp.cjs';
|
|
3
3
|
import 'ai';
|
|
4
4
|
|
package/dist/react/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AssistantPageContext, a as AssistantContext, C as CreateAssistantClientOptions, b as AssistantChatState, c as AssistantClient } from '../client-
|
|
1
|
+
import { A as AssistantPageContext, a as AssistantContext, C as CreateAssistantClientOptions, b as AssistantChatState, c as AssistantClient } from '../client-CysBQBdd.js';
|
|
2
2
|
import '../appearance-Cc-eqSbp.js';
|
|
3
3
|
import 'ai';
|
|
4
4
|
|
package/dist/react/client.js
CHANGED
package/dist/react.cjs
CHANGED
|
@@ -22570,7 +22570,122 @@ function radiusValue(radius) {
|
|
|
22570
22570
|
return 14;
|
|
22571
22571
|
}
|
|
22572
22572
|
|
|
22573
|
+
// src/model-context.ts
|
|
22574
|
+
var MAX_BYTES = 16 * 1024;
|
|
22575
|
+
var MAX_DEPTH = 8;
|
|
22576
|
+
var MAX_ENTRIES = 128;
|
|
22577
|
+
var SENSITIVE_KEY = /(?:secret|token|api[-_]?key|password|credential|authorization|cookie)/i;
|
|
22578
|
+
var CREDENTIAL_SHAPED_TEXT = /(?:-----BEGIN [A-Z ]*PRIVATE KEY-----|\bsk-[A-Za-z0-9_-]{20,}\b|\b(?:bearer|basic)\s+[A-Za-z0-9._~+/=-]{20,}\b|\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b)/i;
|
|
22579
|
+
function copyAssistantModelContext(update) {
|
|
22580
|
+
const copied = copyJsonValue(update, "$", 0, /* @__PURE__ */ new Set());
|
|
22581
|
+
assertModelContextShape(copied);
|
|
22582
|
+
const encoded = JSON.stringify(copied);
|
|
22583
|
+
if (new TextEncoder().encode(encoded).byteLength > MAX_BYTES) {
|
|
22584
|
+
throw new Error("Model context must not exceed 16 KiB");
|
|
22585
|
+
}
|
|
22586
|
+
return copied;
|
|
22587
|
+
}
|
|
22588
|
+
function copyAssistantPageContext(context) {
|
|
22589
|
+
const copied = copyJsonValue(context, "$", 0, /* @__PURE__ */ new Set());
|
|
22590
|
+
if (typeof copied !== "object" || copied === null || Array.isArray(copied)) {
|
|
22591
|
+
throw new Error("Page context must be a JSON object");
|
|
22592
|
+
}
|
|
22593
|
+
const encoded = JSON.stringify(copied);
|
|
22594
|
+
if (new TextEncoder().encode(encoded).byteLength > MAX_BYTES) {
|
|
22595
|
+
throw new Error("Page context must not exceed 16 KiB");
|
|
22596
|
+
}
|
|
22597
|
+
return copied;
|
|
22598
|
+
}
|
|
22599
|
+
function assertModelContextShape(value) {
|
|
22600
|
+
if (!isPlainRecord(value)) throw new Error("Model context must be a JSON object");
|
|
22601
|
+
for (const key of Object.keys(value)) {
|
|
22602
|
+
if (key !== "content" && key !== "structuredContent") {
|
|
22603
|
+
throw new Error(`Model context contains unknown field ${key}`);
|
|
22604
|
+
}
|
|
22605
|
+
}
|
|
22606
|
+
if (value.content !== void 0) {
|
|
22607
|
+
if (!Array.isArray(value.content)) throw new Error("Model context content must be an array");
|
|
22608
|
+
for (const part of value.content) {
|
|
22609
|
+
if (!isPlainRecord(part) || Object.keys(part).some((key) => key !== "type" && key !== "text") || part.type !== "text" || typeof part.text !== "string") {
|
|
22610
|
+
throw new Error("Model context content supports text parts only");
|
|
22611
|
+
}
|
|
22612
|
+
}
|
|
22613
|
+
}
|
|
22614
|
+
if (value.structuredContent !== void 0 && !isPlainRecord(value.structuredContent)) {
|
|
22615
|
+
throw new Error("Model context structuredContent must be an object");
|
|
22616
|
+
}
|
|
22617
|
+
}
|
|
22618
|
+
function copyJsonValue(value, path, depth, ancestors) {
|
|
22619
|
+
if (depth > MAX_DEPTH) throw new Error(`Model context exceeds maximum depth at ${path}`);
|
|
22620
|
+
if (typeof value === "string") {
|
|
22621
|
+
if (CREDENTIAL_SHAPED_TEXT.test(value)) {
|
|
22622
|
+
throw new Error(`Model context contains credential-shaped text at ${path}`);
|
|
22623
|
+
}
|
|
22624
|
+
return value;
|
|
22625
|
+
}
|
|
22626
|
+
if (value === null || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
|
|
22627
|
+
return value;
|
|
22628
|
+
}
|
|
22629
|
+
if (typeof value !== "object") throw new Error(`Model context contains non-JSON data at ${path}`);
|
|
22630
|
+
if (hasToJsonProperty(value)) {
|
|
22631
|
+
throw new Error(`Model context must not define or inherit toJSON at ${path}`);
|
|
22632
|
+
}
|
|
22633
|
+
const prototype = Object.getPrototypeOf(value);
|
|
22634
|
+
if (Array.isArray(value)) {
|
|
22635
|
+
if (prototype !== Array.prototype) {
|
|
22636
|
+
throw new Error(`Model context contains a non-JSON object at ${path}`);
|
|
22637
|
+
}
|
|
22638
|
+
} else if (prototype !== Object.prototype && prototype !== null) {
|
|
22639
|
+
throw new Error(`Model context contains a non-JSON object at ${path}`);
|
|
22640
|
+
}
|
|
22641
|
+
if (ancestors.has(value)) throw new Error(`Model context contains a cycle at ${path}`);
|
|
22642
|
+
if (Array.isArray(value)) {
|
|
22643
|
+
if (value.length > MAX_ENTRIES) {
|
|
22644
|
+
throw new Error(`Model context has more than 128 entries at ${path}`);
|
|
22645
|
+
}
|
|
22646
|
+
const copy2 = [];
|
|
22647
|
+
ancestors.add(value);
|
|
22648
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
22649
|
+
const entry = Object.hasOwn(value, index) ? value[index] : null;
|
|
22650
|
+
copy2.push(copyJsonValue(entry, `${path}.${index}`, depth + 1, ancestors));
|
|
22651
|
+
}
|
|
22652
|
+
ancestors.delete(value);
|
|
22653
|
+
return copy2;
|
|
22654
|
+
}
|
|
22655
|
+
const entries2 = Object.entries(value);
|
|
22656
|
+
if (entries2.length > MAX_ENTRIES) {
|
|
22657
|
+
throw new Error(`Model context has more than 128 entries at ${path}`);
|
|
22658
|
+
}
|
|
22659
|
+
const copy = /* @__PURE__ */ Object.create(null);
|
|
22660
|
+
ancestors.add(value);
|
|
22661
|
+
for (const [key, entry] of entries2) {
|
|
22662
|
+
if (SENSITIVE_KEY.test(key)) {
|
|
22663
|
+
throw new Error(`Model context contains sensitive key ${path}.${key}`);
|
|
22664
|
+
}
|
|
22665
|
+
copy[key] = copyJsonValue(entry, `${path}.${key}`, depth + 1, ancestors);
|
|
22666
|
+
}
|
|
22667
|
+
ancestors.delete(value);
|
|
22668
|
+
return copy;
|
|
22669
|
+
}
|
|
22670
|
+
function isPlainRecord(value) {
|
|
22671
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
22672
|
+
const prototype = Object.getPrototypeOf(value);
|
|
22673
|
+
return prototype === Object.prototype || prototype === null;
|
|
22674
|
+
}
|
|
22675
|
+
function hasToJsonProperty(value) {
|
|
22676
|
+
let current = value;
|
|
22677
|
+
const visited = /* @__PURE__ */ new Set();
|
|
22678
|
+
while (current !== null && !visited.has(current)) {
|
|
22679
|
+
visited.add(current);
|
|
22680
|
+
if (Object.getOwnPropertyDescriptor(current, "toJSON") !== void 0) return true;
|
|
22681
|
+
current = Object.getPrototypeOf(current);
|
|
22682
|
+
}
|
|
22683
|
+
return false;
|
|
22684
|
+
}
|
|
22685
|
+
|
|
22573
22686
|
// src/browser-context.ts
|
|
22687
|
+
var PAGE_MARKDOWN_MAX_BYTES = 12 * 1024;
|
|
22688
|
+
var PAGE_MARKDOWN_TIMEOUT_MS = 2e3;
|
|
22574
22689
|
function browserClientContext() {
|
|
22575
22690
|
let timeZone;
|
|
22576
22691
|
try {
|
|
@@ -22583,6 +22698,108 @@ function browserClientContext() {
|
|
|
22583
22698
|
...timeZone ? { timeZone } : {}
|
|
22584
22699
|
};
|
|
22585
22700
|
}
|
|
22701
|
+
function browserPageUrl() {
|
|
22702
|
+
try {
|
|
22703
|
+
const location = globalThis.location;
|
|
22704
|
+
if (!location) return void 0;
|
|
22705
|
+
const url2 = new URL(location.href);
|
|
22706
|
+
if (url2.origin === "null") return void 0;
|
|
22707
|
+
return `${url2.origin}${url2.pathname}`;
|
|
22708
|
+
} catch {
|
|
22709
|
+
return void 0;
|
|
22710
|
+
}
|
|
22711
|
+
}
|
|
22712
|
+
async function browserPageContext(url2) {
|
|
22713
|
+
let urlOnly;
|
|
22714
|
+
try {
|
|
22715
|
+
urlOnly = copyAssistantPageContext({ page: { url: url2 } });
|
|
22716
|
+
} catch {
|
|
22717
|
+
return void 0;
|
|
22718
|
+
}
|
|
22719
|
+
const controller = new AbortController();
|
|
22720
|
+
const timeout = globalThis.setTimeout(() => controller.abort(), PAGE_MARKDOWN_TIMEOUT_MS);
|
|
22721
|
+
try {
|
|
22722
|
+
const response = await fetch(url2, {
|
|
22723
|
+
headers: { Accept: "text/markdown" },
|
|
22724
|
+
credentials: "omit",
|
|
22725
|
+
cache: "no-store",
|
|
22726
|
+
redirect: "error",
|
|
22727
|
+
referrerPolicy: "no-referrer",
|
|
22728
|
+
signal: controller.signal
|
|
22729
|
+
});
|
|
22730
|
+
if (!response.ok || !isSameOrigin(response, url2) || !isMarkdown(response)) return urlOnly;
|
|
22731
|
+
const { content, truncated } = await readBoundedUtf8(response);
|
|
22732
|
+
const page = {
|
|
22733
|
+
page: {
|
|
22734
|
+
url: url2,
|
|
22735
|
+
contentType: "text/markdown",
|
|
22736
|
+
content,
|
|
22737
|
+
...truncated ? { truncated: true } : {}
|
|
22738
|
+
}
|
|
22739
|
+
};
|
|
22740
|
+
return copyAssistantPageContext(page);
|
|
22741
|
+
} catch {
|
|
22742
|
+
return urlOnly;
|
|
22743
|
+
} finally {
|
|
22744
|
+
globalThis.clearTimeout(timeout);
|
|
22745
|
+
}
|
|
22746
|
+
}
|
|
22747
|
+
function isSameOrigin(response, url2) {
|
|
22748
|
+
try {
|
|
22749
|
+
return response.url !== "" && new URL(response.url).origin === new URL(url2).origin;
|
|
22750
|
+
} catch {
|
|
22751
|
+
return false;
|
|
22752
|
+
}
|
|
22753
|
+
}
|
|
22754
|
+
function isMarkdown(response) {
|
|
22755
|
+
return response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase() === "text/markdown";
|
|
22756
|
+
}
|
|
22757
|
+
async function readBoundedUtf8(response) {
|
|
22758
|
+
const reader = response.body?.getReader();
|
|
22759
|
+
if (!reader) throw new Error("Markdown response has no readable body");
|
|
22760
|
+
const chunks = [];
|
|
22761
|
+
let byteLength = 0;
|
|
22762
|
+
let truncated = false;
|
|
22763
|
+
try {
|
|
22764
|
+
while (true) {
|
|
22765
|
+
const { done, value } = await reader.read();
|
|
22766
|
+
if (done) break;
|
|
22767
|
+
const remaining = PAGE_MARKDOWN_MAX_BYTES - byteLength;
|
|
22768
|
+
if (value.byteLength > remaining) {
|
|
22769
|
+
if (remaining > 0) chunks.push(value.slice(0, remaining));
|
|
22770
|
+
truncated = true;
|
|
22771
|
+
await reader.cancel();
|
|
22772
|
+
break;
|
|
22773
|
+
}
|
|
22774
|
+
chunks.push(value);
|
|
22775
|
+
byteLength += value.byteLength;
|
|
22776
|
+
}
|
|
22777
|
+
} finally {
|
|
22778
|
+
reader.releaseLock();
|
|
22779
|
+
}
|
|
22780
|
+
const bytes = new Uint8Array(chunks.reduce((size, chunk) => size + chunk.byteLength, 0));
|
|
22781
|
+
let offset = 0;
|
|
22782
|
+
for (const chunk of chunks) {
|
|
22783
|
+
bytes.set(chunk, offset);
|
|
22784
|
+
offset += chunk.byteLength;
|
|
22785
|
+
}
|
|
22786
|
+
return { content: decodeUtf8(bytes, truncated), truncated };
|
|
22787
|
+
}
|
|
22788
|
+
function decodeUtf8(bytes, truncated) {
|
|
22789
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
22790
|
+
let content;
|
|
22791
|
+
try {
|
|
22792
|
+
content = decoder.decode(bytes, { stream: true });
|
|
22793
|
+
} catch {
|
|
22794
|
+
throw new Error("Markdown response is not valid UTF-8");
|
|
22795
|
+
}
|
|
22796
|
+
try {
|
|
22797
|
+
return content + decoder.decode();
|
|
22798
|
+
} catch {
|
|
22799
|
+
if (truncated) return content;
|
|
22800
|
+
throw new Error("Markdown response is not valid UTF-8");
|
|
22801
|
+
}
|
|
22802
|
+
}
|
|
22586
22803
|
|
|
22587
22804
|
// ../../node_modules/.pnpm/@ai-sdk+provider@3.0.10/node_modules/@ai-sdk/provider/dist/index.mjs
|
|
22588
22805
|
var marker = "vercel.ai.error";
|
|
@@ -27095,11 +27312,16 @@ function toAssistantClientEvent(event) {
|
|
|
27095
27312
|
return event;
|
|
27096
27313
|
}
|
|
27097
27314
|
break;
|
|
27098
|
-
case "auth_requested":
|
|
27099
|
-
|
|
27100
|
-
|
|
27315
|
+
case "auth_requested": {
|
|
27316
|
+
const signInTicket = typeof value.signInTicket === "string" ? value.signInTicket : typeof value.continuation === "string" ? value.continuation : void 0;
|
|
27317
|
+
if (hasString(value, "id") && hasString(value, "tool") && signInTicket !== void 0 && hasString(value, "expiresAt") && hasOptionalTurnId(value)) {
|
|
27318
|
+
return {
|
|
27319
|
+
event: "auth_requested",
|
|
27320
|
+
data: { ...value, signInTicket }
|
|
27321
|
+
};
|
|
27101
27322
|
}
|
|
27102
27323
|
break;
|
|
27324
|
+
}
|
|
27103
27325
|
case "interaction_resolved":
|
|
27104
27326
|
if (hasString(value, "id") && (value.action === void 0 || isInteractionAction(value.action)) && hasOptionalTurnId(value)) {
|
|
27105
27327
|
return event;
|
|
@@ -27171,119 +27393,6 @@ function isRecord2(value) {
|
|
|
27171
27393
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27172
27394
|
}
|
|
27173
27395
|
|
|
27174
|
-
// src/model-context.ts
|
|
27175
|
-
var MAX_BYTES = 16 * 1024;
|
|
27176
|
-
var MAX_DEPTH = 8;
|
|
27177
|
-
var MAX_ENTRIES = 128;
|
|
27178
|
-
var SENSITIVE_KEY = /(?:secret|token|api[-_]?key|password|credential|authorization|cookie)/i;
|
|
27179
|
-
var CREDENTIAL_SHAPED_TEXT = /(?:-----BEGIN [A-Z ]*PRIVATE KEY-----|\bsk-[A-Za-z0-9_-]{20,}\b|\b(?:bearer|basic)\s+[A-Za-z0-9._~+/=-]{20,}\b|\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b)/i;
|
|
27180
|
-
function copyAssistantModelContext(update) {
|
|
27181
|
-
const copied = copyJsonValue(update, "$", 0, /* @__PURE__ */ new Set());
|
|
27182
|
-
assertModelContextShape(copied);
|
|
27183
|
-
const encoded = JSON.stringify(copied);
|
|
27184
|
-
if (new TextEncoder().encode(encoded).byteLength > MAX_BYTES) {
|
|
27185
|
-
throw new Error("Model context must not exceed 16 KiB");
|
|
27186
|
-
}
|
|
27187
|
-
return copied;
|
|
27188
|
-
}
|
|
27189
|
-
function copyAssistantPageContext(context) {
|
|
27190
|
-
const copied = copyJsonValue(context, "$", 0, /* @__PURE__ */ new Set());
|
|
27191
|
-
if (typeof copied !== "object" || copied === null || Array.isArray(copied)) {
|
|
27192
|
-
throw new Error("Page context must be a JSON object");
|
|
27193
|
-
}
|
|
27194
|
-
const encoded = JSON.stringify(copied);
|
|
27195
|
-
if (new TextEncoder().encode(encoded).byteLength > MAX_BYTES) {
|
|
27196
|
-
throw new Error("Page context must not exceed 16 KiB");
|
|
27197
|
-
}
|
|
27198
|
-
return copied;
|
|
27199
|
-
}
|
|
27200
|
-
function assertModelContextShape(value) {
|
|
27201
|
-
if (!isPlainRecord(value)) throw new Error("Model context must be a JSON object");
|
|
27202
|
-
for (const key of Object.keys(value)) {
|
|
27203
|
-
if (key !== "content" && key !== "structuredContent") {
|
|
27204
|
-
throw new Error(`Model context contains unknown field ${key}`);
|
|
27205
|
-
}
|
|
27206
|
-
}
|
|
27207
|
-
if (value.content !== void 0) {
|
|
27208
|
-
if (!Array.isArray(value.content)) throw new Error("Model context content must be an array");
|
|
27209
|
-
for (const part of value.content) {
|
|
27210
|
-
if (!isPlainRecord(part) || Object.keys(part).some((key) => key !== "type" && key !== "text") || part.type !== "text" || typeof part.text !== "string") {
|
|
27211
|
-
throw new Error("Model context content supports text parts only");
|
|
27212
|
-
}
|
|
27213
|
-
}
|
|
27214
|
-
}
|
|
27215
|
-
if (value.structuredContent !== void 0 && !isPlainRecord(value.structuredContent)) {
|
|
27216
|
-
throw new Error("Model context structuredContent must be an object");
|
|
27217
|
-
}
|
|
27218
|
-
}
|
|
27219
|
-
function copyJsonValue(value, path, depth, ancestors) {
|
|
27220
|
-
if (depth > MAX_DEPTH) throw new Error(`Model context exceeds maximum depth at ${path}`);
|
|
27221
|
-
if (typeof value === "string") {
|
|
27222
|
-
if (CREDENTIAL_SHAPED_TEXT.test(value)) {
|
|
27223
|
-
throw new Error(`Model context contains credential-shaped text at ${path}`);
|
|
27224
|
-
}
|
|
27225
|
-
return value;
|
|
27226
|
-
}
|
|
27227
|
-
if (value === null || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
|
|
27228
|
-
return value;
|
|
27229
|
-
}
|
|
27230
|
-
if (typeof value !== "object") throw new Error(`Model context contains non-JSON data at ${path}`);
|
|
27231
|
-
if (hasToJsonProperty(value)) {
|
|
27232
|
-
throw new Error(`Model context must not define or inherit toJSON at ${path}`);
|
|
27233
|
-
}
|
|
27234
|
-
const prototype = Object.getPrototypeOf(value);
|
|
27235
|
-
if (Array.isArray(value)) {
|
|
27236
|
-
if (prototype !== Array.prototype) {
|
|
27237
|
-
throw new Error(`Model context contains a non-JSON object at ${path}`);
|
|
27238
|
-
}
|
|
27239
|
-
} else if (prototype !== Object.prototype && prototype !== null) {
|
|
27240
|
-
throw new Error(`Model context contains a non-JSON object at ${path}`);
|
|
27241
|
-
}
|
|
27242
|
-
if (ancestors.has(value)) throw new Error(`Model context contains a cycle at ${path}`);
|
|
27243
|
-
if (Array.isArray(value)) {
|
|
27244
|
-
if (value.length > MAX_ENTRIES) {
|
|
27245
|
-
throw new Error(`Model context has more than 128 entries at ${path}`);
|
|
27246
|
-
}
|
|
27247
|
-
const copy2 = [];
|
|
27248
|
-
ancestors.add(value);
|
|
27249
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
27250
|
-
const entry = Object.hasOwn(value, index) ? value[index] : null;
|
|
27251
|
-
copy2.push(copyJsonValue(entry, `${path}.${index}`, depth + 1, ancestors));
|
|
27252
|
-
}
|
|
27253
|
-
ancestors.delete(value);
|
|
27254
|
-
return copy2;
|
|
27255
|
-
}
|
|
27256
|
-
const entries2 = Object.entries(value);
|
|
27257
|
-
if (entries2.length > MAX_ENTRIES) {
|
|
27258
|
-
throw new Error(`Model context has more than 128 entries at ${path}`);
|
|
27259
|
-
}
|
|
27260
|
-
const copy = /* @__PURE__ */ Object.create(null);
|
|
27261
|
-
ancestors.add(value);
|
|
27262
|
-
for (const [key, entry] of entries2) {
|
|
27263
|
-
if (SENSITIVE_KEY.test(key)) {
|
|
27264
|
-
throw new Error(`Model context contains sensitive key ${path}.${key}`);
|
|
27265
|
-
}
|
|
27266
|
-
copy[key] = copyJsonValue(entry, `${path}.${key}`, depth + 1, ancestors);
|
|
27267
|
-
}
|
|
27268
|
-
ancestors.delete(value);
|
|
27269
|
-
return copy;
|
|
27270
|
-
}
|
|
27271
|
-
function isPlainRecord(value) {
|
|
27272
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
27273
|
-
const prototype = Object.getPrototypeOf(value);
|
|
27274
|
-
return prototype === Object.prototype || prototype === null;
|
|
27275
|
-
}
|
|
27276
|
-
function hasToJsonProperty(value) {
|
|
27277
|
-
let current = value;
|
|
27278
|
-
const visited = /* @__PURE__ */ new Set();
|
|
27279
|
-
while (current !== null && !visited.has(current)) {
|
|
27280
|
-
visited.add(current);
|
|
27281
|
-
if (Object.getOwnPropertyDescriptor(current, "toJSON") !== void 0) return true;
|
|
27282
|
-
current = Object.getPrototypeOf(current);
|
|
27283
|
-
}
|
|
27284
|
-
return false;
|
|
27285
|
-
}
|
|
27286
|
-
|
|
27287
27396
|
// src/session-source.ts
|
|
27288
27397
|
var NOODLE_CLOUD_URL = "https://cloud.noodleseed.dev";
|
|
27289
27398
|
var PUBLIC_SESSION_PATH = "/v1/assistant/public-sessions";
|
|
@@ -31169,11 +31278,11 @@ var AssistantElementEventController = class {
|
|
|
31169
31278
|
);
|
|
31170
31279
|
return;
|
|
31171
31280
|
}
|
|
31172
|
-
if (name21 === "auth_requested" && typeof data.
|
|
31281
|
+
if (name21 === "auth_requested" && typeof data.signInTicket === "string") {
|
|
31173
31282
|
this.#appendSignInRequest(
|
|
31174
31283
|
String(data.id ?? ""),
|
|
31175
31284
|
String(data.tool ?? "this"),
|
|
31176
|
-
data.
|
|
31285
|
+
data.signInTicket,
|
|
31177
31286
|
String(data.expiresAt ?? "")
|
|
31178
31287
|
);
|
|
31179
31288
|
return;
|
|
@@ -31266,15 +31375,15 @@ var AssistantElementEventController = class {
|
|
|
31266
31375
|
/**
|
|
31267
31376
|
* The host application owns the login. This renders the prompt and raises
|
|
31268
31377
|
* `assistant-sign-in-requested`; the page signs the visitor in however it already does, then its
|
|
31269
|
-
* backend spends the
|
|
31378
|
+
* backend spends the sign-in ticket. Nothing here talks to an identity provider.
|
|
31270
31379
|
*/
|
|
31271
|
-
#appendSignInRequest(id, tool,
|
|
31380
|
+
#appendSignInRequest(id, tool, signInTicket, expiresAt) {
|
|
31272
31381
|
const messages = this.#host.messages();
|
|
31273
31382
|
if (!messages) return;
|
|
31274
31383
|
this.#proposalCards.get(id)?.remove();
|
|
31275
31384
|
const card = createSignInCard({
|
|
31276
31385
|
tool,
|
|
31277
|
-
|
|
31386
|
+
signInTicket,
|
|
31278
31387
|
expiresAt,
|
|
31279
31388
|
labels: {
|
|
31280
31389
|
heading: "Sign in to continue",
|
|
@@ -31282,7 +31391,7 @@ var AssistantElementEventController = class {
|
|
|
31282
31391
|
},
|
|
31283
31392
|
onSignIn: () => this.#host.element.dispatchEvent(
|
|
31284
31393
|
new CustomEvent("assistant-sign-in-requested", {
|
|
31285
|
-
detail: { id, tool,
|
|
31394
|
+
detail: { id, tool, signInTicket, expiresAt },
|
|
31286
31395
|
bubbles: true,
|
|
31287
31396
|
composed: true
|
|
31288
31397
|
})
|
|
@@ -31293,7 +31402,7 @@ var AssistantElementEventController = class {
|
|
|
31293
31402
|
this.#host.revealLatest();
|
|
31294
31403
|
this.#host.element.dispatchEvent(
|
|
31295
31404
|
new CustomEvent("assistant-sign-in-required", {
|
|
31296
|
-
detail: { id, tool,
|
|
31405
|
+
detail: { id, tool, signInTicket, expiresAt }
|
|
31297
31406
|
})
|
|
31298
31407
|
);
|
|
31299
31408
|
}
|
|
@@ -31368,6 +31477,46 @@ function queryRequired(root, selector) {
|
|
|
31368
31477
|
return element;
|
|
31369
31478
|
}
|
|
31370
31479
|
|
|
31480
|
+
// src/element-page-context-controller.ts
|
|
31481
|
+
var AssistantElementPageContextController = class {
|
|
31482
|
+
#snapshot;
|
|
31483
|
+
#load;
|
|
31484
|
+
#isEnabled;
|
|
31485
|
+
constructor(isEnabled) {
|
|
31486
|
+
this.#isEnabled = isEnabled;
|
|
31487
|
+
}
|
|
31488
|
+
current() {
|
|
31489
|
+
const url2 = browserPageUrl();
|
|
31490
|
+
if (!url2 || this.#snapshot?.url !== url2) {
|
|
31491
|
+
this.#snapshot = void 0;
|
|
31492
|
+
return void 0;
|
|
31493
|
+
}
|
|
31494
|
+
return this.#snapshot.context;
|
|
31495
|
+
}
|
|
31496
|
+
async refresh() {
|
|
31497
|
+
while (true) {
|
|
31498
|
+
const url2 = browserPageUrl();
|
|
31499
|
+
if (!url2) return;
|
|
31500
|
+
if (this.#snapshot?.url === url2) return;
|
|
31501
|
+
this.#snapshot = void 0;
|
|
31502
|
+
let load = this.#load;
|
|
31503
|
+
if (!load || load.url !== url2) {
|
|
31504
|
+
const promise2 = browserPageContext(url2).then((context) => {
|
|
31505
|
+
if (this.#isEnabled() && browserPageUrl() === url2) {
|
|
31506
|
+
this.#snapshot = { url: url2, context };
|
|
31507
|
+
}
|
|
31508
|
+
}).finally(() => {
|
|
31509
|
+
if (this.#load?.promise === promise2) this.#load = void 0;
|
|
31510
|
+
});
|
|
31511
|
+
load = { url: url2, promise: promise2 };
|
|
31512
|
+
this.#load = load;
|
|
31513
|
+
}
|
|
31514
|
+
await load.promise;
|
|
31515
|
+
if (browserPageUrl() === url2) return;
|
|
31516
|
+
}
|
|
31517
|
+
}
|
|
31518
|
+
};
|
|
31519
|
+
|
|
31371
31520
|
// src/element-scroll-controller.ts
|
|
31372
31521
|
var AssistantElementScrollController = class {
|
|
31373
31522
|
#region;
|
|
@@ -32108,6 +32257,9 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
32108
32257
|
#context;
|
|
32109
32258
|
#modelContext;
|
|
32110
32259
|
#pageContext;
|
|
32260
|
+
#automaticPageContext = new AssistantElementPageContextController(
|
|
32261
|
+
() => !this.#pageContext
|
|
32262
|
+
);
|
|
32111
32263
|
#pendingUserEcho;
|
|
32112
32264
|
#sessionState = "idle";
|
|
32113
32265
|
#startOpenApplied = false;
|
|
@@ -32186,10 +32338,10 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
32186
32338
|
if (this.hasAttribute("start-open")) {
|
|
32187
32339
|
this.setAttribute("open", "");
|
|
32188
32340
|
this.#startOpenApplied = true;
|
|
32189
|
-
this.#primeSession();
|
|
32190
32341
|
} else if (!this.embedId) {
|
|
32191
32342
|
this.#primeSession();
|
|
32192
32343
|
}
|
|
32344
|
+
this.#syncOpenState();
|
|
32193
32345
|
}
|
|
32194
32346
|
disconnectedCallback() {
|
|
32195
32347
|
this.#conversationGeneration += 1;
|
|
@@ -32211,7 +32363,6 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
32211
32363
|
}
|
|
32212
32364
|
open() {
|
|
32213
32365
|
this.setAttribute("open", "");
|
|
32214
|
-
this.#primeSession();
|
|
32215
32366
|
this.dispatchEvent(new CustomEvent("assistant-open"));
|
|
32216
32367
|
}
|
|
32217
32368
|
close() {
|
|
@@ -32305,6 +32456,8 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
32305
32456
|
try {
|
|
32306
32457
|
await this.#sessionBootstrap;
|
|
32307
32458
|
if (generation !== this.#conversationGeneration) return;
|
|
32459
|
+
if (this.embedId && !this.#pageContext) await this.#automaticPageContext.refresh();
|
|
32460
|
+
if (generation !== this.#conversationGeneration) return;
|
|
32308
32461
|
await this.#ensureClient().sendMessage(message);
|
|
32309
32462
|
} catch (error51) {
|
|
32310
32463
|
if (generation !== this.#conversationGeneration) return;
|
|
@@ -32362,7 +32515,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
32362
32515
|
const behavior = {
|
|
32363
32516
|
...this.#context ? { context: this.#context } : {},
|
|
32364
32517
|
clientContext: browserClientContext,
|
|
32365
|
-
...this.#pageContext ? { pageContext: this.#pageContext } : {},
|
|
32518
|
+
...this.#pageContext ? { pageContext: this.#pageContext } : this.embedId ? { pageContext: () => this.#automaticPageContext.current() } : {},
|
|
32366
32519
|
...this.#modelContext ? { modelContext: this.#modelContext } : {}
|
|
32367
32520
|
};
|
|
32368
32521
|
const client = this.embedId ? createAssistantClient({
|
|
@@ -32380,6 +32533,7 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
32380
32533
|
#primeSession() {
|
|
32381
32534
|
if (!this.sessionEndpoint && !this.embedId) return;
|
|
32382
32535
|
if (this.#sessionBootstrap || this.#client?.hasSession()) return;
|
|
32536
|
+
if (this.embedId && !this.#pageContext) void this.#automaticPageContext.refresh();
|
|
32383
32537
|
const client = this.#ensureClient();
|
|
32384
32538
|
const generation = this.#conversationGeneration;
|
|
32385
32539
|
this.#setSessionState("loading");
|
|
@@ -32563,7 +32717,9 @@ var NoodleAssistantElement = class extends HTMLElementBase {
|
|
|
32563
32717
|
syncAssistantSessionVisualState(this, this.shadowRoot, state, this.#appearance);
|
|
32564
32718
|
}
|
|
32565
32719
|
#syncOpenState() {
|
|
32566
|
-
|
|
32720
|
+
const open = this.hasAttribute("open");
|
|
32721
|
+
this.shadowRoot?.querySelector(".launcher")?.setAttribute("aria-expanded", String(open));
|
|
32722
|
+
if (open && this.isConnected) this.#primeSession();
|
|
32567
32723
|
}
|
|
32568
32724
|
#closeAndRestoreFocus() {
|
|
32569
32725
|
this.close();
|