prompt-api-polyfill 1.5.0 → 1.6.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 +213 -209
- package/package.json +1 -1
|
@@ -27,13 +27,13 @@ class M {
|
|
|
27
27
|
if (t instanceof Blob)
|
|
28
28
|
return this.blobToInlineData(t);
|
|
29
29
|
if (ArrayBuffer.isView(t) || t instanceof ArrayBuffer) {
|
|
30
|
-
const e = t instanceof ArrayBuffer ? new Uint8Array(t) : new Uint8Array(t.buffer, t.byteOffset, t.byteLength),
|
|
30
|
+
const e = t instanceof ArrayBuffer ? new Uint8Array(t) : new Uint8Array(t.buffer, t.byteOffset, t.byteLength), n = e.buffer.slice(
|
|
31
31
|
e.byteOffset,
|
|
32
32
|
e.byteOffset + e.byteLength
|
|
33
|
-
), r = this.arrayBufferToBase64(
|
|
34
|
-
if (!
|
|
33
|
+
), r = this.arrayBufferToBase64(n), o = this.#o(e);
|
|
34
|
+
if (!o)
|
|
35
35
|
throw new DOMException("Invalid image data", "InvalidStateError");
|
|
36
|
-
return { inlineData: { data: r, mimeType:
|
|
36
|
+
return { inlineData: { data: r, mimeType: o } };
|
|
37
37
|
}
|
|
38
38
|
return this.canvasSourceToInlineData(t);
|
|
39
39
|
}
|
|
@@ -67,8 +67,8 @@ class M {
|
|
|
67
67
|
return "image/jxl";
|
|
68
68
|
if (t[0] === 0 && t[4] === 106 && t[5] === 80 && t[6] === 32)
|
|
69
69
|
return "image/jp2";
|
|
70
|
-
const
|
|
71
|
-
return
|
|
70
|
+
const n = String.fromCharCode(...t.slice(0, 100)).toLowerCase();
|
|
71
|
+
return n.includes("<svg") || n.includes("<?xml") ? "image/svg+xml" : null;
|
|
72
72
|
}
|
|
73
73
|
static async processAudio(t) {
|
|
74
74
|
if (t instanceof Blob) {
|
|
@@ -80,8 +80,8 @@ class M {
|
|
|
80
80
|
const r = this.audioBufferToWav(t);
|
|
81
81
|
return { inlineData: { data: this.arrayBufferToBase64(r), mimeType: "audio/wav" } };
|
|
82
82
|
}
|
|
83
|
-
const e = t instanceof ArrayBuffer || t && t.constructor && t.constructor.name === "ArrayBuffer",
|
|
84
|
-
if (e ||
|
|
83
|
+
const e = t instanceof ArrayBuffer || t && t.constructor && t.constructor.name === "ArrayBuffer", n = ArrayBuffer.isView(t) || t && t.buffer && (t.buffer instanceof ArrayBuffer || t.buffer.constructor.name === "ArrayBuffer");
|
|
84
|
+
if (e || n) {
|
|
85
85
|
const r = e ? t : t.buffer;
|
|
86
86
|
return {
|
|
87
87
|
inlineData: {
|
|
@@ -95,10 +95,10 @@ class M {
|
|
|
95
95
|
}
|
|
96
96
|
// Low Level Converters
|
|
97
97
|
static blobToInlineData(t) {
|
|
98
|
-
return new Promise((e,
|
|
98
|
+
return new Promise((e, n) => {
|
|
99
99
|
const r = new FileReader();
|
|
100
100
|
r.onloadend = () => {
|
|
101
|
-
r.error ?
|
|
101
|
+
r.error ? n(r.error) : e({
|
|
102
102
|
inlineData: {
|
|
103
103
|
data: r.result.split(",")[1],
|
|
104
104
|
mimeType: t.type
|
|
@@ -110,74 +110,74 @@ class M {
|
|
|
110
110
|
static async canvasSourceToInlineData(t) {
|
|
111
111
|
typeof HTMLImageElement < "u" && t instanceof HTMLImageElement && !t.complete && await t.decode().catch(() => {
|
|
112
112
|
});
|
|
113
|
-
const e = (
|
|
114
|
-
const l = t[
|
|
113
|
+
const e = (c) => {
|
|
114
|
+
const l = t[c];
|
|
115
115
|
return typeof l == "object" && l !== null && "baseVal" in l ? l.baseVal.value : typeof l == "number" ? l : 0;
|
|
116
116
|
};
|
|
117
|
-
let
|
|
118
|
-
if ((!
|
|
117
|
+
let n = t.displayWidth || t.naturalWidth || t.videoWidth || e("width"), r = t.displayHeight || t.naturalHeight || t.videoHeight || e("height");
|
|
118
|
+
if ((!n || !r) && typeof t.getBBox == "function")
|
|
119
119
|
try {
|
|
120
|
-
const
|
|
121
|
-
|
|
120
|
+
const c = t.getBBox();
|
|
121
|
+
n = n || c.width, r = r || c.height;
|
|
122
122
|
} catch {
|
|
123
123
|
}
|
|
124
|
-
if ((!
|
|
124
|
+
if ((!n || !r) && typeof t.getBoundingClientRect == "function")
|
|
125
125
|
try {
|
|
126
|
-
const
|
|
127
|
-
|
|
126
|
+
const c = t.getBoundingClientRect();
|
|
127
|
+
n = n || c.width, r = r || c.height;
|
|
128
128
|
} catch {
|
|
129
129
|
}
|
|
130
|
-
if (!
|
|
130
|
+
if (!n || !r)
|
|
131
131
|
throw new DOMException("Invalid image dimensions", "InvalidStateError");
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
const i =
|
|
132
|
+
const o = document.createElement("canvas");
|
|
133
|
+
o.width = n, o.height = r;
|
|
134
|
+
const i = o.getContext("2d");
|
|
135
135
|
return typeof ImageData < "u" && t instanceof ImageData ? i.putImageData(t, 0, 0) : i.drawImage(t, 0, 0), {
|
|
136
136
|
inlineData: {
|
|
137
|
-
data:
|
|
137
|
+
data: o.toDataURL("image/png").split(",")[1],
|
|
138
138
|
mimeType: "image/png"
|
|
139
139
|
}
|
|
140
140
|
};
|
|
141
141
|
}
|
|
142
142
|
static arrayBufferToBase64(t) {
|
|
143
143
|
let e = "";
|
|
144
|
-
const
|
|
145
|
-
for (let
|
|
146
|
-
e += String.fromCharCode(o
|
|
144
|
+
const n = new Uint8Array(t), r = n.byteLength;
|
|
145
|
+
for (let o = 0; o < r; o++)
|
|
146
|
+
e += String.fromCharCode(n[o]);
|
|
147
147
|
return window.btoa(e);
|
|
148
148
|
}
|
|
149
149
|
// Simple WAV Encoder for AudioBuffer
|
|
150
150
|
static audioBufferToWav(t) {
|
|
151
|
-
const e = t.numberOfChannels,
|
|
151
|
+
const e = t.numberOfChannels, n = t.sampleRate, r = 1, o = 16;
|
|
152
152
|
let i;
|
|
153
153
|
return e === 2 ? i = this.interleave(
|
|
154
154
|
t.getChannelData(0),
|
|
155
155
|
t.getChannelData(1)
|
|
156
|
-
) : i = t.getChannelData(0), this.encodeWAV(i, r,
|
|
156
|
+
) : i = t.getChannelData(0), this.encodeWAV(i, r, n, e, o);
|
|
157
157
|
}
|
|
158
158
|
static interleave(t, e) {
|
|
159
|
-
const
|
|
160
|
-
let
|
|
161
|
-
for (;
|
|
162
|
-
r[
|
|
159
|
+
const n = t.length + e.length, r = new Float32Array(n);
|
|
160
|
+
let o = 0, i = 0;
|
|
161
|
+
for (; o < n; )
|
|
162
|
+
r[o++] = t[i], r[o++] = e[i], i++;
|
|
163
163
|
return r;
|
|
164
164
|
}
|
|
165
|
-
static encodeWAV(t, e,
|
|
166
|
-
const i =
|
|
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,
|
|
165
|
+
static encodeWAV(t, e, n, r, o) {
|
|
166
|
+
const i = o / 8, a = r * i, c = new ArrayBuffer(44 + t.length * i), l = new DataView(c);
|
|
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 * a, !0), l.setUint16(32, a, !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
168
|
}
|
|
169
|
-
static floatTo16BitPCM(t, e,
|
|
170
|
-
for (let r = 0; r <
|
|
171
|
-
const
|
|
172
|
-
t.setInt16(e,
|
|
169
|
+
static floatTo16BitPCM(t, e, n) {
|
|
170
|
+
for (let r = 0; r < n.length; r++, e += 2) {
|
|
171
|
+
const o = Math.max(-1, Math.min(1, n[r]));
|
|
172
|
+
t.setInt16(e, o < 0 ? o * 32768 : o * 32767, !0);
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
-
static writeString(t, e,
|
|
176
|
-
for (let r = 0; r <
|
|
177
|
-
t.setUint8(e + r,
|
|
175
|
+
static writeString(t, e, n) {
|
|
176
|
+
for (let r = 0; r < n.length; r++)
|
|
177
|
+
t.setUint8(e + r, n.charCodeAt(r));
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
-
function
|
|
180
|
+
function O(s) {
|
|
181
181
|
if (!s)
|
|
182
182
|
return;
|
|
183
183
|
const t = {
|
|
@@ -201,22 +201,22 @@ function v(s) {
|
|
|
201
201
|
return T.array({
|
|
202
202
|
...t,
|
|
203
203
|
// Recursively convert the 'items' schema
|
|
204
|
-
items:
|
|
204
|
+
items: O(s.items)
|
|
205
205
|
});
|
|
206
206
|
case "object":
|
|
207
|
-
const e = {},
|
|
208
|
-
|
|
209
|
-
e[i] =
|
|
207
|
+
const e = {}, n = s.properties ? Object.keys(s.properties) : [];
|
|
208
|
+
n.forEach((i) => {
|
|
209
|
+
e[i] = O(
|
|
210
210
|
s.properties[i]
|
|
211
211
|
);
|
|
212
212
|
});
|
|
213
|
-
const r = s.required || [],
|
|
213
|
+
const r = s.required || [], o = n.filter(
|
|
214
214
|
(i) => !r.includes(i)
|
|
215
215
|
);
|
|
216
216
|
return T.object({
|
|
217
217
|
...t,
|
|
218
218
|
properties: e,
|
|
219
|
-
optionalProperties:
|
|
219
|
+
optionalProperties: o
|
|
220
220
|
});
|
|
221
221
|
default:
|
|
222
222
|
return console.warn(
|
|
@@ -255,30 +255,30 @@ async function I(s) {
|
|
|
255
255
|
}
|
|
256
256
|
async function C(s, t = globalThis) {
|
|
257
257
|
const e = [];
|
|
258
|
-
for (const
|
|
259
|
-
const r =
|
|
258
|
+
for (const n of s) {
|
|
259
|
+
const r = n.role === "assistant" ? "model" : "user", o = r === "model";
|
|
260
260
|
let i = [];
|
|
261
|
-
if (Array.isArray(
|
|
262
|
-
for (const
|
|
263
|
-
if (
|
|
264
|
-
const
|
|
265
|
-
if (typeof
|
|
261
|
+
if (Array.isArray(n.content))
|
|
262
|
+
for (const a of n.content)
|
|
263
|
+
if (a.type === "text") {
|
|
264
|
+
const c = a.value || a.text || "";
|
|
265
|
+
if (typeof c != "string")
|
|
266
266
|
throw new (t.DOMException || globalThis.DOMException)(
|
|
267
267
|
'The content type "text" must have a string value.',
|
|
268
268
|
"SyntaxError"
|
|
269
269
|
);
|
|
270
|
-
i.push({ text:
|
|
270
|
+
i.push({ text: c });
|
|
271
271
|
} else {
|
|
272
|
-
if (
|
|
272
|
+
if (o)
|
|
273
273
|
throw new (t.DOMException || globalThis.DOMException)(
|
|
274
274
|
"Assistant messages only support text content.",
|
|
275
275
|
"NotSupportedError"
|
|
276
276
|
);
|
|
277
|
-
const
|
|
278
|
-
i.push(
|
|
277
|
+
const c = await M.convert(a.type, a.value);
|
|
278
|
+
i.push(c);
|
|
279
279
|
}
|
|
280
280
|
else
|
|
281
|
-
i.push({ text:
|
|
281
|
+
i.push({ text: n.content });
|
|
282
282
|
e.push({ role: r, parts: i });
|
|
283
283
|
}
|
|
284
284
|
return e;
|
|
@@ -286,15 +286,15 @@ async function C(s, t = globalThis) {
|
|
|
286
286
|
class d extends EventTarget {
|
|
287
287
|
#o;
|
|
288
288
|
#f;
|
|
289
|
-
#r;
|
|
290
|
-
#s;
|
|
291
289
|
#e;
|
|
290
|
+
#s;
|
|
291
|
+
#r;
|
|
292
292
|
#n;
|
|
293
293
|
#i;
|
|
294
294
|
#c;
|
|
295
295
|
#t;
|
|
296
|
-
constructor(t, e,
|
|
297
|
-
super(), this.#o = t, this.#f = e, this.#
|
|
296
|
+
constructor(t, e, n, r = {}, o, i = 0, a = globalThis) {
|
|
297
|
+
super(), this.#o = t, this.#f = e, this.#e = n || [], this.#s = r, this.#r = o, this.#n = !1, this.#i = i, this.#c = {}, this.#t = a;
|
|
298
298
|
}
|
|
299
299
|
get contextUsage() {
|
|
300
300
|
return this.#i;
|
|
@@ -315,8 +315,8 @@ class d extends EventTarget {
|
|
|
315
315
|
if (t !== globalThis && t !== t.top && (!t.frameElement || !t.frameElement.isConnected))
|
|
316
316
|
throw new Error();
|
|
317
317
|
} catch {
|
|
318
|
-
const
|
|
319
|
-
throw new
|
|
318
|
+
const n = t?.DOMException || globalThis.DOMException;
|
|
319
|
+
throw new n(
|
|
320
320
|
"The execution context is not valid.",
|
|
321
321
|
"InvalidStateError"
|
|
322
322
|
);
|
|
@@ -349,12 +349,12 @@ class d extends EventTarget {
|
|
|
349
349
|
}
|
|
350
350
|
static #g = A;
|
|
351
351
|
static #d(t = globalThis) {
|
|
352
|
-
for (const
|
|
353
|
-
const r = t[
|
|
352
|
+
for (const n of d.#g) {
|
|
353
|
+
const r = t[n.config] || globalThis[n.config];
|
|
354
354
|
if (r && r.apiKey)
|
|
355
|
-
return { ...
|
|
355
|
+
return { ...n, configValue: r };
|
|
356
356
|
}
|
|
357
|
-
const e = d.#g.map((
|
|
357
|
+
const e = d.#g.map((n) => `window.${n.config}`).join(", ");
|
|
358
358
|
throw new (t.DOMException || globalThis.DOMException)(
|
|
359
359
|
`Prompt API Polyfill: No backend configuration found. Please set one of: ${e}.`,
|
|
360
360
|
"NotSupportedError"
|
|
@@ -377,13 +377,13 @@ class d extends EventTarget {
|
|
|
377
377
|
throw new RangeError(`Unsupported output type: ${r.type}`);
|
|
378
378
|
r.languages && d.#y(r.languages);
|
|
379
379
|
}
|
|
380
|
-
const
|
|
380
|
+
const n = t.expectedInputs ? ["text", ...t.expectedInputs.map((r) => r.type)] : ["text"];
|
|
381
381
|
if (t.initialPrompts && Array.isArray(t.initialPrompts)) {
|
|
382
382
|
let r = !1;
|
|
383
|
-
for (let
|
|
384
|
-
const i = t.initialPrompts[
|
|
383
|
+
for (let o = 0; o < t.initialPrompts.length; o++) {
|
|
384
|
+
const i = t.initialPrompts[o];
|
|
385
385
|
if (i.role === "system") {
|
|
386
|
-
if (
|
|
386
|
+
if (o !== 0)
|
|
387
387
|
throw new TypeError(
|
|
388
388
|
"The prompt with 'system' role must be placed at the first entry of initialPrompts."
|
|
389
389
|
);
|
|
@@ -394,15 +394,15 @@ class d extends EventTarget {
|
|
|
394
394
|
r = !0;
|
|
395
395
|
}
|
|
396
396
|
if (Array.isArray(i.content))
|
|
397
|
-
for (const
|
|
398
|
-
const
|
|
399
|
-
if (!
|
|
397
|
+
for (const a of i.content) {
|
|
398
|
+
const c = a.type || "text";
|
|
399
|
+
if (!n.includes(c))
|
|
400
400
|
throw new (e.DOMException || globalThis.DOMException)(
|
|
401
|
-
`The content type "${
|
|
401
|
+
`The content type "${c}" is not in the expectedInputs.`,
|
|
402
402
|
"NotSupportedError"
|
|
403
403
|
);
|
|
404
404
|
}
|
|
405
|
-
else if (!
|
|
405
|
+
else if (!n.includes("text"))
|
|
406
406
|
throw new (e.DOMException || globalThis.DOMException)(
|
|
407
407
|
'The content type "text" is not in the expectedInputs.',
|
|
408
408
|
"NotSupportedError"
|
|
@@ -436,13 +436,13 @@ class d extends EventTarget {
|
|
|
436
436
|
"Aborted",
|
|
437
437
|
"AbortError"
|
|
438
438
|
);
|
|
439
|
-
const
|
|
440
|
-
if (
|
|
439
|
+
const n = await this.availability(t);
|
|
440
|
+
if (n === "unavailable")
|
|
441
441
|
throw new (e.DOMException || globalThis.DOMException)(
|
|
442
442
|
"The model is not available for the given options.",
|
|
443
443
|
"NotSupportedError"
|
|
444
444
|
);
|
|
445
|
-
if (
|
|
445
|
+
if (n === "downloadable" || n === "downloading")
|
|
446
446
|
throw new (e.DOMException || globalThis.DOMException)(
|
|
447
447
|
'Requires a user gesture when availability is "downloading" or "downloadable".',
|
|
448
448
|
"NotAllowedError"
|
|
@@ -452,26 +452,26 @@ class d extends EventTarget {
|
|
|
452
452
|
"Aborted",
|
|
453
453
|
"AbortError"
|
|
454
454
|
);
|
|
455
|
-
const r = d.#d(e),
|
|
455
|
+
const r = d.#d(e), o = await d.#p(e), i = new o(r.configValue), a = { ...t };
|
|
456
456
|
d.#x(
|
|
457
|
-
|
|
457
|
+
a.responseConstraint,
|
|
458
458
|
e
|
|
459
459
|
);
|
|
460
|
-
const
|
|
460
|
+
const c = {
|
|
461
461
|
model: i.modelName,
|
|
462
462
|
generationConfig: {}
|
|
463
463
|
};
|
|
464
464
|
let l = [], y = 0;
|
|
465
|
-
if (
|
|
466
|
-
const w =
|
|
465
|
+
if (a.initialPrompts && Array.isArray(a.initialPrompts)) {
|
|
466
|
+
const w = a.initialPrompts.filter(
|
|
467
467
|
(f) => f.role === "system"
|
|
468
|
-
), p =
|
|
468
|
+
), p = a.initialPrompts.filter(
|
|
469
469
|
(f) => f.role !== "system"
|
|
470
470
|
);
|
|
471
|
-
w.length > 0 && (
|
|
471
|
+
w.length > 0 && (c.systemInstruction = w.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
472
|
`) : "").join(`
|
|
473
473
|
`)), l = await C(p, e);
|
|
474
|
-
for (const f of
|
|
474
|
+
for (const f of a.initialPrompts) {
|
|
475
475
|
if (typeof f.content != "string")
|
|
476
476
|
continue;
|
|
477
477
|
const h = d.#E([
|
|
@@ -492,10 +492,10 @@ class d extends EventTarget {
|
|
|
492
492
|
}
|
|
493
493
|
}
|
|
494
494
|
let g = null;
|
|
495
|
-
if (typeof
|
|
495
|
+
if (typeof a.monitor == "function") {
|
|
496
496
|
g = new EventTarget();
|
|
497
497
|
try {
|
|
498
|
-
|
|
498
|
+
a.monitor(g);
|
|
499
499
|
} catch (w) {
|
|
500
500
|
throw w;
|
|
501
501
|
}
|
|
@@ -526,8 +526,8 @@ class d extends EventTarget {
|
|
|
526
526
|
"AbortError"
|
|
527
527
|
);
|
|
528
528
|
const m = await i.createSession(
|
|
529
|
-
c,
|
|
530
529
|
a,
|
|
530
|
+
c,
|
|
531
531
|
g
|
|
532
532
|
);
|
|
533
533
|
if (!await b(1))
|
|
@@ -535,11 +535,11 @@ class d extends EventTarget {
|
|
|
535
535
|
"Aborted",
|
|
536
536
|
"AbortError"
|
|
537
537
|
);
|
|
538
|
-
if (
|
|
538
|
+
if (a.initialPrompts?.length > 0) {
|
|
539
539
|
const w = [...l];
|
|
540
|
-
if (
|
|
540
|
+
if (c.systemInstruction && w.unshift({
|
|
541
541
|
role: "system",
|
|
542
|
-
parts: [{ text:
|
|
542
|
+
parts: [{ text: c.systemInstruction }]
|
|
543
543
|
}), y = await i.countTokens(w) || 0, y > 1e6) {
|
|
544
544
|
const p = e.QuotaExceededError || e.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, f = new p(
|
|
545
545
|
"The initial prompts are too large, they exceed the quota.",
|
|
@@ -552,8 +552,8 @@ class d extends EventTarget {
|
|
|
552
552
|
i,
|
|
553
553
|
m,
|
|
554
554
|
l,
|
|
555
|
-
c,
|
|
556
555
|
a,
|
|
556
|
+
c,
|
|
557
557
|
y,
|
|
558
558
|
e
|
|
559
559
|
);
|
|
@@ -570,9 +570,9 @@ class d extends EventTarget {
|
|
|
570
570
|
"Aborted",
|
|
571
571
|
"AbortError"
|
|
572
572
|
);
|
|
573
|
-
const e = JSON.parse(JSON.stringify(this.#
|
|
574
|
-
|
|
575
|
-
this.#
|
|
573
|
+
const e = JSON.parse(JSON.stringify(this.#e)), n = { ...this.#s, ...t }, r = await d.#p(this.#t), o = d.#d(this.#t), i = new r(o.configValue), a = await i.createSession(
|
|
574
|
+
n,
|
|
575
|
+
this.#r
|
|
576
576
|
);
|
|
577
577
|
if (t.signal?.aborted)
|
|
578
578
|
throw t.signal.reason || new (this.#t.DOMException || globalThis.DOMException)(
|
|
@@ -581,16 +581,16 @@ class d extends EventTarget {
|
|
|
581
581
|
);
|
|
582
582
|
return new this.constructor(
|
|
583
583
|
i,
|
|
584
|
-
|
|
584
|
+
a,
|
|
585
585
|
e,
|
|
586
|
-
|
|
587
|
-
this.#
|
|
586
|
+
n,
|
|
587
|
+
this.#r,
|
|
588
588
|
this.#i,
|
|
589
589
|
this.#t
|
|
590
590
|
);
|
|
591
591
|
}
|
|
592
592
|
destroy() {
|
|
593
|
-
this.#a(), this.#n = !0, this.#
|
|
593
|
+
this.#a(), this.#n = !0, this.#e = null;
|
|
594
594
|
}
|
|
595
595
|
async prompt(t, e = {}) {
|
|
596
596
|
if (this.#a(), this.#n)
|
|
@@ -610,21 +610,21 @@ class d extends EventTarget {
|
|
|
610
610
|
e.responseConstraint,
|
|
611
611
|
this.#t
|
|
612
612
|
);
|
|
613
|
-
const
|
|
613
|
+
const c = O(
|
|
614
614
|
e.responseConstraint
|
|
615
615
|
);
|
|
616
|
-
this.#
|
|
616
|
+
this.#r.generationConfig.responseMimeType = "application/json", this.#r.generationConfig.responseSchema = c, this.#f = this.#o.createSession(
|
|
617
617
|
this.#s,
|
|
618
|
-
this.#
|
|
618
|
+
this.#r
|
|
619
619
|
);
|
|
620
620
|
}
|
|
621
|
-
const
|
|
621
|
+
const n = this.#b(t), r = await this.#l(t);
|
|
622
622
|
if (this.#n)
|
|
623
623
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
624
624
|
"Session is destroyed",
|
|
625
625
|
"InvalidStateError"
|
|
626
626
|
);
|
|
627
|
-
const
|
|
627
|
+
const o = { role: "user", parts: r }, i = new Promise((c, l) => {
|
|
628
628
|
if (e.signal?.aborted) {
|
|
629
629
|
l(
|
|
630
630
|
e.signal.reason || new (this.#t.DOMException || globalThis.DOMException)(
|
|
@@ -646,9 +646,9 @@ class d extends EventTarget {
|
|
|
646
646
|
},
|
|
647
647
|
{ once: !0 }
|
|
648
648
|
);
|
|
649
|
-
}),
|
|
650
|
-
const
|
|
651
|
-
if (
|
|
649
|
+
}), a = (async () => {
|
|
650
|
+
const c = this.#u(r);
|
|
651
|
+
if (c === "QuotaExceededError") {
|
|
652
652
|
const f = this.#t && this.#t.QuotaExceededError || this.#t && this.#t.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, h = new f(
|
|
653
653
|
"The prompt is too large, it exceeds the quota.",
|
|
654
654
|
"QuotaExceededError"
|
|
@@ -656,12 +656,12 @@ class d extends EventTarget {
|
|
|
656
656
|
Object.defineProperty(h, "code", { value: 22, configurable: !0 });
|
|
657
657
|
const E = 1e7;
|
|
658
658
|
throw h.requested = E, h.quota = this.contextWindow, h;
|
|
659
|
-
} else if (
|
|
659
|
+
} else if (c === "contextoverflow")
|
|
660
660
|
return this.dispatchEvent(new Event("contextoverflow")), "Mock response for quota overflow test.";
|
|
661
|
-
const l = [...this.#
|
|
662
|
-
this.#
|
|
661
|
+
const l = [...this.#e, o];
|
|
662
|
+
this.#r.systemInstruction && l.unshift({
|
|
663
663
|
role: "system",
|
|
664
|
-
parts: [{ text: this.#
|
|
664
|
+
parts: [{ text: this.#r.systemInstruction }]
|
|
665
665
|
});
|
|
666
666
|
const y = await this.#o.countTokens(
|
|
667
667
|
l
|
|
@@ -674,7 +674,7 @@ class d extends EventTarget {
|
|
|
674
674
|
throw Object.defineProperty(h, "code", { value: 22, configurable: !0 }), h.requested = y, h.quota = this.contextWindow, h;
|
|
675
675
|
}
|
|
676
676
|
y > this.contextWindow && this.dispatchEvent(new Event("contextoverflow"));
|
|
677
|
-
const g = [...this.#
|
|
677
|
+
const g = [...this.#e, o];
|
|
678
678
|
let b;
|
|
679
679
|
try {
|
|
680
680
|
b = await this.#o.generateContent(g);
|
|
@@ -683,16 +683,16 @@ class d extends EventTarget {
|
|
|
683
683
|
}
|
|
684
684
|
const { text: m, usage: w } = b;
|
|
685
685
|
let p = m;
|
|
686
|
-
if (
|
|
686
|
+
if (n) {
|
|
687
687
|
const f = p.match(/^\s*{\s*"Rating"\s*:\s*/);
|
|
688
688
|
f && (p = p.slice(f[0].length));
|
|
689
689
|
}
|
|
690
|
-
return w && (this.#i = w), this.#
|
|
690
|
+
return w && (this.#i = w), !this.#n && this.#e && (this.#e.push(o), this.#e.push({ role: "model", parts: [{ text: p }] })), p;
|
|
691
691
|
})();
|
|
692
692
|
try {
|
|
693
|
-
return await Promise.race([
|
|
694
|
-
} catch (
|
|
695
|
-
throw
|
|
693
|
+
return await Promise.race([a, i]);
|
|
694
|
+
} catch (c) {
|
|
695
|
+
throw c.name === "AbortError" || console.error("Prompt API Polyfill Error:", c), c;
|
|
696
696
|
}
|
|
697
697
|
}
|
|
698
698
|
promptStreaming(t, e = {}) {
|
|
@@ -708,53 +708,53 @@ class d extends EventTarget {
|
|
|
708
708
|
);
|
|
709
709
|
if (typeof t == "object" && t !== null && !Array.isArray(t) && Object.keys(t).length === 0)
|
|
710
710
|
return new ReadableStream({
|
|
711
|
-
start(
|
|
712
|
-
|
|
711
|
+
start(o) {
|
|
712
|
+
o.enqueue("[object Object]"), o.close();
|
|
713
713
|
}
|
|
714
714
|
});
|
|
715
|
-
const
|
|
715
|
+
const n = this, r = e.signal;
|
|
716
716
|
return new ReadableStream({
|
|
717
|
-
async start(
|
|
717
|
+
async start(o) {
|
|
718
718
|
let i = !1;
|
|
719
|
-
const
|
|
719
|
+
const a = () => {
|
|
720
720
|
i = !0;
|
|
721
721
|
try {
|
|
722
|
-
const
|
|
722
|
+
const c = r?.reason || new (n.#t.DOMException || globalThis.DOMException)(
|
|
723
723
|
"Aborted",
|
|
724
724
|
"AbortError"
|
|
725
725
|
);
|
|
726
|
-
|
|
726
|
+
o.error(c);
|
|
727
727
|
} catch {
|
|
728
728
|
}
|
|
729
729
|
};
|
|
730
730
|
if (r?.aborted) {
|
|
731
|
-
|
|
731
|
+
a();
|
|
732
732
|
return;
|
|
733
733
|
}
|
|
734
|
-
r && r.addEventListener("abort",
|
|
734
|
+
r && r.addEventListener("abort", a);
|
|
735
735
|
try {
|
|
736
736
|
if (e.responseConstraint) {
|
|
737
737
|
d.#x(
|
|
738
738
|
e.responseConstraint,
|
|
739
|
-
|
|
739
|
+
n.#t
|
|
740
740
|
);
|
|
741
|
-
const u =
|
|
741
|
+
const u = O(
|
|
742
742
|
e.responseConstraint
|
|
743
743
|
);
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
744
|
+
n.#r.generationConfig.responseMimeType = "application/json", n.#r.generationConfig.responseSchema = u, n.#f = n.#o.createSession(
|
|
745
|
+
n.#s,
|
|
746
|
+
n.#r
|
|
747
747
|
);
|
|
748
748
|
}
|
|
749
|
-
const
|
|
750
|
-
if (
|
|
751
|
-
throw new (
|
|
749
|
+
const c = n.#b(t), l = await n.#l(t);
|
|
750
|
+
if (n.#n)
|
|
751
|
+
throw new (n.#t.DOMException || globalThis.DOMException)(
|
|
752
752
|
"Session is destroyed",
|
|
753
753
|
"InvalidStateError"
|
|
754
754
|
);
|
|
755
|
-
const y = { role: "user", parts: l }, g =
|
|
755
|
+
const y = { role: "user", parts: l }, g = n.#u(l);
|
|
756
756
|
if (g === "QuotaExceededError") {
|
|
757
|
-
const u =
|
|
757
|
+
const u = n.#t && n.#t.QuotaExceededError || n.#t && n.#t.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, x = new u(
|
|
758
758
|
"The prompt is too large, it exceeds the quota.",
|
|
759
759
|
"QuotaExceededError"
|
|
760
760
|
);
|
|
@@ -762,37 +762,37 @@ class d extends EventTarget {
|
|
|
762
762
|
value: 22,
|
|
763
763
|
configurable: !0
|
|
764
764
|
});
|
|
765
|
-
const
|
|
766
|
-
throw x.requested =
|
|
765
|
+
const v = 1e7;
|
|
766
|
+
throw x.requested = v, x.quota = n.contextWindow, x;
|
|
767
767
|
} else if (g === "contextoverflow") {
|
|
768
|
-
|
|
768
|
+
n.dispatchEvent(new Event("contextoverflow")), o.enqueue("Mock response for quota overflow test."), o.close();
|
|
769
769
|
return;
|
|
770
770
|
}
|
|
771
|
-
const b = [...
|
|
772
|
-
|
|
771
|
+
const b = [...n.#e, y];
|
|
772
|
+
n.#r.systemInstruction && b.unshift({
|
|
773
773
|
role: "system",
|
|
774
|
-
parts: [{ text:
|
|
774
|
+
parts: [{ text: n.#r.systemInstruction }]
|
|
775
775
|
});
|
|
776
|
-
const m = await
|
|
776
|
+
const m = await n.#o.countTokens(
|
|
777
777
|
b
|
|
778
778
|
);
|
|
779
|
-
if (m >
|
|
780
|
-
const u =
|
|
781
|
-
`The prompt is too large (${m} tokens), it exceeds the quota of ${
|
|
779
|
+
if (m > n.contextWindow) {
|
|
780
|
+
const u = n.#t && n.#t.QuotaExceededError || n.#t && n.#t.DOMException || globalThis.QuotaExceededError || globalThis.DOMException, x = new u(
|
|
781
|
+
`The prompt is too large (${m} tokens), it exceeds the quota of ${n.contextWindow} tokens.`,
|
|
782
782
|
"QuotaExceededError"
|
|
783
783
|
);
|
|
784
784
|
throw Object.defineProperty(x, "code", {
|
|
785
785
|
value: 22,
|
|
786
786
|
configurable: !0
|
|
787
|
-
}), x.requested = m, x.quota =
|
|
787
|
+
}), x.requested = m, x.quota = n.contextWindow, x;
|
|
788
788
|
}
|
|
789
|
-
m >
|
|
790
|
-
const w = [...
|
|
789
|
+
m > n.contextWindow && n.dispatchEvent(new Event("contextoverflow"));
|
|
790
|
+
const w = [...n.#e, y];
|
|
791
791
|
let p;
|
|
792
792
|
try {
|
|
793
|
-
p = await
|
|
793
|
+
p = await n.#o.generateContentStream(w);
|
|
794
794
|
} catch (u) {
|
|
795
|
-
throw
|
|
795
|
+
throw n.#m(u, l), u;
|
|
796
796
|
}
|
|
797
797
|
let f = "", h = !1, E = "";
|
|
798
798
|
for await (const u of p) {
|
|
@@ -801,26 +801,26 @@ class d extends EventTarget {
|
|
|
801
801
|
return;
|
|
802
802
|
}
|
|
803
803
|
let x = u.text();
|
|
804
|
-
if (
|
|
804
|
+
if (c && !h) {
|
|
805
805
|
E += x;
|
|
806
|
-
const
|
|
807
|
-
if (
|
|
808
|
-
x = E.slice(
|
|
806
|
+
const v = E.match(/^\s*{\s*"Rating"\s*:\s*/);
|
|
807
|
+
if (v)
|
|
808
|
+
x = E.slice(v[0].length), h = !0, E = "";
|
|
809
809
|
else if (E.length > 50)
|
|
810
810
|
x = E, h = !0, E = "";
|
|
811
811
|
else
|
|
812
812
|
continue;
|
|
813
813
|
}
|
|
814
|
-
f += x, u.usageMetadata?.totalTokenCount && (
|
|
814
|
+
f += x, u.usageMetadata?.totalTokenCount && (n.#i = u.usageMetadata.totalTokenCount), o.enqueue(x);
|
|
815
815
|
}
|
|
816
|
-
i
|
|
816
|
+
!i && !n.#n && n.#e && (n.#e.push(y), n.#e.push({
|
|
817
817
|
role: "model",
|
|
818
818
|
parts: [{ text: f }]
|
|
819
|
-
}),
|
|
820
|
-
} catch (
|
|
821
|
-
i ||
|
|
819
|
+
})), o.close();
|
|
820
|
+
} catch (c) {
|
|
821
|
+
i || o.error(c);
|
|
822
822
|
} finally {
|
|
823
|
-
r && r.removeEventListener("abort",
|
|
823
|
+
r && r.removeEventListener("abort", a);
|
|
824
824
|
}
|
|
825
825
|
}
|
|
826
826
|
});
|
|
@@ -836,21 +836,21 @@ class d extends EventTarget {
|
|
|
836
836
|
"Aborted",
|
|
837
837
|
"AbortError"
|
|
838
838
|
);
|
|
839
|
-
const
|
|
839
|
+
const n = await this.#l(t);
|
|
840
840
|
if (this.#n)
|
|
841
841
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
842
842
|
"Session is destroyed",
|
|
843
843
|
"InvalidStateError"
|
|
844
844
|
);
|
|
845
|
-
const r = { role: "user", parts:
|
|
846
|
-
this.#
|
|
845
|
+
const r = { role: "user", parts: n };
|
|
846
|
+
this.#e.push(r);
|
|
847
847
|
try {
|
|
848
|
-
const
|
|
849
|
-
this.#
|
|
848
|
+
const o = [...this.#e];
|
|
849
|
+
this.#r.systemInstruction && o.unshift({
|
|
850
850
|
role: "system",
|
|
851
|
-
parts: [{ text: this.#
|
|
851
|
+
parts: [{ text: this.#r.systemInstruction }]
|
|
852
852
|
});
|
|
853
|
-
const i = await this.#o.countTokens(
|
|
853
|
+
const i = await this.#o.countTokens(o);
|
|
854
854
|
this.#i = i || 0;
|
|
855
855
|
} catch {
|
|
856
856
|
}
|
|
@@ -869,8 +869,8 @@ class d extends EventTarget {
|
|
|
869
869
|
"Session is destroyed",
|
|
870
870
|
"InvalidStateError"
|
|
871
871
|
);
|
|
872
|
-
const
|
|
873
|
-
return
|
|
872
|
+
const n = this.#u(e);
|
|
873
|
+
return n === "QuotaExceededError" ? 1e7 : n === "contextoverflow" ? 5e5 : await this.#o.countTokens([
|
|
874
874
|
{ role: "user", parts: e }
|
|
875
875
|
]) || 0;
|
|
876
876
|
} catch {
|
|
@@ -924,39 +924,39 @@ class d extends EventTarget {
|
|
|
924
924
|
return [{ text: " " }];
|
|
925
925
|
if (t.length > 0 && t[0].role) {
|
|
926
926
|
let r = [];
|
|
927
|
-
for (const
|
|
928
|
-
const i =
|
|
929
|
-
if (typeof
|
|
927
|
+
for (const o of t) {
|
|
928
|
+
const i = o.role === "assistant" || o.role === "model";
|
|
929
|
+
if (typeof o.content == "string") {
|
|
930
930
|
if (!e.includes("text"))
|
|
931
931
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
932
932
|
'The content type "text" is not in the expectedInputs.',
|
|
933
933
|
"NotSupportedError"
|
|
934
934
|
);
|
|
935
|
-
r.push({ text:
|
|
935
|
+
r.push({ text: o.content }), o.prefix && console.warn(
|
|
936
936
|
"The `prefix` flag isn't supported and was ignored."
|
|
937
937
|
);
|
|
938
|
-
} else if (Array.isArray(
|
|
939
|
-
for (const
|
|
940
|
-
const
|
|
941
|
-
if (!e.includes(
|
|
938
|
+
} else if (Array.isArray(o.content))
|
|
939
|
+
for (const a of o.content) {
|
|
940
|
+
const c = a.type || "text";
|
|
941
|
+
if (!e.includes(c))
|
|
942
942
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
943
|
-
`The content type "${
|
|
943
|
+
`The content type "${c}" is not in the expectedInputs.`,
|
|
944
944
|
"NotSupportedError"
|
|
945
945
|
);
|
|
946
|
-
if (
|
|
947
|
-
if (typeof
|
|
946
|
+
if (c === "text") {
|
|
947
|
+
if (typeof a.value != "string")
|
|
948
948
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
949
949
|
'The content type "text" must have a string value.',
|
|
950
950
|
"SyntaxError"
|
|
951
951
|
);
|
|
952
|
-
r.push({ text:
|
|
952
|
+
r.push({ text: a.value });
|
|
953
953
|
} else {
|
|
954
954
|
if (i)
|
|
955
955
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
956
956
|
"Assistant messages only support text content.",
|
|
957
957
|
"NotSupportedError"
|
|
958
958
|
);
|
|
959
|
-
const l = await M.convert(
|
|
959
|
+
const l = a.value && a.value.inlineData ? a.value : await M.convert(a.type, a.value);
|
|
960
960
|
r.push(l);
|
|
961
961
|
}
|
|
962
962
|
}
|
|
@@ -973,22 +973,26 @@ class d extends EventTarget {
|
|
|
973
973
|
);
|
|
974
974
|
return { text: r === "" ? " " : r };
|
|
975
975
|
}
|
|
976
|
-
if (typeof r == "object" && r !== null
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
);
|
|
983
|
-
if (n === "text") {
|
|
984
|
-
if (typeof r.value != "string")
|
|
976
|
+
if (typeof r == "object" && r !== null) {
|
|
977
|
+
if (r.inlineData)
|
|
978
|
+
return r;
|
|
979
|
+
if (r.type && r.value) {
|
|
980
|
+
const o = r.type || "text";
|
|
981
|
+
if (!e.includes(o))
|
|
985
982
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
986
|
-
|
|
987
|
-
"
|
|
983
|
+
`The content type "${o}" is not in the expectedInputs.`,
|
|
984
|
+
"NotSupportedError"
|
|
988
985
|
);
|
|
989
|
-
|
|
986
|
+
if (o === "text") {
|
|
987
|
+
if (typeof r.value != "string")
|
|
988
|
+
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
989
|
+
'The content type "text" must have a string value.',
|
|
990
|
+
"SyntaxError"
|
|
991
|
+
);
|
|
992
|
+
return { text: r.value };
|
|
993
|
+
}
|
|
994
|
+
return r.value && r.value.inlineData ? r.value : await M.convert(r.type, r.value);
|
|
990
995
|
}
|
|
991
|
-
return await M.convert(r.type, r.value);
|
|
992
996
|
}
|
|
993
997
|
if (!e.includes("text"))
|
|
994
998
|
throw new (this.#t.DOMException || globalThis.DOMException)(
|
|
@@ -1008,16 +1012,16 @@ class d extends EventTarget {
|
|
|
1008
1012
|
}
|
|
1009
1013
|
// Map backend errors to WPT expectations
|
|
1010
1014
|
#m(t, e) {
|
|
1011
|
-
const
|
|
1012
|
-
if (
|
|
1015
|
+
const n = String(t.message || t);
|
|
1016
|
+
if (n.includes("400") || n.toLowerCase().includes("unable to process") || n.toLowerCase().includes("invalid")) {
|
|
1013
1017
|
const r = e.some(
|
|
1014
|
-
(
|
|
1015
|
-
),
|
|
1016
|
-
(
|
|
1018
|
+
(a) => a.inlineData?.mimeType.startsWith("audio/")
|
|
1019
|
+
), o = e.some(
|
|
1020
|
+
(a) => a.inlineData?.mimeType.startsWith("image/")
|
|
1017
1021
|
), i = this.#t.DOMException || globalThis.DOMException;
|
|
1018
1022
|
if (r)
|
|
1019
1023
|
throw new i("Invalid audio data", "DataError");
|
|
1020
|
-
if (
|
|
1024
|
+
if (o)
|
|
1021
1025
|
throw new i("Invalid image data", "InvalidStateError");
|
|
1022
1026
|
}
|
|
1023
1027
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prompt-api-polyfill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.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",
|