prompt-api-polyfill 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/prompt-api-polyfill.js +187 -178
- package/package.json +1 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Schema as T } from "firebase/ai";
|
|
2
2
|
ReadableStream.prototype[Symbol.asyncIterator] || (ReadableStream.prototype[Symbol.asyncIterator] = async function* () {
|
|
3
|
-
const
|
|
3
|
+
const a = this.getReader();
|
|
4
4
|
try {
|
|
5
5
|
for (; ; ) {
|
|
6
|
-
const { done: t, value: e } = await
|
|
6
|
+
const { done: t, value: e } = await a.read();
|
|
7
7
|
if (t)
|
|
8
8
|
return;
|
|
9
9
|
yield e;
|
|
10
10
|
}
|
|
11
11
|
} finally {
|
|
12
|
-
|
|
12
|
+
a.releaseLock();
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
15
|
class M {
|
|
@@ -108,31 +108,40 @@ class M {
|
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
static async canvasSourceToInlineData(t) {
|
|
111
|
+
if (!t)
|
|
112
|
+
throw new DOMException("Invalid image source", "InvalidStateError");
|
|
111
113
|
typeof HTMLImageElement < "u" && t instanceof HTMLImageElement && !t.complete && await t.decode().catch(() => {
|
|
114
|
+
}), typeof HTMLVideoElement < "u" && t instanceof HTMLVideoElement && t.readyState < 2 && await new Promise((l) => {
|
|
115
|
+
t.addEventListener("loadeddata", l, { once: !0 }), t.readyState >= 2 && l(), setTimeout(l, 1e3);
|
|
112
116
|
});
|
|
113
|
-
const e = (
|
|
114
|
-
const
|
|
115
|
-
return typeof
|
|
117
|
+
const e = (l) => {
|
|
118
|
+
const p = t[l];
|
|
119
|
+
return typeof p == "object" && p !== null && "baseVal" in p ? p.baseVal.value : typeof p == "number" ? p : 0;
|
|
116
120
|
};
|
|
117
|
-
let n = t.displayWidth || t.naturalWidth || t.videoWidth || e("width"), r = t.displayHeight || t.naturalHeight || t.videoHeight || e("height");
|
|
121
|
+
let n = t.displayWidth || t.naturalWidth || t.videoWidth || t.width || e("width"), r = t.displayHeight || t.naturalHeight || t.videoHeight || t.height || e("height");
|
|
118
122
|
if ((!n || !r) && typeof t.getBBox == "function")
|
|
119
123
|
try {
|
|
120
|
-
const
|
|
121
|
-
n = n ||
|
|
124
|
+
const l = t.getBBox();
|
|
125
|
+
n = n || l.width, r = r || l.height;
|
|
122
126
|
} catch {
|
|
123
127
|
}
|
|
124
128
|
if ((!n || !r) && typeof t.getBoundingClientRect == "function")
|
|
125
129
|
try {
|
|
126
|
-
const
|
|
127
|
-
n = n ||
|
|
130
|
+
const l = t.getBoundingClientRect();
|
|
131
|
+
n = n || l.width, r = r || l.height;
|
|
128
132
|
} catch {
|
|
129
133
|
}
|
|
130
|
-
if (!n || !r)
|
|
131
|
-
|
|
134
|
+
if (!n || !r) {
|
|
135
|
+
const l = t.constructor && t.constructor.name ? t.constructor.name : typeof t;
|
|
136
|
+
throw new DOMException(
|
|
137
|
+
`Invalid image dimensions (${n}x${r}) for source type ${l}`,
|
|
138
|
+
"InvalidStateError"
|
|
139
|
+
);
|
|
140
|
+
}
|
|
132
141
|
const o = document.createElement("canvas");
|
|
133
142
|
o.width = n, o.height = r;
|
|
134
143
|
const i = o.getContext("2d");
|
|
135
|
-
return typeof ImageData < "u" && t instanceof ImageData ? i.putImageData(t, 0, 0) : i.drawImage(t, 0, 0), {
|
|
144
|
+
return typeof ImageData < "u" && t instanceof ImageData || t && typeof t.width == "number" && typeof t.height == "number" && t.data && t.data.buffer ? i.putImageData(t, 0, 0) : i.drawImage(t, 0, 0), {
|
|
136
145
|
inlineData: {
|
|
137
146
|
data: o.toDataURL("image/png").split(",")[1],
|
|
138
147
|
mimeType: "image/png"
|
|
@@ -163,8 +172,8 @@ class M {
|
|
|
163
172
|
return r;
|
|
164
173
|
}
|
|
165
174
|
static encodeWAV(t, e, n, r, o) {
|
|
166
|
-
const i = o / 8,
|
|
167
|
-
return this.writeString(l, 0, "RIFF"), l.setUint32(4, 36 + t.length * i, !0), this.writeString(l, 8, "WAVE"), this.writeString(l, 12, "fmt "), l.setUint32(16, 16, !0), l.setUint16(20, e, !0), l.setUint16(22, r, !0), l.setUint32(24, n, !0), l.setUint32(28, n *
|
|
175
|
+
const i = o / 8, s = r * i, c = new ArrayBuffer(44 + t.length * i), l = new DataView(c);
|
|
176
|
+
return this.writeString(l, 0, "RIFF"), l.setUint32(4, 36 + t.length * i, !0), this.writeString(l, 8, "WAVE"), this.writeString(l, 12, "fmt "), l.setUint32(16, 16, !0), l.setUint16(20, e, !0), l.setUint16(22, r, !0), l.setUint32(24, n, !0), l.setUint32(28, n * s, !0), l.setUint16(32, s, !0), l.setUint16(34, o, !0), this.writeString(l, 36, "data"), l.setUint32(40, t.length * i, !0), this.floatTo16BitPCM(l, 44, t), c;
|
|
168
177
|
}
|
|
169
178
|
static floatTo16BitPCM(t, e, n) {
|
|
170
179
|
for (let r = 0; r < n.length; r++, e += 2) {
|
|
@@ -177,19 +186,19 @@ class M {
|
|
|
177
186
|
t.setUint8(e + r, n.charCodeAt(r));
|
|
178
187
|
}
|
|
179
188
|
}
|
|
180
|
-
function O(
|
|
181
|
-
if (!
|
|
189
|
+
function O(a) {
|
|
190
|
+
if (!a)
|
|
182
191
|
return;
|
|
183
192
|
const t = {
|
|
184
|
-
description:
|
|
185
|
-
nullable:
|
|
186
|
-
format:
|
|
193
|
+
description: a.description,
|
|
194
|
+
nullable: a.nullable || !1,
|
|
195
|
+
format: a.format
|
|
187
196
|
};
|
|
188
|
-
switch (Array.isArray(
|
|
197
|
+
switch (Array.isArray(a.type) && a.type.includes("null") && (t.nullable = !0, a.type = a.type.find((e) => e !== "null")), a.type) {
|
|
189
198
|
case "string":
|
|
190
|
-
return
|
|
199
|
+
return a.enum && Array.isArray(a.enum) ? T.enumString({
|
|
191
200
|
...t,
|
|
192
|
-
enum:
|
|
201
|
+
enum: a.enum
|
|
193
202
|
}) : T.string(t);
|
|
194
203
|
case "number":
|
|
195
204
|
return T.number(t);
|
|
@@ -201,16 +210,16 @@ function O(s) {
|
|
|
201
210
|
return T.array({
|
|
202
211
|
...t,
|
|
203
212
|
// Recursively convert the 'items' schema
|
|
204
|
-
items: O(
|
|
213
|
+
items: O(a.items)
|
|
205
214
|
});
|
|
206
215
|
case "object":
|
|
207
|
-
const e = {}, n =
|
|
216
|
+
const e = {}, n = a.properties ? Object.keys(a.properties) : [];
|
|
208
217
|
n.forEach((i) => {
|
|
209
218
|
e[i] = O(
|
|
210
|
-
|
|
219
|
+
a.properties[i]
|
|
211
220
|
);
|
|
212
221
|
});
|
|
213
|
-
const r =
|
|
222
|
+
const r = a.required || [], o = n.filter(
|
|
214
223
|
(i) => !r.includes(i)
|
|
215
224
|
);
|
|
216
225
|
return T.object({
|
|
@@ -220,11 +229,11 @@ function O(s) {
|
|
|
220
229
|
});
|
|
221
230
|
default:
|
|
222
231
|
return console.warn(
|
|
223
|
-
`Unsupported type: ${
|
|
232
|
+
`Unsupported type: ${a.type}, defaulting to string.`
|
|
224
233
|
), T.string(t);
|
|
225
234
|
}
|
|
226
235
|
}
|
|
227
|
-
const
|
|
236
|
+
const I = [
|
|
228
237
|
{
|
|
229
238
|
config: "FIREBASE_CONFIG",
|
|
230
239
|
path: "./backends/firebase.js"
|
|
@@ -242,26 +251,26 @@ const A = [
|
|
|
242
251
|
path: "./backends/transformers.js"
|
|
243
252
|
}
|
|
244
253
|
];
|
|
245
|
-
async function
|
|
246
|
-
if (
|
|
254
|
+
async function A(a) {
|
|
255
|
+
if (a === "./backends/firebase.js")
|
|
247
256
|
return (await import("./backends/firebase.js")).default;
|
|
248
|
-
if (
|
|
257
|
+
if (a === "./backends/gemini.js")
|
|
249
258
|
return (await import("./backends/gemini.js")).default;
|
|
250
|
-
if (
|
|
259
|
+
if (a === "./backends/openai.js")
|
|
251
260
|
return (await import("./backends/openai.js")).default;
|
|
252
|
-
if (
|
|
261
|
+
if (a === "./backends/transformers.js")
|
|
253
262
|
return (await import("./backends/transformers.js")).default;
|
|
254
|
-
throw new Error(`Unknown backend path "${
|
|
263
|
+
throw new Error(`Unknown backend path "${a}"`);
|
|
255
264
|
}
|
|
256
|
-
async function
|
|
265
|
+
async function S(a, t = globalThis) {
|
|
257
266
|
const e = [];
|
|
258
|
-
for (const n of
|
|
267
|
+
for (const n of a) {
|
|
259
268
|
const r = n.role === "assistant" ? "model" : "user", o = r === "model";
|
|
260
269
|
let i = [];
|
|
261
270
|
if (Array.isArray(n.content))
|
|
262
|
-
for (const
|
|
263
|
-
if (
|
|
264
|
-
const c =
|
|
271
|
+
for (const s of n.content)
|
|
272
|
+
if (s.type === "text") {
|
|
273
|
+
const c = s.value || s.text || "";
|
|
265
274
|
if (typeof c != "string")
|
|
266
275
|
throw new (t.DOMException || globalThis.DOMException)(
|
|
267
276
|
'The content type "text" must have a string value.',
|
|
@@ -274,7 +283,7 @@ async function C(s, t = globalThis) {
|
|
|
274
283
|
"Assistant messages only support text content.",
|
|
275
284
|
"NotSupportedError"
|
|
276
285
|
);
|
|
277
|
-
const c = await M.convert(
|
|
286
|
+
const c = await M.convert(s.type, s.value);
|
|
278
287
|
i.push(c);
|
|
279
288
|
}
|
|
280
289
|
else
|
|
@@ -287,14 +296,14 @@ class d extends EventTarget {
|
|
|
287
296
|
#o;
|
|
288
297
|
#f;
|
|
289
298
|
#e;
|
|
290
|
-
#
|
|
299
|
+
#a;
|
|
291
300
|
#r;
|
|
292
301
|
#n;
|
|
293
302
|
#i;
|
|
294
|
-
#
|
|
303
|
+
#l;
|
|
295
304
|
#t;
|
|
296
|
-
constructor(t, e, n, r = {}, o, i = 0,
|
|
297
|
-
super(), this.#o = t, this.#f = e, this.#e = n || [], this.#
|
|
305
|
+
constructor(t, e, n, r = {}, o, i = 0, s = globalThis) {
|
|
306
|
+
super(), this.#o = t, this.#f = e, this.#e = n || [], this.#a = r, this.#r = o, this.#n = !1, this.#i = i, this.#l = {}, this.#t = s;
|
|
298
307
|
}
|
|
299
308
|
get contextUsage() {
|
|
300
309
|
return this.#i;
|
|
@@ -303,10 +312,10 @@ class d extends EventTarget {
|
|
|
303
312
|
return 1e6;
|
|
304
313
|
}
|
|
305
314
|
get oncontextoverflow() {
|
|
306
|
-
return this.#
|
|
315
|
+
return this.#l;
|
|
307
316
|
}
|
|
308
317
|
set oncontextoverflow(t) {
|
|
309
|
-
this.#
|
|
318
|
+
this.#l && this.removeEventListener("contextoverflow", this.#l), this.#l = t, typeof t == "function" && this.addEventListener("contextoverflow", t);
|
|
310
319
|
}
|
|
311
320
|
static #h(t) {
|
|
312
321
|
try {
|
|
@@ -322,7 +331,7 @@ class d extends EventTarget {
|
|
|
322
331
|
);
|
|
323
332
|
}
|
|
324
333
|
}
|
|
325
|
-
#
|
|
334
|
+
#s() {
|
|
326
335
|
d.#h(this.#t);
|
|
327
336
|
}
|
|
328
337
|
static async availability(t = {}) {
|
|
@@ -347,14 +356,14 @@ class d extends EventTarget {
|
|
|
347
356
|
}
|
|
348
357
|
return (await d.#p(e)).availability(t);
|
|
349
358
|
}
|
|
350
|
-
static #
|
|
359
|
+
static #x = I;
|
|
351
360
|
static #d(t = globalThis) {
|
|
352
|
-
for (const n of d.#
|
|
361
|
+
for (const n of d.#x) {
|
|
353
362
|
const r = t[n.config] || globalThis[n.config];
|
|
354
363
|
if (r && r.apiKey)
|
|
355
364
|
return { ...n, configValue: r };
|
|
356
365
|
}
|
|
357
|
-
const e = d.#
|
|
366
|
+
const e = d.#x.map((n) => `window.${n.config}`).join(", ");
|
|
358
367
|
throw new (t.DOMException || globalThis.DOMException)(
|
|
359
368
|
`Prompt API Polyfill: No backend configuration found. Please set one of: ${e}.`,
|
|
360
369
|
"NotSupportedError"
|
|
@@ -362,7 +371,7 @@ class d extends EventTarget {
|
|
|
362
371
|
}
|
|
363
372
|
static async #p(t = globalThis) {
|
|
364
373
|
const e = d.#d(t);
|
|
365
|
-
return
|
|
374
|
+
return A(e.path);
|
|
366
375
|
}
|
|
367
376
|
static async #w(t = {}, e = globalThis) {
|
|
368
377
|
if (t.expectedInputs)
|
|
@@ -394,8 +403,8 @@ class d extends EventTarget {
|
|
|
394
403
|
r = !0;
|
|
395
404
|
}
|
|
396
405
|
if (Array.isArray(i.content))
|
|
397
|
-
for (const
|
|
398
|
-
const c =
|
|
406
|
+
for (const s of i.content) {
|
|
407
|
+
const c = s.type || "text";
|
|
399
408
|
if (!n.includes(c))
|
|
400
409
|
throw new (e.DOMException || globalThis.DOMException)(
|
|
401
410
|
`The content type "${c}" is not in the expectedInputs.`,
|
|
@@ -452,115 +461,115 @@ class d extends EventTarget {
|
|
|
452
461
|
"Aborted",
|
|
453
462
|
"AbortError"
|
|
454
463
|
);
|
|
455
|
-
const r = d.#d(e), o = await d.#p(e), i = new o(r.configValue),
|
|
456
|
-
d.#
|
|
457
|
-
|
|
464
|
+
const r = d.#d(e), o = await d.#p(e), i = new o(r.configValue), s = { ...t };
|
|
465
|
+
d.#g(
|
|
466
|
+
s.responseConstraint,
|
|
458
467
|
e
|
|
459
468
|
);
|
|
460
469
|
const c = {
|
|
461
470
|
model: i.modelName,
|
|
462
471
|
generationConfig: {}
|
|
463
472
|
};
|
|
464
|
-
let l = [],
|
|
465
|
-
if (
|
|
466
|
-
const
|
|
473
|
+
let l = [], p = 0;
|
|
474
|
+
if (s.initialPrompts && Array.isArray(s.initialPrompts)) {
|
|
475
|
+
const y = s.initialPrompts.filter(
|
|
467
476
|
(f) => f.role === "system"
|
|
468
|
-
),
|
|
477
|
+
), u = s.initialPrompts.filter(
|
|
469
478
|
(f) => f.role !== "system"
|
|
470
479
|
);
|
|
471
|
-
|
|
480
|
+
y.length > 0 && (c.systemInstruction = y.map((f) => typeof f.content == "string" ? f.content : Array.isArray(f.content) ? f.content.filter((h) => h.type === "text").map((h) => h.value || h.text || "").join(`
|
|
472
481
|
`) : "").join(`
|
|
473
|
-
`)), l = await
|
|
474
|
-
for (const f of
|
|
482
|
+
`)), l = await S(u, e);
|
|
483
|
+
for (const f of s.initialPrompts) {
|
|
475
484
|
if (typeof f.content != "string")
|
|
476
485
|
continue;
|
|
477
486
|
const h = d.#E([
|
|
478
487
|
{ text: f.content }
|
|
479
488
|
]);
|
|
480
489
|
if (h === "QuotaExceededError" || h === "contextoverflow") {
|
|
481
|
-
const E = e.QuotaExceededError || e.DOMException || globalThis.QuotaExceededError || globalThis.DOMException,
|
|
490
|
+
const E = e.QuotaExceededError || e.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, g = new E(
|
|
482
491
|
"The initial prompts are too large, they exceed the quota.",
|
|
483
492
|
"QuotaExceededError"
|
|
484
493
|
);
|
|
485
|
-
Object.defineProperty(
|
|
494
|
+
Object.defineProperty(g, "code", {
|
|
486
495
|
value: 22,
|
|
487
496
|
configurable: !0
|
|
488
497
|
});
|
|
489
498
|
const x = h === "QuotaExceededError" ? 1e7 : 5e5;
|
|
490
|
-
throw
|
|
499
|
+
throw g.requested = x, g.quota = 1e6, g;
|
|
491
500
|
}
|
|
492
501
|
}
|
|
493
502
|
}
|
|
494
|
-
let
|
|
495
|
-
if (typeof
|
|
496
|
-
|
|
503
|
+
let w = null;
|
|
504
|
+
if (typeof s.monitor == "function") {
|
|
505
|
+
w = new EventTarget();
|
|
497
506
|
try {
|
|
498
|
-
|
|
499
|
-
} catch (
|
|
500
|
-
throw
|
|
507
|
+
s.monitor(w);
|
|
508
|
+
} catch (y) {
|
|
509
|
+
throw y;
|
|
501
510
|
}
|
|
502
511
|
}
|
|
503
|
-
|
|
504
|
-
const
|
|
505
|
-
if (!
|
|
512
|
+
w && (w.__lastProgressLoaded = -1);
|
|
513
|
+
const m = async (y) => {
|
|
514
|
+
if (!w || t.signal?.aborted)
|
|
506
515
|
return !t.signal?.aborted;
|
|
507
|
-
const
|
|
508
|
-
if (f <=
|
|
516
|
+
const u = 1 / 65536, f = Math.floor(y / u) * u;
|
|
517
|
+
if (f <= w.__lastProgressLoaded)
|
|
509
518
|
return !0;
|
|
510
519
|
try {
|
|
511
|
-
|
|
520
|
+
w.dispatchEvent(
|
|
512
521
|
new ProgressEvent("downloadprogress", {
|
|
513
522
|
loaded: f,
|
|
514
523
|
total: 1,
|
|
515
524
|
lengthComputable: !0
|
|
516
525
|
})
|
|
517
|
-
),
|
|
526
|
+
), w.__lastProgressLoaded = f;
|
|
518
527
|
} catch (h) {
|
|
519
528
|
console.error("Error dispatching downloadprogress events:", h);
|
|
520
529
|
}
|
|
521
530
|
return await new Promise((h) => setTimeout(h, 0)), !t.signal?.aborted;
|
|
522
531
|
};
|
|
523
|
-
if (!await
|
|
532
|
+
if (!await m(0))
|
|
524
533
|
throw t.signal.reason || new (e.DOMException || globalThis.DOMException)(
|
|
525
534
|
"Aborted",
|
|
526
535
|
"AbortError"
|
|
527
536
|
);
|
|
528
|
-
const
|
|
529
|
-
|
|
537
|
+
const b = await i.createSession(
|
|
538
|
+
s,
|
|
530
539
|
c,
|
|
531
|
-
|
|
540
|
+
w
|
|
532
541
|
);
|
|
533
|
-
if (!await
|
|
542
|
+
if (!await m(1))
|
|
534
543
|
throw t.signal.reason || new (e.DOMException || globalThis.DOMException)(
|
|
535
544
|
"Aborted",
|
|
536
545
|
"AbortError"
|
|
537
546
|
);
|
|
538
|
-
if (
|
|
539
|
-
const
|
|
540
|
-
if (c.systemInstruction &&
|
|
547
|
+
if (s.initialPrompts?.length > 0) {
|
|
548
|
+
const y = [...l];
|
|
549
|
+
if (c.systemInstruction && y.unshift({
|
|
541
550
|
role: "system",
|
|
542
551
|
parts: [{ text: c.systemInstruction }]
|
|
543
|
-
}),
|
|
544
|
-
const
|
|
552
|
+
}), p = await i.countTokens(y) || 0, p > 1e6) {
|
|
553
|
+
const u = e.QuotaExceededError || e.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, f = new u(
|
|
545
554
|
"The initial prompts are too large, they exceed the quota.",
|
|
546
555
|
"QuotaExceededError"
|
|
547
556
|
);
|
|
548
|
-
throw Object.defineProperty(f, "code", { value: 22, configurable: !0 }), f.requested =
|
|
557
|
+
throw Object.defineProperty(f, "code", { value: 22, configurable: !0 }), f.requested = p, f.quota = 1e6, f;
|
|
549
558
|
}
|
|
550
559
|
}
|
|
551
560
|
return new this(
|
|
552
561
|
i,
|
|
553
|
-
|
|
562
|
+
b,
|
|
554
563
|
l,
|
|
555
|
-
|
|
564
|
+
s,
|
|
556
565
|
c,
|
|
557
|
-
|
|
566
|
+
p,
|
|
558
567
|
e
|
|
559
568
|
);
|
|
560
569
|
}
|
|
561
570
|
// Instance Methods
|
|
562
571
|
async clone(t = {}) {
|
|
563
|
-
if (this.#
|
|
572
|
+
if (this.#s(), this.#n)
|
|
564
573
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
565
574
|
"Session is destroyed",
|
|
566
575
|
"InvalidStateError"
|
|
@@ -570,7 +579,7 @@ class d extends EventTarget {
|
|
|
570
579
|
"Aborted",
|
|
571
580
|
"AbortError"
|
|
572
581
|
);
|
|
573
|
-
const e = JSON.parse(JSON.stringify(this.#e)), n = { ...this.#
|
|
582
|
+
const e = JSON.parse(JSON.stringify(this.#e)), n = { ...this.#a, ...t }, r = await d.#p(this.#t), o = d.#d(this.#t), i = new r(o.configValue), s = await i.createSession(
|
|
574
583
|
n,
|
|
575
584
|
this.#r
|
|
576
585
|
);
|
|
@@ -581,7 +590,7 @@ class d extends EventTarget {
|
|
|
581
590
|
);
|
|
582
591
|
return new this.constructor(
|
|
583
592
|
i,
|
|
584
|
-
|
|
593
|
+
s,
|
|
585
594
|
e,
|
|
586
595
|
n,
|
|
587
596
|
this.#r,
|
|
@@ -590,10 +599,10 @@ class d extends EventTarget {
|
|
|
590
599
|
);
|
|
591
600
|
}
|
|
592
601
|
destroy() {
|
|
593
|
-
this.#
|
|
602
|
+
this.#s(), this.#n = !0, this.#e = null;
|
|
594
603
|
}
|
|
595
604
|
async prompt(t, e = {}) {
|
|
596
|
-
if (this.#
|
|
605
|
+
if (this.#s(), this.#n)
|
|
597
606
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
598
607
|
"Session is destroyed",
|
|
599
608
|
"InvalidStateError"
|
|
@@ -606,7 +615,7 @@ class d extends EventTarget {
|
|
|
606
615
|
if (typeof t == "object" && t !== null && !Array.isArray(t) && Object.keys(t).length === 0)
|
|
607
616
|
return "[object Object]";
|
|
608
617
|
if (e.responseConstraint) {
|
|
609
|
-
d.#
|
|
618
|
+
d.#g(
|
|
610
619
|
e.responseConstraint,
|
|
611
620
|
this.#t
|
|
612
621
|
);
|
|
@@ -614,11 +623,11 @@ class d extends EventTarget {
|
|
|
614
623
|
e.responseConstraint
|
|
615
624
|
);
|
|
616
625
|
this.#r.generationConfig.responseMimeType = "application/json", this.#r.generationConfig.responseSchema = c, this.#f = this.#o.createSession(
|
|
617
|
-
this.#
|
|
626
|
+
this.#a,
|
|
618
627
|
this.#r
|
|
619
628
|
);
|
|
620
629
|
}
|
|
621
|
-
const n = this.#
|
|
630
|
+
const n = this.#m(t), r = await this.#c(t);
|
|
622
631
|
if (this.#n)
|
|
623
632
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
624
633
|
"Session is destroyed",
|
|
@@ -646,7 +655,7 @@ class d extends EventTarget {
|
|
|
646
655
|
},
|
|
647
656
|
{ once: !0 }
|
|
648
657
|
);
|
|
649
|
-
}),
|
|
658
|
+
}), s = (async () => {
|
|
650
659
|
const c = this.#u(r);
|
|
651
660
|
if (c === "QuotaExceededError") {
|
|
652
661
|
const f = this.#t && this.#t.QuotaExceededError || this.#t && this.#t.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, h = new f(
|
|
@@ -663,40 +672,40 @@ class d extends EventTarget {
|
|
|
663
672
|
role: "system",
|
|
664
673
|
parts: [{ text: this.#r.systemInstruction }]
|
|
665
674
|
});
|
|
666
|
-
const
|
|
675
|
+
const p = await this.#o.countTokens(
|
|
667
676
|
l
|
|
668
677
|
);
|
|
669
|
-
if (
|
|
678
|
+
if (p > this.contextWindow) {
|
|
670
679
|
const f = this.#t && this.#t.QuotaExceededError || this.#t && this.#t.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, h = new f(
|
|
671
|
-
`The prompt is too large (${
|
|
680
|
+
`The prompt is too large (${p} tokens), it exceeds the quota of ${this.contextWindow} tokens.`,
|
|
672
681
|
"QuotaExceededError"
|
|
673
682
|
);
|
|
674
|
-
throw Object.defineProperty(h, "code", { value: 22, configurable: !0 }), h.requested =
|
|
683
|
+
throw Object.defineProperty(h, "code", { value: 22, configurable: !0 }), h.requested = p, h.quota = this.contextWindow, h;
|
|
675
684
|
}
|
|
676
|
-
|
|
677
|
-
const
|
|
678
|
-
let
|
|
685
|
+
p > this.contextWindow && this.dispatchEvent(new Event("contextoverflow"));
|
|
686
|
+
const w = [...this.#e, o];
|
|
687
|
+
let m;
|
|
679
688
|
try {
|
|
680
|
-
|
|
689
|
+
m = await this.#o.generateContent(w);
|
|
681
690
|
} catch (f) {
|
|
682
|
-
throw this.#
|
|
691
|
+
throw this.#b(f, r), f;
|
|
683
692
|
}
|
|
684
|
-
const { text:
|
|
685
|
-
let
|
|
693
|
+
const { text: b, usage: y } = m;
|
|
694
|
+
let u = b;
|
|
686
695
|
if (n) {
|
|
687
|
-
const f =
|
|
688
|
-
f && (
|
|
696
|
+
const f = u.match(/^\s*{\s*"Rating"\s*:\s*/);
|
|
697
|
+
f && (u = u.slice(f[0].length));
|
|
689
698
|
}
|
|
690
|
-
return
|
|
699
|
+
return y && (this.#i = y), !this.#n && this.#e && (this.#e.push(o), this.#e.push({ role: "model", parts: [{ text: u }] })), u;
|
|
691
700
|
})();
|
|
692
701
|
try {
|
|
693
|
-
return await Promise.race([
|
|
702
|
+
return await Promise.race([s, i]);
|
|
694
703
|
} catch (c) {
|
|
695
704
|
throw c.name === "AbortError" || console.error("Prompt API Polyfill Error:", c), c;
|
|
696
705
|
}
|
|
697
706
|
}
|
|
698
707
|
promptStreaming(t, e = {}) {
|
|
699
|
-
if (this.#
|
|
708
|
+
if (this.#s(), this.#n)
|
|
700
709
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
701
710
|
"Session is destroyed",
|
|
702
711
|
"InvalidStateError"
|
|
@@ -716,7 +725,7 @@ class d extends EventTarget {
|
|
|
716
725
|
return new ReadableStream({
|
|
717
726
|
async start(o) {
|
|
718
727
|
let i = !1;
|
|
719
|
-
const
|
|
728
|
+
const s = () => {
|
|
720
729
|
i = !0;
|
|
721
730
|
try {
|
|
722
731
|
const c = r?.reason || new (n.#t.DOMException || globalThis.DOMException)(
|
|
@@ -728,33 +737,33 @@ class d extends EventTarget {
|
|
|
728
737
|
}
|
|
729
738
|
};
|
|
730
739
|
if (r?.aborted) {
|
|
731
|
-
|
|
740
|
+
s();
|
|
732
741
|
return;
|
|
733
742
|
}
|
|
734
|
-
r && r.addEventListener("abort",
|
|
743
|
+
r && r.addEventListener("abort", s);
|
|
735
744
|
try {
|
|
736
745
|
if (e.responseConstraint) {
|
|
737
|
-
d.#
|
|
746
|
+
d.#g(
|
|
738
747
|
e.responseConstraint,
|
|
739
748
|
n.#t
|
|
740
749
|
);
|
|
741
|
-
const
|
|
750
|
+
const g = O(
|
|
742
751
|
e.responseConstraint
|
|
743
752
|
);
|
|
744
|
-
n.#r.generationConfig.responseMimeType = "application/json", n.#r.generationConfig.responseSchema =
|
|
745
|
-
n.#
|
|
753
|
+
n.#r.generationConfig.responseMimeType = "application/json", n.#r.generationConfig.responseSchema = g, n.#f = n.#o.createSession(
|
|
754
|
+
n.#a,
|
|
746
755
|
n.#r
|
|
747
756
|
);
|
|
748
757
|
}
|
|
749
|
-
const c = n.#
|
|
758
|
+
const c = n.#m(t), l = await n.#c(t);
|
|
750
759
|
if (n.#n)
|
|
751
760
|
throw new (n.#t.DOMException || globalThis.DOMException)(
|
|
752
761
|
"Session is destroyed",
|
|
753
762
|
"InvalidStateError"
|
|
754
763
|
);
|
|
755
|
-
const
|
|
756
|
-
if (
|
|
757
|
-
const
|
|
764
|
+
const p = { role: "user", parts: l }, w = n.#u(l);
|
|
765
|
+
if (w === "QuotaExceededError") {
|
|
766
|
+
const g = n.#t && n.#t.QuotaExceededError || n.#t && n.#t.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, x = new g(
|
|
758
767
|
"The prompt is too large, it exceeds the quota.",
|
|
759
768
|
"QuotaExceededError"
|
|
760
769
|
);
|
|
@@ -764,43 +773,43 @@ class d extends EventTarget {
|
|
|
764
773
|
});
|
|
765
774
|
const v = 1e7;
|
|
766
775
|
throw x.requested = v, x.quota = n.contextWindow, x;
|
|
767
|
-
} else if (
|
|
776
|
+
} else if (w === "contextoverflow") {
|
|
768
777
|
n.dispatchEvent(new Event("contextoverflow")), o.enqueue("Mock response for quota overflow test."), o.close();
|
|
769
778
|
return;
|
|
770
779
|
}
|
|
771
|
-
const
|
|
772
|
-
n.#r.systemInstruction &&
|
|
780
|
+
const m = [...n.#e, p];
|
|
781
|
+
n.#r.systemInstruction && m.unshift({
|
|
773
782
|
role: "system",
|
|
774
783
|
parts: [{ text: n.#r.systemInstruction }]
|
|
775
784
|
});
|
|
776
|
-
const
|
|
777
|
-
|
|
785
|
+
const b = await n.#o.countTokens(
|
|
786
|
+
m
|
|
778
787
|
);
|
|
779
|
-
if (
|
|
780
|
-
const
|
|
781
|
-
`The prompt is too large (${
|
|
788
|
+
if (b > n.contextWindow) {
|
|
789
|
+
const g = n.#t && n.#t.QuotaExceededError || n.#t && n.#t.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, x = new g(
|
|
790
|
+
`The prompt is too large (${b} tokens), it exceeds the quota of ${n.contextWindow} tokens.`,
|
|
782
791
|
"QuotaExceededError"
|
|
783
792
|
);
|
|
784
793
|
throw Object.defineProperty(x, "code", {
|
|
785
794
|
value: 22,
|
|
786
795
|
configurable: !0
|
|
787
|
-
}), x.requested =
|
|
796
|
+
}), x.requested = b, x.quota = n.contextWindow, x;
|
|
788
797
|
}
|
|
789
|
-
|
|
790
|
-
const
|
|
791
|
-
let
|
|
798
|
+
b > n.contextWindow && n.dispatchEvent(new Event("contextoverflow"));
|
|
799
|
+
const y = [...n.#e, p];
|
|
800
|
+
let u;
|
|
792
801
|
try {
|
|
793
|
-
|
|
794
|
-
} catch (
|
|
795
|
-
throw n.#
|
|
802
|
+
u = await n.#o.generateContentStream(y);
|
|
803
|
+
} catch (g) {
|
|
804
|
+
throw n.#b(g, l), g;
|
|
796
805
|
}
|
|
797
806
|
let f = "", h = !1, E = "";
|
|
798
|
-
for await (const
|
|
807
|
+
for await (const g of u) {
|
|
799
808
|
if (i) {
|
|
800
|
-
typeof
|
|
809
|
+
typeof u.return == "function" && await u.return();
|
|
801
810
|
return;
|
|
802
811
|
}
|
|
803
|
-
let x =
|
|
812
|
+
let x = g.text();
|
|
804
813
|
if (c && !h) {
|
|
805
814
|
E += x;
|
|
806
815
|
const v = E.match(/^\s*{\s*"Rating"\s*:\s*/);
|
|
@@ -811,22 +820,22 @@ class d extends EventTarget {
|
|
|
811
820
|
else
|
|
812
821
|
continue;
|
|
813
822
|
}
|
|
814
|
-
f += x,
|
|
823
|
+
f += x, g.usageMetadata?.totalTokenCount && (n.#i = g.usageMetadata.totalTokenCount), o.enqueue(x);
|
|
815
824
|
}
|
|
816
|
-
!i && !n.#n && n.#e && (n.#e.push(
|
|
825
|
+
!i && !n.#n && n.#e && (n.#e.push(p), n.#e.push({
|
|
817
826
|
role: "model",
|
|
818
827
|
parts: [{ text: f }]
|
|
819
828
|
})), o.close();
|
|
820
829
|
} catch (c) {
|
|
821
830
|
i || o.error(c);
|
|
822
831
|
} finally {
|
|
823
|
-
r && r.removeEventListener("abort",
|
|
832
|
+
r && r.removeEventListener("abort", s);
|
|
824
833
|
}
|
|
825
834
|
}
|
|
826
835
|
});
|
|
827
836
|
}
|
|
828
837
|
async append(t, e = {}) {
|
|
829
|
-
if (this.#
|
|
838
|
+
if (this.#s(), this.#n)
|
|
830
839
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
831
840
|
"Session is destroyed",
|
|
832
841
|
"InvalidStateError"
|
|
@@ -836,7 +845,7 @@ class d extends EventTarget {
|
|
|
836
845
|
"Aborted",
|
|
837
846
|
"AbortError"
|
|
838
847
|
);
|
|
839
|
-
const n = await this.#
|
|
848
|
+
const n = await this.#c(t);
|
|
840
849
|
if (this.#n)
|
|
841
850
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
842
851
|
"Session is destroyed",
|
|
@@ -857,13 +866,13 @@ class d extends EventTarget {
|
|
|
857
866
|
this.#i > this.contextWindow && this.dispatchEvent(new Event("contextoverflow"));
|
|
858
867
|
}
|
|
859
868
|
async measureContextUsage(t) {
|
|
860
|
-
if (this.#
|
|
869
|
+
if (this.#s(), this.#n)
|
|
861
870
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
862
871
|
"Session is destroyed",
|
|
863
872
|
"InvalidStateError"
|
|
864
873
|
);
|
|
865
874
|
try {
|
|
866
|
-
const e = await this.#
|
|
875
|
+
const e = await this.#c(t);
|
|
867
876
|
if (this.#n)
|
|
868
877
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
869
878
|
"Session is destroyed",
|
|
@@ -889,7 +898,7 @@ class d extends EventTarget {
|
|
|
889
898
|
const e = t[0].text;
|
|
890
899
|
return typeof e != "string" || !e.startsWith("Please write a sentence in English.") ? null : e.length > 1e7 ? "QuotaExceededError" : e.length > 5e4 ? "contextoverflow" : null;
|
|
891
900
|
}
|
|
892
|
-
static #
|
|
901
|
+
static #g(t, e) {
|
|
893
902
|
if (t)
|
|
894
903
|
try {
|
|
895
904
|
JSON.stringify(t);
|
|
@@ -900,7 +909,7 @@ class d extends EventTarget {
|
|
|
900
909
|
);
|
|
901
910
|
}
|
|
902
911
|
}
|
|
903
|
-
#
|
|
912
|
+
#m(t) {
|
|
904
913
|
if (Array.isArray(t)) {
|
|
905
914
|
for (const e of t)
|
|
906
915
|
if (e.prefix && (e.role === "assistant" || e.role === "model") && typeof e.content == "string" && e.content.includes('"Rating":'))
|
|
@@ -909,8 +918,8 @@ class d extends EventTarget {
|
|
|
909
918
|
return null;
|
|
910
919
|
}
|
|
911
920
|
// Private Helper to process diverse input types
|
|
912
|
-
async #
|
|
913
|
-
const e = this.#
|
|
921
|
+
async #c(t) {
|
|
922
|
+
const e = this.#a.expectedInputs ? ["text", ...this.#a.expectedInputs.map((r) => r.type)] : ["text"];
|
|
914
923
|
if (typeof t == "string") {
|
|
915
924
|
if (!e.includes("text"))
|
|
916
925
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
@@ -936,27 +945,27 @@ class d extends EventTarget {
|
|
|
936
945
|
"The `prefix` flag isn't supported and was ignored."
|
|
937
946
|
);
|
|
938
947
|
} else if (Array.isArray(o.content))
|
|
939
|
-
for (const
|
|
940
|
-
const c =
|
|
948
|
+
for (const s of o.content) {
|
|
949
|
+
const c = s.type || "text";
|
|
941
950
|
if (!e.includes(c))
|
|
942
951
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
943
952
|
`The content type "${c}" is not in the expectedInputs.`,
|
|
944
953
|
"NotSupportedError"
|
|
945
954
|
);
|
|
946
955
|
if (c === "text") {
|
|
947
|
-
if (typeof
|
|
956
|
+
if (typeof s.value != "string")
|
|
948
957
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
949
958
|
'The content type "text" must have a string value.',
|
|
950
959
|
"SyntaxError"
|
|
951
960
|
);
|
|
952
|
-
r.push({ text:
|
|
961
|
+
r.push({ text: s.value });
|
|
953
962
|
} else {
|
|
954
963
|
if (i)
|
|
955
964
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
956
965
|
"Assistant messages only support text content.",
|
|
957
966
|
"NotSupportedError"
|
|
958
967
|
);
|
|
959
|
-
const l =
|
|
968
|
+
const l = s.value && s.value.inlineData ? s.value : await M.convert(s.type, s.value);
|
|
960
969
|
r.push(l);
|
|
961
970
|
}
|
|
962
971
|
}
|
|
@@ -1011,13 +1020,13 @@ class d extends EventTarget {
|
|
|
1011
1020
|
return [{ text: JSON.stringify(t) }];
|
|
1012
1021
|
}
|
|
1013
1022
|
// Map backend errors to WPT expectations
|
|
1014
|
-
#
|
|
1023
|
+
#b(t, e) {
|
|
1015
1024
|
const n = String(t.message || t);
|
|
1016
1025
|
if (n.includes("400") || n.toLowerCase().includes("unable to process") || n.toLowerCase().includes("invalid")) {
|
|
1017
1026
|
const r = e.some(
|
|
1018
|
-
(
|
|
1027
|
+
(s) => s.inlineData?.mimeType.startsWith("audio/")
|
|
1019
1028
|
), o = e.some(
|
|
1020
|
-
(
|
|
1029
|
+
(s) => s.inlineData?.mimeType.startsWith("image/")
|
|
1021
1030
|
), i = this.#t.DOMException || globalThis.DOMException;
|
|
1022
1031
|
if (r)
|
|
1023
1032
|
throw new i("Invalid audio data", "DataError");
|
|
@@ -1027,33 +1036,33 @@ class d extends EventTarget {
|
|
|
1027
1036
|
}
|
|
1028
1037
|
}
|
|
1029
1038
|
globalThis.DOMException && (globalThis.QuotaExceededError = globalThis.DOMException);
|
|
1030
|
-
const D = (
|
|
1039
|
+
const D = (a) => {
|
|
1031
1040
|
try {
|
|
1032
|
-
if (!
|
|
1041
|
+
if (!a || a.LanguageModel?.__isPolyfill)
|
|
1033
1042
|
return;
|
|
1034
1043
|
const t = class extends d {
|
|
1035
1044
|
};
|
|
1036
|
-
t.__window =
|
|
1045
|
+
t.__window = a, t.__isPolyfill = !0, a.LanguageModel = t, a.DOMException && (a.QuotaExceededError = a.DOMException);
|
|
1037
1046
|
} catch {
|
|
1038
1047
|
}
|
|
1039
1048
|
};
|
|
1040
1049
|
if (typeof HTMLIFrameElement < "u")
|
|
1041
1050
|
try {
|
|
1042
|
-
const
|
|
1051
|
+
const a = Object.getOwnPropertyDescriptor(
|
|
1043
1052
|
HTMLIFrameElement.prototype,
|
|
1044
1053
|
"contentWindow"
|
|
1045
1054
|
);
|
|
1046
|
-
|
|
1055
|
+
a && a.get && Object.defineProperty(HTMLIFrameElement.prototype, "contentWindow", {
|
|
1047
1056
|
get() {
|
|
1048
|
-
const t =
|
|
1057
|
+
const t = a.get.call(this);
|
|
1049
1058
|
return t && D(t), t;
|
|
1050
1059
|
},
|
|
1051
1060
|
configurable: !0
|
|
1052
1061
|
});
|
|
1053
1062
|
} catch {
|
|
1054
1063
|
}
|
|
1055
|
-
const P = new MutationObserver((
|
|
1056
|
-
for (const t of
|
|
1064
|
+
const P = new MutationObserver((a) => {
|
|
1065
|
+
for (const t of a)
|
|
1057
1066
|
for (const e of t.addedNodes)
|
|
1058
1067
|
e.tagName === "IFRAME" && (D(e.contentWindow), e.addEventListener("load", () => D(e.contentWindow), {
|
|
1059
1068
|
once: !1
|
|
@@ -1062,8 +1071,8 @@ const P = new MutationObserver((s) => {
|
|
|
1062
1071
|
globalThis.document?.documentElement && (P.observe(globalThis.document.documentElement, {
|
|
1063
1072
|
childList: !0,
|
|
1064
1073
|
subtree: !0
|
|
1065
|
-
}), globalThis.document.querySelectorAll("iframe").forEach((
|
|
1066
|
-
D(
|
|
1074
|
+
}), globalThis.document.querySelectorAll("iframe").forEach((a) => {
|
|
1075
|
+
D(a.contentWindow);
|
|
1067
1076
|
}));
|
|
1068
1077
|
(!("LanguageModel" in globalThis) || globalThis.__FORCE_PROMPT_API_POLYFILL__) && (globalThis.LanguageModel = d, d.__isPolyfill = !0, console.log(
|
|
1069
1078
|
"Polyfill: window.LanguageModel is now backed by the Prompt API polyfill."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prompt-api-polyfill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Polyfill for the Prompt API (`LanguageModel`) backed by Firebase AI Logic, Gemini API, OpenAI API, or Transformers.js.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/prompt-api-polyfill.js",
|