@ai-sdk/quiverai 2.0.52 → 2.0.54

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/index.js CHANGED
@@ -1,1218 +1,937 @@
1
- // src/quiverai-provider.ts
2
- import {
3
- NoSuchModelError
4
- } from "@ai-sdk/provider";
5
- import {
6
- createOpenResponses as createOpenResponses2
7
- } from "@ai-sdk/open-responses";
8
- import {
9
- loadApiKey,
10
- loadOptionalSetting,
11
- withoutTrailingSlash,
12
- withUserAgentSuffix
13
- } from "@ai-sdk/provider-utils";
14
-
15
- // src/quiverai-error.ts
16
- import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
1
+ import { InvalidArgumentError, NoSuchModelError } from "@ai-sdk/provider";
2
+ import { createOpenResponses } from "@ai-sdk/open-responses";
3
+ import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, convertBase64ToUint8Array, convertUint8ArrayToBase64, createJsonErrorResponseHandler, createJsonResponseHandler, detectMediaType, lazySchema, loadApiKey, loadOptionalSetting, parseProviderOptions, postJsonToApi, serializeModelOptions, withUserAgentSuffix, withoutTrailingSlash, zodSchema } from "@ai-sdk/provider-utils";
17
4
  import { z } from "zod/v4";
18
- var quiveraiErrorSchema = z.object({
19
- status: z.number().int(),
20
- code: z.string().min(1),
21
- message: z.string().min(1),
22
- request_id: z.string().min(1)
23
- });
24
- var quiveraiFailedResponseHandler = createJsonErrorResponseHandler({
25
- errorSchema: quiveraiErrorSchema,
26
- errorToMessage: (error) => error.message,
27
- isRetryable: (response) => response.status === 429 || response.status >= 500
5
+ //#region src/quiverai-error.ts
6
+ const quiveraiErrorSchema = z.object({
7
+ status: z.number().int(),
8
+ code: z.string().min(1),
9
+ message: z.string().min(1),
10
+ request_id: z.string().min(1)
28
11
  });
29
- var getQuiverAIResponseErrorMetadata = (error) => ({
30
- statusCode: typeof error.status_code === "number" && Number.isInteger(error.status_code) && error.status_code >= 400 && error.status_code <= 599 ? error.status_code : void 0
12
+ const quiveraiFailedResponseHandler = createJsonErrorResponseHandler({
13
+ errorSchema: quiveraiErrorSchema,
14
+ errorToMessage: (error) => error.message,
15
+ isRetryable: (response) => response.status === 429 || response.status >= 500
31
16
  });
32
-
33
- // src/quiverai-language-model.ts
34
- import {
35
- InvalidArgumentError
36
- } from "@ai-sdk/provider";
37
- import {
38
- createOpenResponses
39
- } from "@ai-sdk/open-responses";
40
- import {
41
- serializeModelOptions,
42
- WORKFLOW_DESERIALIZE,
43
- WORKFLOW_SERIALIZE
44
- } from "@ai-sdk/provider-utils";
45
- var QuiverAILanguageModel = class _QuiverAILanguageModel {
46
- constructor(model, config) {
47
- this.model = model;
48
- this.config = config;
49
- this.specificationVersion = "v4";
50
- }
51
- static [WORKFLOW_SERIALIZE](model) {
52
- return serializeModelOptions({
53
- modelId: model.modelId,
54
- config: model.config
55
- });
56
- }
57
- static [WORKFLOW_DESERIALIZE](options) {
58
- const config = {
59
- ...options.config,
60
- failedResponseHandler: quiveraiFailedResponseHandler,
61
- getResponseErrorMetadata: getQuiverAIResponseErrorMetadata
62
- };
63
- return new _QuiverAILanguageModel(
64
- createOpenResponses(config).languageModel(options.modelId),
65
- config
66
- );
67
- }
68
- get modelId() {
69
- return this.model.modelId;
70
- }
71
- get provider() {
72
- return this.model.provider;
73
- }
74
- get supportedUrls() {
75
- return this.model.supportedUrls;
76
- }
77
- async doGenerate(options) {
78
- const prepared = prepareQuiverAICall(options);
79
- const result = await this.model.doGenerate(prepared.options);
80
- return { ...result, warnings: [...prepared.warnings, ...result.warnings] };
81
- }
82
- async doStream(options) {
83
- const prepared = prepareQuiverAICall(options);
84
- const result = await this.model.doStream(prepared.options);
85
- if (prepared.warnings.length === 0) return result;
86
- return {
87
- ...result,
88
- stream: result.stream.pipeThrough(
89
- new TransformStream({
90
- transform(part, controller) {
91
- controller.enqueue(
92
- part.type === "stream-start" ? {
93
- ...part,
94
- warnings: [...prepared.warnings, ...part.warnings]
95
- } : part
96
- );
97
- }
98
- })
99
- )
100
- };
101
- }
17
+ const getQuiverAIResponseErrorMetadata = (error) => ({ statusCode: typeof error.status_code === "number" && Number.isInteger(error.status_code) && error.status_code >= 400 && error.status_code <= 599 ? error.status_code : void 0 });
18
+ //#endregion
19
+ //#region src/quiverai-language-model.ts
20
+ /** Applies QuiverAI's request policy while reusing the Open Responses transport. */
21
+ var QuiverAILanguageModel = class QuiverAILanguageModel {
22
+ static [WORKFLOW_SERIALIZE](model) {
23
+ return serializeModelOptions({
24
+ modelId: model.modelId,
25
+ config: model.config
26
+ });
27
+ }
28
+ static [WORKFLOW_DESERIALIZE](options) {
29
+ const config = {
30
+ ...options.config,
31
+ failedResponseHandler: quiveraiFailedResponseHandler,
32
+ getResponseErrorMetadata: getQuiverAIResponseErrorMetadata
33
+ };
34
+ return new QuiverAILanguageModel(createOpenResponses(config).languageModel(options.modelId), config);
35
+ }
36
+ constructor(model, config) {
37
+ this.model = model;
38
+ this.config = config;
39
+ this.specificationVersion = "v4";
40
+ }
41
+ get modelId() {
42
+ return this.model.modelId;
43
+ }
44
+ get provider() {
45
+ return this.model.provider;
46
+ }
47
+ get supportedUrls() {
48
+ return this.model.supportedUrls;
49
+ }
50
+ async doGenerate(options) {
51
+ const prepared = prepareQuiverAICall(options);
52
+ const result = await this.model.doGenerate(prepared.options);
53
+ return {
54
+ ...result,
55
+ warnings: [...prepared.warnings, ...result.warnings]
56
+ };
57
+ }
58
+ async doStream(options) {
59
+ const prepared = prepareQuiverAICall(options);
60
+ const result = await this.model.doStream(prepared.options);
61
+ if (prepared.warnings.length === 0) return result;
62
+ return {
63
+ ...result,
64
+ stream: result.stream.pipeThrough(new TransformStream({ transform(part, controller) {
65
+ controller.enqueue(part.type === "stream-start" ? {
66
+ ...part,
67
+ warnings: [...prepared.warnings, ...part.warnings]
68
+ } : part);
69
+ } }))
70
+ };
71
+ }
102
72
  };
103
73
  function prepareQuiverAICall(options) {
104
- const { reasoningEffort, reasoningSummary } = options.providerOptions?.quiverai ?? {};
105
- if (reasoningEffort != null && (typeof reasoningEffort !== "string" || !["low", "medium", "high", "xhigh"].includes(reasoningEffort))) {
106
- throw new InvalidArgumentError({
107
- argument: "providerOptions",
108
- message: `Unsupported reasoning effort: ${reasoningEffort}`
109
- });
110
- }
111
- if (reasoningSummary != null && reasoningSummary !== "auto") {
112
- throw new InvalidArgumentError({
113
- argument: "providerOptions",
114
- message: `Unsupported reasoning summary: ${reasoningSummary}`
115
- });
116
- }
117
- const warnings = [];
118
- const omitReasoning = options.reasoning === "none" && reasoningEffort == null;
119
- if (omitReasoning) {
120
- warnings.push({ type: "unsupported", feature: "reasoning effort none" });
121
- }
122
- return {
123
- warnings,
124
- options: {
125
- ...options,
126
- reasoning: omitReasoning ? void 0 : options.reasoning,
127
- prompt: options.prompt.map(
128
- (message) => message.role !== "assistant" ? message : {
129
- ...message,
130
- content: message.content.map((part) => {
131
- if (part.type !== "reasoning") return part;
132
- const metadata = part.providerOptions?.quiverai ?? part.providerMetadata?.quiverai;
133
- return {
134
- ...part,
135
- text: "",
136
- providerOptions: {
137
- ...part.providerOptions,
138
- quiverai: {
139
- itemId: metadata?.itemId,
140
- reasoningSummary: metadata?.reasoningSummary
141
- }
142
- }
143
- };
144
- })
145
- }
146
- )
147
- }
148
- };
74
+ const { reasoningEffort, reasoningSummary } = options.providerOptions?.quiverai ?? {};
75
+ if (reasoningEffort != null && (typeof reasoningEffort !== "string" || ![
76
+ "low",
77
+ "medium",
78
+ "high",
79
+ "xhigh"
80
+ ].includes(reasoningEffort))) throw new InvalidArgumentError({
81
+ argument: "providerOptions",
82
+ message: `Unsupported reasoning effort: ${reasoningEffort}`
83
+ });
84
+ if (reasoningSummary != null && reasoningSummary !== "auto") throw new InvalidArgumentError({
85
+ argument: "providerOptions",
86
+ message: `Unsupported reasoning summary: ${reasoningSummary}`
87
+ });
88
+ const warnings = [];
89
+ const omitReasoning = options.reasoning === "none" && reasoningEffort == null;
90
+ if (omitReasoning) warnings.push({
91
+ type: "unsupported",
92
+ feature: "reasoning effort none"
93
+ });
94
+ return {
95
+ warnings,
96
+ options: {
97
+ ...options,
98
+ reasoning: omitReasoning ? void 0 : options.reasoning,
99
+ prompt: options.prompt.map((message) => message.role !== "assistant" ? message : {
100
+ ...message,
101
+ content: message.content.map((part) => {
102
+ if (part.type !== "reasoning") return part;
103
+ const metadata = part.providerOptions?.quiverai ?? part.providerMetadata?.quiverai;
104
+ return {
105
+ ...part,
106
+ text: "",
107
+ providerOptions: {
108
+ ...part.providerOptions,
109
+ quiverai: {
110
+ itemId: metadata?.itemId,
111
+ reasoningSummary: metadata?.reasoningSummary
112
+ }
113
+ }
114
+ };
115
+ })
116
+ })
117
+ }
118
+ };
149
119
  }
150
-
151
- // src/quiverai-image-model.ts
152
- import {
153
- InvalidArgumentError as InvalidArgumentError3
154
- } from "@ai-sdk/provider";
155
- import {
156
- combineHeaders,
157
- convertBase64ToUint8Array as convertBase64ToUint8Array2,
158
- convertUint8ArrayToBase64 as convertUint8ArrayToBase642,
159
- createJsonResponseHandler,
160
- parseProviderOptions,
161
- postJsonToApi,
162
- serializeModelOptions as serializeModelOptions2,
163
- WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE2,
164
- WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE2
165
- } from "@ai-sdk/provider-utils";
166
- import { z as z3 } from "zod/v4";
167
-
168
- // src/quiverai-image-model-options.ts
169
- import {
170
- lazySchema,
171
- zodSchema
172
- } from "@ai-sdk/provider-utils";
173
- import { z as z2 } from "zod/v4";
174
- var quiveraiImageModelOptionsSchema = lazySchema(
175
- () => zodSchema(
176
- z2.object({
177
- /**
178
- * The operation to perform. Defaults to `generate`.
179
- *
180
- * - `generate`: Text-to-SVG generation. Requires `prompt`.
181
- * - `vectorize`: Convert an input raster image into an SVG. Requires a
182
- * single image in `prompt.images` / `files`.
183
- * - `animate`: Animate an input SVG. Requires a single SVG in
184
- * `prompt.images` / `files`; the text prompt is optional.
185
- * - `edit`: Edit a single SVG from `prompt.images` using `prompt.text`
186
- * as the required instruction.
187
- */
188
- operation: z2.enum(["generate", "vectorize", "animate", "edit"]).optional(),
189
- /**
190
- * Extra style guidance for prompt-based generation.
191
- */
192
- instructions: z2.string().min(1).optional(),
193
- /**
194
- * Reasoning effort applied to generation or vectorization.
195
- */
196
- reasoningEffort: z2.enum(["low", "medium", "high", "xhigh"]).optional(),
197
- /**
198
- * Optional reference images for SVG editing. Use
199
- * `prepareQuiverAIImageReference` to convert binary inputs.
200
- */
201
- referenceImages: z2.array(
202
- z2.union([
203
- z2.object({ url: z2.string().min(1) }).strict(),
204
- z2.object({ base64: z2.string().min(1).max(16777216) }).strict()
205
- ])
206
- ).max(4).optional(),
207
- /**
208
- * Maximum number of edit review and redo steps (0-5).
209
- */
210
- maxReviewSteps: z2.number().int().min(0).max(5).optional(),
211
- /**
212
- * SVG root attributes requested for generation or vectorization.
213
- */
214
- attributes: z2.object({
215
- viewBox: z2.object({
216
- minX: z2.number(),
217
- minY: z2.number(),
218
- width: z2.number().positive(),
219
- height: z2.number().positive()
220
- }).optional()
221
- }).optional(),
222
- /**
223
- * Sampling temperature (0-2).
224
- */
225
- temperature: z2.number().min(0).max(2).optional(),
226
- /**
227
- * Nucleus sampling top-p (0-1).
228
- */
229
- topP: z2.number().min(0).max(1).optional(),
230
- /**
231
- * Presence penalty (-2 to 2).
232
- */
233
- presencePenalty: z2.number().min(-2).max(2).nullable().optional(),
234
- /**
235
- * Maximum number of output tokens (1 - 65536 for Arrow 2 models).
236
- * The legacy upper bound of 131072 is retained for other model IDs.
237
- */
238
- maxOutputTokens: z2.number().int().min(1).max(131072).optional(),
239
- /**
240
- * Provider orchestrator token budget for SVG editing (1-65536).
241
- */
242
- orchestratorMaxOutputTokens: z2.number().int().min(1).max(65536).optional(),
243
- /**
244
- * Provider shallow edit token budget for SVG editing (1-65536).
245
- */
246
- shallowMaxOutputTokens: z2.number().int().min(1).max(65536).optional(),
247
- /**
248
- * Whether to auto-crop the input image before vectorization.
249
- * Only used when `operation` is `vectorize`.
250
- */
251
- autoCrop: z2.boolean().optional(),
252
- /**
253
- * Target canvas size in pixels for vectorization (128 - 4096).
254
- * Only used when `operation` is `vectorize`.
255
- */
256
- targetSize: z2.number().int().min(128).max(4096).optional()
257
- })
258
- )
259
- );
260
-
261
- // src/prepare-quiverai-image-reference.ts
262
- import { InvalidArgumentError as InvalidArgumentError2 } from "@ai-sdk/provider";
263
- import {
264
- convertBase64ToUint8Array,
265
- convertUint8ArrayToBase64,
266
- detectMediaType
267
- } from "@ai-sdk/provider-utils";
268
- var MAX_REFERENCE_BASE64_LENGTH = 16777216;
269
- var MAX_REFERENCE_BYTES = 12582912;
270
- var supportedReferenceMediaTypes = /* @__PURE__ */ new Set([
271
- "image/gif",
272
- "image/jpeg",
273
- "image/png",
274
- "image/svg+xml",
275
- "image/webp"
120
+ //#endregion
121
+ //#region src/quiverai-image-model-options.ts
122
+ /**
123
+ * Provider options schema for QuiverAI image generation.
124
+ *
125
+ * @see https://quiver.ai/
126
+ */
127
+ const quiveraiImageModelOptionsSchema = lazySchema(() => zodSchema(z.object({
128
+ /**
129
+ * The operation to perform. Defaults to `generate`.
130
+ *
131
+ * - `generate`: Text-to-SVG generation. Requires `prompt`.
132
+ * - `vectorize`: Convert an input raster image into an SVG. Requires a
133
+ * single image in `prompt.images` / `files`.
134
+ * - `animate`: Animate an input SVG. Requires a single SVG in
135
+ * `prompt.images` / `files`; the text prompt is optional.
136
+ * - `edit`: Edit a single SVG from `prompt.images` using `prompt.text`
137
+ * as the required instruction.
138
+ */
139
+ operation: z.enum([
140
+ "generate",
141
+ "vectorize",
142
+ "animate",
143
+ "edit"
144
+ ]).optional(),
145
+ /**
146
+ * Extra style guidance for prompt-based generation.
147
+ */
148
+ instructions: z.string().min(1).optional(),
149
+ /**
150
+ * Reasoning effort applied to generation or vectorization.
151
+ */
152
+ reasoningEffort: z.enum([
153
+ "low",
154
+ "medium",
155
+ "high",
156
+ "xhigh"
157
+ ]).optional(),
158
+ /**
159
+ * Optional reference images for SVG editing. Use
160
+ * `prepareQuiverAIImageReference` to convert binary inputs.
161
+ */
162
+ referenceImages: z.array(z.union([z.object({ url: z.string().min(1) }).strict(), z.object({ base64: z.string().min(1).max(16777216) }).strict()])).max(4).optional(),
163
+ /**
164
+ * Maximum number of edit review and redo steps (0-5).
165
+ */
166
+ maxReviewSteps: z.number().int().min(0).max(5).optional(),
167
+ /**
168
+ * SVG root attributes requested for generation or vectorization.
169
+ */
170
+ attributes: z.object({ viewBox: z.object({
171
+ minX: z.number(),
172
+ minY: z.number(),
173
+ width: z.number().positive(),
174
+ height: z.number().positive()
175
+ }).optional() }).optional(),
176
+ /**
177
+ * Sampling temperature (0-2).
178
+ */
179
+ temperature: z.number().min(0).max(2).optional(),
180
+ /**
181
+ * Nucleus sampling top-p (0-1).
182
+ */
183
+ topP: z.number().min(0).max(1).optional(),
184
+ /**
185
+ * Presence penalty (-2 to 2).
186
+ */
187
+ presencePenalty: z.number().min(-2).max(2).nullable().optional(),
188
+ /**
189
+ * Maximum number of output tokens (1 - 65536 for Arrow 2 models).
190
+ * The legacy upper bound of 131072 is retained for other model IDs.
191
+ */
192
+ maxOutputTokens: z.number().int().min(1).max(131072).optional(),
193
+ /**
194
+ * Provider orchestrator token budget for SVG editing (1-65536).
195
+ */
196
+ orchestratorMaxOutputTokens: z.number().int().min(1).max(65536).optional(),
197
+ /**
198
+ * Provider shallow edit token budget for SVG editing (1-65536).
199
+ */
200
+ shallowMaxOutputTokens: z.number().int().min(1).max(65536).optional(),
201
+ /**
202
+ * Whether to auto-crop the input image before vectorization.
203
+ * Only used when `operation` is `vectorize`.
204
+ */
205
+ autoCrop: z.boolean().optional(),
206
+ /**
207
+ * Target canvas size in pixels for vectorization (128 - 4096).
208
+ * Only used when `operation` is `vectorize`.
209
+ */
210
+ targetSize: z.number().int().min(128).max(4096).optional()
211
+ })));
212
+ //#endregion
213
+ //#region src/prepare-quiverai-image-reference.ts
214
+ const MAX_REFERENCE_BASE64_LENGTH = 16777216;
215
+ const MAX_REFERENCE_BYTES = 12582912;
216
+ const supportedReferenceMediaTypes = /* @__PURE__ */ new Set([
217
+ "image/gif",
218
+ "image/jpeg",
219
+ "image/png",
220
+ "image/svg+xml",
221
+ "image/webp"
276
222
  ]);
223
+ /**
224
+ * Converts URL, binary, data URL, or base64 image input into the JSON-safe
225
+ * reference shape accepted by QuiverAI provider options.
226
+ */
277
227
  function prepareQuiverAIImageReference(input) {
278
- if (input instanceof URL) {
279
- return { url: validateQuiverAIImageUrl(input.toString()) };
280
- }
281
- if (typeof input === "string") {
282
- if (/^[a-z][a-z\d+.-]*:\/\//i.test(input)) {
283
- return { url: validateQuiverAIImageUrl(input) };
284
- }
285
- if (input.startsWith("data:")) {
286
- const match = /^data:([^;,]+);base64,(.+)$/s.exec(input);
287
- if (match == null || !supportedReferenceMediaTypes.has(match[1])) {
288
- throw new InvalidArgumentError2({
289
- argument: "input",
290
- message: "QuiverAI reference image data URLs must use base64 encoding and a supported image media type."
291
- });
292
- }
293
- validateQuiverAIReferenceBase64(match[2], "input");
294
- return { base64: match[2] };
295
- }
296
- validateQuiverAIReferenceBase64(input, "input");
297
- return { base64: input };
298
- }
299
- const data = input instanceof ArrayBuffer ? new Uint8Array(input) : new Uint8Array(input);
300
- validateQuiverAIReferenceBytes(data, "input");
301
- return { base64: convertUint8ArrayToBase64(data) };
228
+ if (input instanceof URL) return { url: validateQuiverAIImageUrl(input.toString()) };
229
+ if (typeof input === "string") {
230
+ if (/^[a-z][a-z\d+.-]*:\/\//i.test(input)) return { url: validateQuiverAIImageUrl(input) };
231
+ if (input.startsWith("data:")) {
232
+ const match = /^data:([^;,]+);base64,(.+)$/s.exec(input);
233
+ if (match == null || !supportedReferenceMediaTypes.has(match[1])) throw new InvalidArgumentError({
234
+ argument: "input",
235
+ message: "QuiverAI reference image data URLs must use base64 encoding and a supported image media type."
236
+ });
237
+ validateQuiverAIReferenceBase64(match[2], "input");
238
+ return { base64: match[2] };
239
+ }
240
+ validateQuiverAIReferenceBase64(input, "input");
241
+ return { base64: input };
242
+ }
243
+ const data = input instanceof ArrayBuffer ? new Uint8Array(input) : new Uint8Array(input);
244
+ validateQuiverAIReferenceBytes(data, "input");
245
+ return { base64: convertUint8ArrayToBase64(data) };
302
246
  }
303
247
  function validateQuiverAIImageUrl(url) {
304
- let parsed;
305
- try {
306
- parsed = new URL(url);
307
- } catch {
308
- throw new InvalidArgumentError2({
309
- argument: "url",
310
- message: "QuiverAI image URLs must be valid HTTP or HTTPS URLs."
311
- });
312
- }
313
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
314
- throw new InvalidArgumentError2({
315
- argument: "url",
316
- message: "QuiverAI image URLs must use HTTP or HTTPS."
317
- });
318
- }
319
- return parsed.toString();
248
+ let parsed;
249
+ try {
250
+ parsed = new URL(url);
251
+ } catch {
252
+ throw new InvalidArgumentError({
253
+ argument: "url",
254
+ message: "QuiverAI image URLs must be valid HTTP or HTTPS URLs."
255
+ });
256
+ }
257
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new InvalidArgumentError({
258
+ argument: "url",
259
+ message: "QuiverAI image URLs must use HTTP or HTTPS."
260
+ });
261
+ return parsed.toString();
320
262
  }
321
263
  function validateQuiverAIReferenceBase64(base64, argument) {
322
- if (base64.length === 0 || base64.length > MAX_REFERENCE_BASE64_LENGTH) {
323
- throw new InvalidArgumentError2({
324
- argument,
325
- message: `QuiverAI reference images must contain 1-${MAX_REFERENCE_BASE64_LENGTH} base64 characters.`
326
- });
327
- }
328
- let data;
329
- try {
330
- data = convertBase64ToUint8Array(base64);
331
- } catch (cause) {
332
- throw new InvalidArgumentError2({
333
- argument,
334
- message: "QuiverAI reference image data must be valid base64.",
335
- cause
336
- });
337
- }
338
- validateQuiverAIReferenceBytes(data, argument);
264
+ if (base64.length === 0 || base64.length > MAX_REFERENCE_BASE64_LENGTH) throw new InvalidArgumentError({
265
+ argument,
266
+ message: `QuiverAI reference images must contain 1-${MAX_REFERENCE_BASE64_LENGTH} base64 characters.`
267
+ });
268
+ let data;
269
+ try {
270
+ data = convertBase64ToUint8Array(base64);
271
+ } catch (cause) {
272
+ throw new InvalidArgumentError({
273
+ argument,
274
+ message: "QuiverAI reference image data must be valid base64.",
275
+ cause
276
+ });
277
+ }
278
+ validateQuiverAIReferenceBytes(data, argument);
339
279
  }
340
280
  function validateQuiverAIReferenceBytes(data, argument) {
341
- if (data.length === 0 || data.length > MAX_REFERENCE_BYTES) {
342
- throw new InvalidArgumentError2({
343
- argument,
344
- message: `QuiverAI reference images must decode to 1-${MAX_REFERENCE_BYTES} bytes.`
345
- });
346
- }
347
- const mediaType = isSvg(data) ? "image/svg+xml" : detectMediaType({ data, topLevelType: "image" });
348
- if (mediaType == null || !supportedReferenceMediaTypes.has(mediaType)) {
349
- throw new InvalidArgumentError2({
350
- argument,
351
- message: "QuiverAI reference images must be PNG, JPEG, WebP, GIF, or SVG data."
352
- });
353
- }
281
+ if (data.length === 0 || data.length > MAX_REFERENCE_BYTES) throw new InvalidArgumentError({
282
+ argument,
283
+ message: `QuiverAI reference images must decode to 1-${MAX_REFERENCE_BYTES} bytes.`
284
+ });
285
+ const mediaType = isSvg$1(data) ? "image/svg+xml" : detectMediaType({
286
+ data,
287
+ topLevelType: "image"
288
+ });
289
+ if (mediaType == null || !supportedReferenceMediaTypes.has(mediaType)) throw new InvalidArgumentError({
290
+ argument,
291
+ message: "QuiverAI reference images must be PNG, JPEG, WebP, GIF, or SVG data."
292
+ });
354
293
  }
355
- function isSvg(data) {
356
- let text;
357
- try {
358
- text = new TextDecoder("utf-8", { fatal: true }).decode(data);
359
- } catch {
360
- return false;
361
- }
362
- const normalized = text.replace(/^\uFEFF/, "").trim();
363
- return /^(?:<\?xml[\s\S]*?\?>\s*)?(?:<!--[\s\S]*?-->\s*)?(?:<!DOCTYPE[\s\S]*?>\s*)?<svg[\s>]/i.test(
364
- normalized
365
- ) && (/<\/svg>\s*$/i.test(normalized) || /<svg(?:\s[^>]*)?\/>\s*$/is.test(normalized));
294
+ function isSvg$1(data) {
295
+ let text;
296
+ try {
297
+ text = new TextDecoder("utf-8", { fatal: true }).decode(data);
298
+ } catch {
299
+ return false;
300
+ }
301
+ const normalized = text.replace(/^\uFEFF/, "").trim();
302
+ return /^(?:<\?xml[\s\S]*?\?>\s*)?(?:<!--[\s\S]*?-->\s*)?(?:<!DOCTYPE[\s\S]*?>\s*)?<svg[\s>]/i.test(normalized) && (/<\/svg>\s*$/i.test(normalized) || /<svg(?:\s[^>]*)?\/>\s*$/is.test(normalized));
366
303
  }
367
-
368
- // src/quiverai-image-model.ts
369
- var QuiverAIImageModel = class _QuiverAIImageModel {
370
- constructor(modelId, config) {
371
- this.modelId = modelId;
372
- this.config = config;
373
- this.specificationVersion = "v4";
374
- this.maxImagesPerCall = 16;
375
- }
376
- get supportsFileInputs() {
377
- return this.modelId === "arrow-1" || this.modelId === "arrow-1.1" || this.modelId === "arrow-1.1-max" || this.modelId === "arrow-2" || this.modelId === "arrow-2-telos" ? true : void 0;
378
- }
379
- get supportsMaskInputs() {
380
- return this.supportsFileInputs === true ? false : void 0;
381
- }
382
- get provider() {
383
- return this.config.provider;
384
- }
385
- static [WORKFLOW_SERIALIZE2](model) {
386
- return serializeModelOptions2({
387
- modelId: model.modelId,
388
- config: model.config
389
- });
390
- }
391
- static [WORKFLOW_DESERIALIZE2](options) {
392
- return new _QuiverAIImageModel(options.modelId, options.config);
393
- }
394
- async doGenerate({
395
- prompt,
396
- n,
397
- files,
398
- mask,
399
- size,
400
- aspectRatio,
401
- seed,
402
- providerOptions,
403
- headers,
404
- abortSignal
405
- }) {
406
- const quiveraiOptions = await parseProviderOptions({
407
- provider: "quiverai",
408
- providerOptions,
409
- schema: quiveraiImageModelOptionsSchema
410
- });
411
- const operation = quiveraiOptions?.operation ?? "generate";
412
- const warnings = collectWarnings({ size, aspectRatio, seed, mask });
413
- const body = buildRequestBody({
414
- modelId: this.modelId,
415
- n,
416
- prompt,
417
- files,
418
- mask,
419
- operation,
420
- options: quiveraiOptions ?? {}
421
- });
422
- const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
423
- const combinedHeaders = combineHeaders(this.config.headers?.(), headers);
424
- const { value: response, responseHeaders } = await postJsonToApi({
425
- url: `${this.config.baseURL}${getOperationPath(operation)}`,
426
- headers: combinedHeaders,
427
- body,
428
- failedResponseHandler: quiveraiFailedResponseHandler,
429
- successfulResponseHandler: createJsonResponseHandler(
430
- svgGenerationResponseSchema
431
- ),
432
- abortSignal,
433
- fetch: this.config.fetch
434
- });
435
- const encoder = new TextEncoder();
436
- const images = response.data.map((image) => encoder.encode(image.svg));
437
- return {
438
- images,
439
- warnings,
440
- providerMetadata: {
441
- quiverai: {
442
- ...response.credits != null && { credits: response.credits },
443
- images: response.data.map((image, index) => ({
444
- index,
445
- mimeType: image.mime_type,
446
- ...image.loop_period_ms !== void 0 && {
447
- loopPeriodMs: image.loop_period_ms
448
- },
449
- ...image.opening_animation_ms !== void 0 && {
450
- openingAnimationMs: image.opening_animation_ms
451
- }
452
- }))
453
- }
454
- },
455
- response: {
456
- timestamp: response.created ? new Date(response.created * 1e3) : currentDate,
457
- modelId: this.modelId,
458
- headers: responseHeaders
459
- },
460
- ...response.usage && {
461
- usage: {
462
- inputTokens: response.usage.input_tokens,
463
- outputTokens: response.usage.output_tokens,
464
- totalTokens: response.usage.total_tokens
465
- }
466
- }
467
- };
468
- }
304
+ //#endregion
305
+ //#region src/quiverai-image-model.ts
306
+ var QuiverAIImageModel = class QuiverAIImageModel {
307
+ get supportsFileInputs() {
308
+ return this.modelId === "arrow-1" || this.modelId === "arrow-1.1" || this.modelId === "arrow-1.1-max" || this.modelId === "arrow-2" || this.modelId === "arrow-2-telos" ? true : void 0;
309
+ }
310
+ get supportsMaskInputs() {
311
+ return this.supportsFileInputs === true ? false : void 0;
312
+ }
313
+ get provider() {
314
+ return this.config.provider;
315
+ }
316
+ static [WORKFLOW_SERIALIZE](model) {
317
+ return serializeModelOptions({
318
+ modelId: model.modelId,
319
+ config: model.config
320
+ });
321
+ }
322
+ static [WORKFLOW_DESERIALIZE](options) {
323
+ return new QuiverAIImageModel(options.modelId, options.config);
324
+ }
325
+ constructor(modelId, config) {
326
+ this.modelId = modelId;
327
+ this.config = config;
328
+ this.specificationVersion = "v4";
329
+ this.maxImagesPerCall = 16;
330
+ }
331
+ async doGenerate({ prompt, n, files, mask, size, aspectRatio, seed, providerOptions, headers, abortSignal }) {
332
+ const quiveraiOptions = await parseProviderOptions({
333
+ provider: "quiverai",
334
+ providerOptions,
335
+ schema: quiveraiImageModelOptionsSchema
336
+ });
337
+ const operation = quiveraiOptions?.operation ?? "generate";
338
+ const warnings = collectWarnings({
339
+ size,
340
+ aspectRatio,
341
+ seed,
342
+ mask
343
+ });
344
+ const body = buildRequestBody({
345
+ modelId: this.modelId,
346
+ n,
347
+ prompt,
348
+ files,
349
+ mask,
350
+ operation,
351
+ options: quiveraiOptions ?? {}
352
+ });
353
+ const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
354
+ const combinedHeaders = combineHeaders(this.config.headers?.(), headers);
355
+ const { value: response, responseHeaders } = await postJsonToApi({
356
+ url: `${this.config.baseURL}${getOperationPath(operation)}`,
357
+ headers: combinedHeaders,
358
+ body,
359
+ failedResponseHandler: quiveraiFailedResponseHandler,
360
+ successfulResponseHandler: createJsonResponseHandler(svgGenerationResponseSchema),
361
+ abortSignal,
362
+ fetch: this.config.fetch
363
+ });
364
+ const encoder = new TextEncoder();
365
+ return {
366
+ images: response.data.map((image) => encoder.encode(image.svg)),
367
+ warnings,
368
+ providerMetadata: { quiverai: {
369
+ ...response.credits != null && { credits: response.credits },
370
+ images: response.data.map((image, index) => ({
371
+ index,
372
+ mimeType: image.mime_type,
373
+ ...image.loop_period_ms !== void 0 && { loopPeriodMs: image.loop_period_ms },
374
+ ...image.opening_animation_ms !== void 0 && { openingAnimationMs: image.opening_animation_ms }
375
+ }))
376
+ } },
377
+ response: {
378
+ timestamp: response.created ? /* @__PURE__ */ new Date(response.created * 1e3) : currentDate,
379
+ modelId: this.modelId,
380
+ headers: responseHeaders
381
+ },
382
+ ...response.usage && { usage: {
383
+ inputTokens: response.usage.input_tokens,
384
+ outputTokens: response.usage.output_tokens,
385
+ totalTokens: response.usage.total_tokens
386
+ } }
387
+ };
388
+ }
469
389
  };
470
390
  function getOperationPath(operation) {
471
- switch (operation) {
472
- case "generate":
473
- return "/svgs/generations";
474
- case "vectorize":
475
- return "/svgs/vectorizations";
476
- case "edit":
477
- return "/svgs/edits";
478
- case "animate":
479
- return "/svgs/animations";
480
- }
391
+ switch (operation) {
392
+ case "generate": return "/svgs/generations";
393
+ case "vectorize": return "/svgs/vectorizations";
394
+ case "edit": return "/svgs/edits";
395
+ case "animate": return "/svgs/animations";
396
+ }
481
397
  }
482
398
  function getGenerateReferenceLimit(modelId) {
483
- return ["arrow-1", "arrow-1.0", "arrow-1.1"].includes(modelId) ? 4 : 16;
399
+ return [
400
+ "arrow-1",
401
+ "arrow-1.0",
402
+ "arrow-1.1"
403
+ ].includes(modelId) ? 4 : 16;
484
404
  }
485
405
  function toQuiverAIImageReference(image) {
486
- if (image.type === "url") {
487
- return { url: image.url };
488
- }
489
- return {
490
- base64: typeof image.data === "string" ? image.data : convertUint8ArrayToBase642(image.data)
491
- };
406
+ if (image.type === "url") return { url: image.url };
407
+ return { base64: typeof image.data === "string" ? image.data : convertUint8ArrayToBase64(image.data) };
492
408
  }
493
- var maxAnimationSourceBase64Length = 1066668;
409
+ const maxAnimationSourceBase64Length = 1066668;
494
410
  function toQuiverAIAnimationSource(image) {
495
- if (image.type === "url") {
496
- let url;
497
- try {
498
- url = new URL(image.url);
499
- } catch {
500
- throw new InvalidArgumentError3({
501
- argument: "files",
502
- message: "QuiverAI animate requires a valid HTTP or HTTPS SVG URL."
503
- });
504
- }
505
- if (url.protocol !== "http:" && url.protocol !== "https:") {
506
- throw new InvalidArgumentError3({
507
- argument: "files",
508
- message: "QuiverAI animate requires an HTTP or HTTPS SVG URL."
509
- });
510
- }
511
- return { url: image.url };
512
- }
513
- let base64;
514
- let bytes;
515
- if (typeof image.data === "string") {
516
- const dataUrlMatch = /^data:image\/svg\+xml(?:;[^,]*)?;base64,([\s\S]+)$/i.exec(image.data);
517
- const encodedData = dataUrlMatch?.[1] ?? image.data;
518
- try {
519
- bytes = convertBase64ToUint8Array2(encodedData);
520
- } catch {
521
- throw new InvalidArgumentError3({
522
- argument: "files",
523
- message: "QuiverAI animate requires the source SVG string to be valid base64 or an SVG data URL."
524
- });
525
- }
526
- base64 = convertUint8ArrayToBase642(bytes);
527
- } else {
528
- bytes = image.data;
529
- base64 = convertUint8ArrayToBase642(bytes);
530
- }
531
- if (!isSvg2(bytes)) {
532
- throw new InvalidArgumentError3({
533
- argument: "files",
534
- message: "QuiverAI animate requires the input file to contain SVG data."
535
- });
536
- }
537
- if (base64.length > maxAnimationSourceBase64Length) {
538
- throw new InvalidArgumentError3({
539
- argument: "files",
540
- message: `QuiverAI animate accepts at most ${maxAnimationSourceBase64Length} base64 characters for the source SVG.`
541
- });
542
- }
543
- return { base64 };
411
+ if (image.type === "url") {
412
+ let url;
413
+ try {
414
+ url = new URL(image.url);
415
+ } catch {
416
+ throw new InvalidArgumentError({
417
+ argument: "files",
418
+ message: "QuiverAI animate requires a valid HTTP or HTTPS SVG URL."
419
+ });
420
+ }
421
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new InvalidArgumentError({
422
+ argument: "files",
423
+ message: "QuiverAI animate requires an HTTP or HTTPS SVG URL."
424
+ });
425
+ return { url: image.url };
426
+ }
427
+ let base64;
428
+ let bytes;
429
+ if (typeof image.data === "string") {
430
+ const encodedData = /^data:image\/svg\+xml(?:;[^,]*)?;base64,([\s\S]+)$/i.exec(image.data)?.[1] ?? image.data;
431
+ try {
432
+ bytes = convertBase64ToUint8Array(encodedData);
433
+ } catch {
434
+ throw new InvalidArgumentError({
435
+ argument: "files",
436
+ message: "QuiverAI animate requires the source SVG string to be valid base64 or an SVG data URL."
437
+ });
438
+ }
439
+ base64 = convertUint8ArrayToBase64(bytes);
440
+ } else {
441
+ bytes = image.data;
442
+ base64 = convertUint8ArrayToBase64(bytes);
443
+ }
444
+ if (!isSvg(bytes)) throw new InvalidArgumentError({
445
+ argument: "files",
446
+ message: "QuiverAI animate requires the input file to contain SVG data."
447
+ });
448
+ if (base64.length > maxAnimationSourceBase64Length) throw new InvalidArgumentError({
449
+ argument: "files",
450
+ message: `QuiverAI animate accepts at most ${maxAnimationSourceBase64Length} base64 characters for the source SVG.`
451
+ });
452
+ return { base64 };
544
453
  }
545
- function isSvg2(data) {
546
- const head = new TextDecoder("utf-8", { fatal: false }).decode(data.subarray(0, 4096)).trimStart();
547
- return /^(?:(?:<\?xml[\s\S]*?\?>|<!--[\s\S]*?-->|<!DOCTYPE[\s\S]*?>)\s*)*<svg(?:\s|>)/i.test(
548
- head
549
- );
454
+ function isSvg(data) {
455
+ const head = new TextDecoder("utf-8", { fatal: false }).decode(data.subarray(0, 4096)).trimStart();
456
+ return /^(?:(?:<\?xml[\s\S]*?\?>|<!--[\s\S]*?-->|<!DOCTYPE[\s\S]*?>)\s*)*<svg(?:\s|>)/i.test(head);
550
457
  }
551
- function buildRequestBody({
552
- modelId,
553
- n,
554
- prompt,
555
- files,
556
- mask,
557
- operation,
558
- options
559
- }) {
560
- if ((modelId === "arrow-2" || modelId === "arrow-2-telos") && options.maxOutputTokens != null && options.maxOutputTokens > 65536) {
561
- throw new InvalidArgumentError3({
562
- argument: "maxOutputTokens",
563
- message: `QuiverAI model "${modelId}" supports at most 65536 output tokens.`
564
- });
565
- }
566
- const sharedOptions = {
567
- temperature: options.temperature,
568
- top_p: options.topP,
569
- presence_penalty: options.presencePenalty,
570
- max_output_tokens: options.maxOutputTokens,
571
- reasoning_effort: options.reasoningEffort,
572
- attributes: options.attributes,
573
- stream: false
574
- };
575
- if (operation !== "edit") {
576
- rejectEditOnlyOptions(operation, options);
577
- }
578
- if (operation === "generate") {
579
- if (prompt == null || prompt.trim().length === 0) {
580
- throw new InvalidArgumentError3({
581
- argument: "prompt",
582
- message: "QuiverAI image generation requires a non-empty prompt for generateImage."
583
- });
584
- }
585
- const references = files?.map(toQuiverAIImageReference);
586
- const maxReferences = getGenerateReferenceLimit(modelId);
587
- if (references != null && references.length > maxReferences) {
588
- throw new InvalidArgumentError3({
589
- argument: "files",
590
- message: `QuiverAI generate supports up to ${maxReferences} reference images for model "${modelId}".`
591
- });
592
- }
593
- return {
594
- model: modelId,
595
- n,
596
- prompt,
597
- ...sharedOptions,
598
- instructions: options.instructions,
599
- references
600
- };
601
- }
602
- if (operation === "edit") {
603
- return buildEditRequestBody({
604
- modelId,
605
- n,
606
- prompt,
607
- files,
608
- mask,
609
- options
610
- });
611
- }
612
- if (operation === "animate") {
613
- return buildAnimationRequestBody({
614
- modelId,
615
- n,
616
- prompt,
617
- files,
618
- mask,
619
- options
620
- });
621
- }
622
- if (files == null || files.length === 0) {
623
- throw new InvalidArgumentError3({
624
- argument: "files",
625
- message: 'QuiverAI vectorize requires an input image. Pass an image in the generateImage prompt and set providerOptions.quiverai.operation to "vectorize".'
626
- });
627
- }
628
- if (files.length > 1) {
629
- throw new InvalidArgumentError3({
630
- argument: "files",
631
- message: "QuiverAI vectorize accepts a single input image."
632
- });
633
- }
634
- if (n !== 1) {
635
- throw new InvalidArgumentError3({
636
- argument: "n",
637
- message: "QuiverAI vectorize returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to vectorize multiple times."
638
- });
639
- }
640
- return {
641
- model: modelId,
642
- image: toQuiverAIImageReference(files[0]),
643
- ...sharedOptions,
644
- auto_crop: options.autoCrop,
645
- target_size: options.targetSize
646
- };
458
+ function buildRequestBody({ modelId, n, prompt, files, mask, operation, options }) {
459
+ if ((modelId === "arrow-2" || modelId === "arrow-2-telos") && options.maxOutputTokens != null && options.maxOutputTokens > 65536) throw new InvalidArgumentError({
460
+ argument: "maxOutputTokens",
461
+ message: `QuiverAI model "${modelId}" supports at most 65536 output tokens.`
462
+ });
463
+ const sharedOptions = {
464
+ temperature: options.temperature,
465
+ top_p: options.topP,
466
+ presence_penalty: options.presencePenalty,
467
+ max_output_tokens: options.maxOutputTokens,
468
+ reasoning_effort: options.reasoningEffort,
469
+ attributes: options.attributes,
470
+ stream: false
471
+ };
472
+ if (operation !== "edit") rejectEditOnlyOptions(operation, options);
473
+ if (operation === "generate") {
474
+ if (prompt == null || prompt.trim().length === 0) throw new InvalidArgumentError({
475
+ argument: "prompt",
476
+ message: "QuiverAI image generation requires a non-empty prompt for generateImage."
477
+ });
478
+ const references = files?.map(toQuiverAIImageReference);
479
+ const maxReferences = getGenerateReferenceLimit(modelId);
480
+ if (references != null && references.length > maxReferences) throw new InvalidArgumentError({
481
+ argument: "files",
482
+ message: `QuiverAI generate supports up to ${maxReferences} reference images for model "${modelId}".`
483
+ });
484
+ return {
485
+ model: modelId,
486
+ n,
487
+ prompt,
488
+ ...sharedOptions,
489
+ instructions: options.instructions,
490
+ references
491
+ };
492
+ }
493
+ if (operation === "edit") return buildEditRequestBody({
494
+ modelId,
495
+ n,
496
+ prompt,
497
+ files,
498
+ mask,
499
+ options
500
+ });
501
+ if (operation === "animate") return buildAnimationRequestBody({
502
+ modelId,
503
+ n,
504
+ prompt,
505
+ files,
506
+ mask,
507
+ options
508
+ });
509
+ if (files == null || files.length === 0) throw new InvalidArgumentError({
510
+ argument: "files",
511
+ message: "QuiverAI vectorize requires an input image. Pass an image in the generateImage prompt and set providerOptions.quiverai.operation to \"vectorize\"."
512
+ });
513
+ if (files.length > 1) throw new InvalidArgumentError({
514
+ argument: "files",
515
+ message: "QuiverAI vectorize accepts a single input image."
516
+ });
517
+ if (n !== 1) throw new InvalidArgumentError({
518
+ argument: "n",
519
+ message: "QuiverAI vectorize returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to vectorize multiple times."
520
+ });
521
+ return {
522
+ model: modelId,
523
+ image: toQuiverAIImageReference(files[0]),
524
+ ...sharedOptions,
525
+ auto_crop: options.autoCrop,
526
+ target_size: options.targetSize
527
+ };
647
528
  }
648
- function buildAnimationRequestBody({
649
- modelId,
650
- n,
651
- prompt,
652
- files,
653
- mask,
654
- options
655
- }) {
656
- if (modelId !== "arrow-2" && modelId !== "arrow-2-telos") {
657
- throw new InvalidArgumentError3({
658
- argument: "modelId",
659
- message: 'QuiverAI animate is supported by the "arrow-2" and "arrow-2-telos" models.'
660
- });
661
- }
662
- if (files == null || files.length === 0) {
663
- throw new InvalidArgumentError3({
664
- argument: "files",
665
- message: "QuiverAI animate requires exactly one source SVG in prompt.images."
666
- });
667
- }
668
- if (files.length !== 1) {
669
- throw new InvalidArgumentError3({
670
- argument: "files",
671
- message: "QuiverAI animate accepts exactly one source SVG in prompt.images."
672
- });
673
- }
674
- if (n !== 1) {
675
- throw new InvalidArgumentError3({
676
- argument: "n",
677
- message: "QuiverAI animate returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to animate multiple times."
678
- });
679
- }
680
- if (mask != null) {
681
- throw new InvalidArgumentError3({
682
- argument: "mask",
683
- message: "QuiverAI animate does not support masks."
684
- });
685
- }
686
- if (prompt != null && prompt.trim().length === 0) {
687
- throw new InvalidArgumentError3({
688
- argument: "prompt",
689
- message: "QuiverAI animate requires a non-empty prompt when an animation instruction is provided."
690
- });
691
- }
692
- const unsupportedOptions = [
693
- ["instructions", options.instructions],
694
- ["topP", options.topP],
695
- ["presencePenalty", options.presencePenalty],
696
- ["attributes", options.attributes],
697
- ["autoCrop", options.autoCrop],
698
- ["targetSize", options.targetSize]
699
- ].filter((option) => {
700
- return option[1] !== void 0;
701
- });
702
- if (unsupportedOptions.length > 0) {
703
- throw new InvalidArgumentError3({
704
- argument: `providerOptions.quiverai.${unsupportedOptions[0][0]}`,
705
- message: `QuiverAI animate does not support providerOptions.quiverai.${unsupportedOptions[0][0]}.`
706
- });
707
- }
708
- return {
709
- model: modelId,
710
- svg_source: toQuiverAIAnimationSource(files[0]),
711
- prompt,
712
- temperature: options.temperature,
713
- max_output_tokens: options.maxOutputTokens,
714
- reasoning_effort: options.reasoningEffort,
715
- stream: false
716
- };
529
+ function buildAnimationRequestBody({ modelId, n, prompt, files, mask, options }) {
530
+ if (modelId !== "arrow-2" && modelId !== "arrow-2-telos") throw new InvalidArgumentError({
531
+ argument: "modelId",
532
+ message: "QuiverAI animate is supported by the \"arrow-2\" and \"arrow-2-telos\" models."
533
+ });
534
+ if (files == null || files.length === 0) throw new InvalidArgumentError({
535
+ argument: "files",
536
+ message: "QuiverAI animate requires exactly one source SVG in prompt.images."
537
+ });
538
+ if (files.length !== 1) throw new InvalidArgumentError({
539
+ argument: "files",
540
+ message: "QuiverAI animate accepts exactly one source SVG in prompt.images."
541
+ });
542
+ if (n !== 1) throw new InvalidArgumentError({
543
+ argument: "n",
544
+ message: "QuiverAI animate returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to animate multiple times."
545
+ });
546
+ if (mask != null) throw new InvalidArgumentError({
547
+ argument: "mask",
548
+ message: "QuiverAI animate does not support masks."
549
+ });
550
+ if (prompt != null && prompt.trim().length === 0) throw new InvalidArgumentError({
551
+ argument: "prompt",
552
+ message: "QuiverAI animate requires a non-empty prompt when an animation instruction is provided."
553
+ });
554
+ const unsupportedOptions = [
555
+ ["instructions", options.instructions],
556
+ ["topP", options.topP],
557
+ ["presencePenalty", options.presencePenalty],
558
+ ["attributes", options.attributes],
559
+ ["autoCrop", options.autoCrop],
560
+ ["targetSize", options.targetSize]
561
+ ].filter((option) => {
562
+ return option[1] !== void 0;
563
+ });
564
+ if (unsupportedOptions.length > 0) throw new InvalidArgumentError({
565
+ argument: `providerOptions.quiverai.${unsupportedOptions[0][0]}`,
566
+ message: `QuiverAI animate does not support providerOptions.quiverai.${unsupportedOptions[0][0]}.`
567
+ });
568
+ return {
569
+ model: modelId,
570
+ svg_source: toQuiverAIAnimationSource(files[0]),
571
+ prompt,
572
+ temperature: options.temperature,
573
+ max_output_tokens: options.maxOutputTokens,
574
+ reasoning_effort: options.reasoningEffort,
575
+ stream: false
576
+ };
717
577
  }
718
- var editModelIds = /* @__PURE__ */ new Set(["arrow-2", "arrow-2-telos"]);
719
- var MAX_EDIT_SVG_BYTES = 2e5;
720
- function buildEditRequestBody({
721
- modelId,
722
- n,
723
- prompt,
724
- files,
725
- mask,
726
- options
727
- }) {
728
- if (!editModelIds.has(modelId)) {
729
- throw new InvalidArgumentError3({
730
- argument: "modelId",
731
- message: 'QuiverAI SVG editing is supported by the "arrow-2" and "arrow-2-telos" models.'
732
- });
733
- }
734
- if (prompt == null || prompt.trim().length === 0) {
735
- throw new InvalidArgumentError3({
736
- argument: "prompt",
737
- message: "QuiverAI SVG editing requires a non-empty instruction in generateImage prompt.text."
738
- });
739
- }
740
- if (prompt.length > 4e3) {
741
- throw new InvalidArgumentError3({
742
- argument: "prompt",
743
- message: "QuiverAI SVG editing instructions must contain at most 4000 characters."
744
- });
745
- }
746
- if (files == null || files.length === 0) {
747
- throw new InvalidArgumentError3({
748
- argument: "files",
749
- message: "QuiverAI SVG editing requires one source SVG in generateImage prompt.images."
750
- });
751
- }
752
- if (files.length !== 1) {
753
- throw new InvalidArgumentError3({
754
- argument: "files",
755
- message: "QuiverAI SVG editing accepts exactly one source SVG."
756
- });
757
- }
758
- if (n !== 1) {
759
- throw new InvalidArgumentError3({
760
- argument: "n",
761
- message: "QuiverAI SVG editing returns exactly one SVG per request. Set maxImagesPerCall to 1 in generateImage to edit multiple times."
762
- });
763
- }
764
- if (mask != null) {
765
- throw new InvalidArgumentError3({
766
- argument: "mask",
767
- message: "QuiverAI SVG editing does not support masks."
768
- });
769
- }
770
- const unsupportedOptions = [
771
- ["instructions", options.instructions],
772
- ["attributes", options.attributes],
773
- ["topP", options.topP],
774
- ["presencePenalty", options.presencePenalty],
775
- ["autoCrop", options.autoCrop],
776
- ["targetSize", options.targetSize]
777
- ].flatMap(([name, value]) => value == null ? [] : [name]);
778
- if (unsupportedOptions.length > 0) {
779
- throw new InvalidArgumentError3({
780
- argument: "providerOptions",
781
- message: `QuiverAI SVG editing does not support these provider options: ${unsupportedOptions.join(
782
- ", "
783
- )}.`
784
- });
785
- }
786
- const referenceImages = options.referenceImages?.map((reference, index) => {
787
- if ("url" in reference) {
788
- return {
789
- url: validateQuiverAIImageUrl(reference.url)
790
- };
791
- }
792
- validateQuiverAIReferenceBase64(
793
- reference.base64,
794
- `providerOptions.quiverai.referenceImages[${index}]`
795
- );
796
- return { base64: reference.base64 };
797
- });
798
- const settings = {
799
- max_output_tokens: options.maxOutputTokens,
800
- orchestrator_max_output_tokens: options.orchestratorMaxOutputTokens,
801
- shallow_max_output_tokens: options.shallowMaxOutputTokens,
802
- temperature: options.temperature
803
- };
804
- const hasSettings = Object.values(settings).some((value) => value != null);
805
- return {
806
- model: modelId,
807
- prompt,
808
- ...toQuiverAIEditSource(files[0]),
809
- reference_images: referenceImages,
810
- max_review_steps: options.maxReviewSteps,
811
- reasoning_effort: options.reasoningEffort,
812
- ...hasSettings && { settings },
813
- stream: false
814
- };
578
+ const editModelIds = /* @__PURE__ */ new Set(["arrow-2", "arrow-2-telos"]);
579
+ const MAX_EDIT_SVG_BYTES = 2e5;
580
+ function buildEditRequestBody({ modelId, n, prompt, files, mask, options }) {
581
+ if (!editModelIds.has(modelId)) throw new InvalidArgumentError({
582
+ argument: "modelId",
583
+ message: "QuiverAI SVG editing is supported by the \"arrow-2\" and \"arrow-2-telos\" models."
584
+ });
585
+ if (prompt == null || prompt.trim().length === 0) throw new InvalidArgumentError({
586
+ argument: "prompt",
587
+ message: "QuiverAI SVG editing requires a non-empty instruction in generateImage prompt.text."
588
+ });
589
+ if (prompt.length > 4e3) throw new InvalidArgumentError({
590
+ argument: "prompt",
591
+ message: "QuiverAI SVG editing instructions must contain at most 4000 characters."
592
+ });
593
+ if (files == null || files.length === 0) throw new InvalidArgumentError({
594
+ argument: "files",
595
+ message: "QuiverAI SVG editing requires one source SVG in generateImage prompt.images."
596
+ });
597
+ if (files.length !== 1) throw new InvalidArgumentError({
598
+ argument: "files",
599
+ message: "QuiverAI SVG editing accepts exactly one source SVG."
600
+ });
601
+ if (n !== 1) throw new InvalidArgumentError({
602
+ argument: "n",
603
+ message: "QuiverAI SVG editing returns exactly one SVG per request. Set maxImagesPerCall to 1 in generateImage to edit multiple times."
604
+ });
605
+ if (mask != null) throw new InvalidArgumentError({
606
+ argument: "mask",
607
+ message: "QuiverAI SVG editing does not support masks."
608
+ });
609
+ const unsupportedOptions = [
610
+ ["instructions", options.instructions],
611
+ ["attributes", options.attributes],
612
+ ["topP", options.topP],
613
+ ["presencePenalty", options.presencePenalty],
614
+ ["autoCrop", options.autoCrop],
615
+ ["targetSize", options.targetSize]
616
+ ].flatMap(([name, value]) => value == null ? [] : [name]);
617
+ if (unsupportedOptions.length > 0) throw new InvalidArgumentError({
618
+ argument: "providerOptions",
619
+ message: `QuiverAI SVG editing does not support these provider options: ${unsupportedOptions.join(", ")}.`
620
+ });
621
+ const referenceImages = options.referenceImages?.map((reference, index) => {
622
+ if ("url" in reference) return { url: validateQuiverAIImageUrl(reference.url) };
623
+ validateQuiverAIReferenceBase64(reference.base64, `providerOptions.quiverai.referenceImages[${index}]`);
624
+ return { base64: reference.base64 };
625
+ });
626
+ const settings = {
627
+ max_output_tokens: options.maxOutputTokens,
628
+ orchestrator_max_output_tokens: options.orchestratorMaxOutputTokens,
629
+ shallow_max_output_tokens: options.shallowMaxOutputTokens,
630
+ temperature: options.temperature
631
+ };
632
+ const hasSettings = Object.values(settings).some((value) => value != null);
633
+ return {
634
+ model: modelId,
635
+ prompt,
636
+ ...toQuiverAIEditSource(files[0]),
637
+ reference_images: referenceImages,
638
+ max_review_steps: options.maxReviewSteps,
639
+ reasoning_effort: options.reasoningEffort,
640
+ ...hasSettings && { settings },
641
+ stream: false
642
+ };
815
643
  }
816
644
  function rejectEditOnlyOptions(operation, options) {
817
- const editOnlyOptions = [
818
- ["referenceImages", options.referenceImages],
819
- ["maxReviewSteps", options.maxReviewSteps],
820
- ["orchestratorMaxOutputTokens", options.orchestratorMaxOutputTokens],
821
- ["shallowMaxOutputTokens", options.shallowMaxOutputTokens]
822
- ].flatMap(([name, value]) => value == null ? [] : [name]);
823
- if (editOnlyOptions.length > 0) {
824
- throw new InvalidArgumentError3({
825
- argument: "providerOptions",
826
- message: `QuiverAI ${operation} does not support these edit-only provider options: ${editOnlyOptions.join(
827
- ", "
828
- )}.`
829
- });
830
- }
645
+ const editOnlyOptions = [
646
+ ["referenceImages", options.referenceImages],
647
+ ["maxReviewSteps", options.maxReviewSteps],
648
+ ["orchestratorMaxOutputTokens", options.orchestratorMaxOutputTokens],
649
+ ["shallowMaxOutputTokens", options.shallowMaxOutputTokens]
650
+ ].flatMap(([name, value]) => value == null ? [] : [name]);
651
+ if (editOnlyOptions.length > 0) throw new InvalidArgumentError({
652
+ argument: "providerOptions",
653
+ message: `QuiverAI ${operation} does not support these edit-only provider options: ${editOnlyOptions.join(", ")}.`
654
+ });
831
655
  }
832
656
  function toQuiverAIEditSource(file) {
833
- if (file.type === "url") {
834
- return {
835
- svg_source: {
836
- url: validateQuiverAIImageUrl(file.url)
837
- }
838
- };
839
- }
840
- let data;
841
- try {
842
- data = typeof file.data === "string" ? convertBase64ToUint8Array2(file.data) : file.data;
843
- } catch (cause) {
844
- throw new InvalidArgumentError3({
845
- argument: "files",
846
- message: "QuiverAI SVG source data must be valid base64 or binary data.",
847
- cause
848
- });
849
- }
850
- if (data.length === 0 || data.length > MAX_EDIT_SVG_BYTES) {
851
- throw new InvalidArgumentError3({
852
- argument: "files",
853
- message: `QuiverAI SVG source data must contain 1-${MAX_EDIT_SVG_BYTES} bytes.`
854
- });
855
- }
856
- let svg;
857
- try {
858
- svg = new TextDecoder("utf-8", { fatal: true }).decode(data);
859
- } catch (cause) {
860
- throw new InvalidArgumentError3({
861
- argument: "files",
862
- message: "QuiverAI SVG source data must be valid UTF-8.",
863
- cause
864
- });
865
- }
866
- if (svg.length > MAX_EDIT_SVG_BYTES || !isSvgMarkup(svg)) {
867
- throw new InvalidArgumentError3({
868
- argument: "files",
869
- message: "QuiverAI SVG source data must contain a complete SVG document."
870
- });
871
- }
872
- return {
873
- svg_source: {
874
- base64: convertUint8ArrayToBase642(data)
875
- }
876
- };
657
+ if (file.type === "url") return { svg_source: { url: validateQuiverAIImageUrl(file.url) } };
658
+ let data;
659
+ try {
660
+ data = typeof file.data === "string" ? convertBase64ToUint8Array(file.data) : file.data;
661
+ } catch (cause) {
662
+ throw new InvalidArgumentError({
663
+ argument: "files",
664
+ message: "QuiverAI SVG source data must be valid base64 or binary data.",
665
+ cause
666
+ });
667
+ }
668
+ if (data.length === 0 || data.length > MAX_EDIT_SVG_BYTES) throw new InvalidArgumentError({
669
+ argument: "files",
670
+ message: `QuiverAI SVG source data must contain 1-${MAX_EDIT_SVG_BYTES} bytes.`
671
+ });
672
+ let svg;
673
+ try {
674
+ svg = new TextDecoder("utf-8", { fatal: true }).decode(data);
675
+ } catch (cause) {
676
+ throw new InvalidArgumentError({
677
+ argument: "files",
678
+ message: "QuiverAI SVG source data must be valid UTF-8.",
679
+ cause
680
+ });
681
+ }
682
+ if (svg.length > MAX_EDIT_SVG_BYTES || !isSvgMarkup(svg)) throw new InvalidArgumentError({
683
+ argument: "files",
684
+ message: "QuiverAI SVG source data must contain a complete SVG document."
685
+ });
686
+ return { svg_source: { base64: convertUint8ArrayToBase64(data) } };
877
687
  }
878
688
  function isSvgMarkup(svg) {
879
- const document = svg.replace(/^\uFEFF/, "");
880
- const elements = [];
881
- let position = 0;
882
- let rootSeen = false;
883
- let rootClosed = false;
884
- let doctypeSeen = false;
885
- while (position < document.length) {
886
- if (document[position] !== "<") {
887
- const nextTag = document.indexOf("<", position);
888
- const end = nextTag === -1 ? document.length : nextTag;
889
- const text = document.slice(position, end);
890
- if (elements.length === 0 && text.trim().length > 0 || text.includes("]]>") || !hasValidXmlReferences(text)) {
891
- return false;
892
- }
893
- position = end;
894
- continue;
895
- }
896
- if (document.startsWith("<!--", position)) {
897
- const commentEnd = document.indexOf("-->", position + 4);
898
- if (commentEnd === -1 || document.slice(position + 4, commentEnd).includes("--")) {
899
- return false;
900
- }
901
- position = commentEnd + 3;
902
- continue;
903
- }
904
- if (document.startsWith("<?", position)) {
905
- const instructionEnd = document.indexOf("?>", position + 2);
906
- if (instructionEnd === -1) {
907
- return false;
908
- }
909
- position = instructionEnd + 2;
910
- continue;
911
- }
912
- if (document.startsWith("<![CDATA[", position)) {
913
- if (elements.length === 0) {
914
- return false;
915
- }
916
- const cdataEnd = document.indexOf("]]>", position + 9);
917
- if (cdataEnd === -1) {
918
- return false;
919
- }
920
- position = cdataEnd + 3;
921
- continue;
922
- }
923
- if (document.slice(position, position + 9).toUpperCase() === "<!DOCTYPE") {
924
- if (rootSeen || doctypeSeen || elements.length > 0 || !/[\t\n\r ]/.test(document[position + 9] ?? "")) {
925
- return false;
926
- }
927
- const doctypeName = readXmlName(
928
- document,
929
- skipXmlWhitespace(document, position + 9)
930
- );
931
- if (doctypeName?.name.toLowerCase() !== "svg") {
932
- return false;
933
- }
934
- const doctypeEnd = findDoctypeEnd(document, doctypeName.end);
935
- if (doctypeEnd === -1) {
936
- return false;
937
- }
938
- doctypeSeen = true;
939
- position = doctypeEnd;
940
- continue;
941
- }
942
- if (document.startsWith("<!", position)) {
943
- return false;
944
- }
945
- if (document.startsWith("</", position)) {
946
- const closingTag = readXmlName(document, position + 2);
947
- if (closingTag == null) {
948
- return false;
949
- }
950
- let tagEnd = skipXmlWhitespace(document, closingTag.end);
951
- if (document[tagEnd] !== ">") {
952
- return false;
953
- }
954
- const expectedTag = elements.pop();
955
- if (expectedTag !== closingTag.name) {
956
- return false;
957
- }
958
- tagEnd += 1;
959
- if (elements.length === 0) {
960
- rootClosed = true;
961
- }
962
- position = tagEnd;
963
- continue;
964
- }
965
- if (rootClosed) {
966
- return false;
967
- }
968
- const openingTag = readXmlName(document, position + 1);
969
- if (openingTag == null) {
970
- return false;
971
- }
972
- if (!rootSeen) {
973
- if (openingTag.name.toLowerCase() !== "svg") {
974
- return false;
975
- }
976
- rootSeen = true;
977
- }
978
- const attributes = /* @__PURE__ */ new Set();
979
- let tagPosition = openingTag.end;
980
- while (tagPosition < document.length) {
981
- const beforeWhitespace = tagPosition;
982
- tagPosition = skipXmlWhitespace(document, tagPosition);
983
- if (document.startsWith("/>", tagPosition)) {
984
- tagPosition += 2;
985
- if (elements.length === 0) {
986
- rootClosed = true;
987
- }
988
- position = tagPosition;
989
- break;
990
- }
991
- if (document[tagPosition] === ">") {
992
- elements.push(openingTag.name);
993
- position = tagPosition + 1;
994
- break;
995
- }
996
- if (tagPosition === beforeWhitespace) {
997
- return false;
998
- }
999
- const attribute = readXmlName(document, tagPosition);
1000
- if (attribute == null || attributes.has(attribute.name)) {
1001
- return false;
1002
- }
1003
- attributes.add(attribute.name);
1004
- tagPosition = skipXmlWhitespace(document, attribute.end);
1005
- if (document[tagPosition] !== "=") {
1006
- return false;
1007
- }
1008
- tagPosition = skipXmlWhitespace(document, tagPosition + 1);
1009
- const quote = document[tagPosition];
1010
- if (quote !== '"' && quote !== "'") {
1011
- return false;
1012
- }
1013
- const valueEnd = document.indexOf(quote, tagPosition + 1);
1014
- if (valueEnd === -1 || document.slice(tagPosition + 1, valueEnd).includes("<") || !hasValidXmlReferences(document.slice(tagPosition + 1, valueEnd))) {
1015
- return false;
1016
- }
1017
- tagPosition = valueEnd + 1;
1018
- }
1019
- if (tagPosition >= document.length && position !== document.length) {
1020
- return false;
1021
- }
1022
- }
1023
- return rootSeen && rootClosed && elements.length === 0;
689
+ const document = svg.replace(/^\uFEFF/, "");
690
+ const elements = [];
691
+ let position = 0;
692
+ let rootSeen = false;
693
+ let rootClosed = false;
694
+ let doctypeSeen = false;
695
+ while (position < document.length) {
696
+ if (document[position] !== "<") {
697
+ const nextTag = document.indexOf("<", position);
698
+ const end = nextTag === -1 ? document.length : nextTag;
699
+ const text = document.slice(position, end);
700
+ if (elements.length === 0 && text.trim().length > 0 || text.includes("]]>") || !hasValidXmlReferences(text)) return false;
701
+ position = end;
702
+ continue;
703
+ }
704
+ if (document.startsWith("<!--", position)) {
705
+ const commentEnd = document.indexOf("-->", position + 4);
706
+ if (commentEnd === -1 || document.slice(position + 4, commentEnd).includes("--")) return false;
707
+ position = commentEnd + 3;
708
+ continue;
709
+ }
710
+ if (document.startsWith("<?", position)) {
711
+ const instructionEnd = document.indexOf("?>", position + 2);
712
+ if (instructionEnd === -1) return false;
713
+ position = instructionEnd + 2;
714
+ continue;
715
+ }
716
+ if (document.startsWith("<![CDATA[", position)) {
717
+ if (elements.length === 0) return false;
718
+ const cdataEnd = document.indexOf("]]>", position + 9);
719
+ if (cdataEnd === -1) return false;
720
+ position = cdataEnd + 3;
721
+ continue;
722
+ }
723
+ if (document.slice(position, position + 9).toUpperCase() === "<!DOCTYPE") {
724
+ if (rootSeen || doctypeSeen || elements.length > 0 || !/[\t\n\r ]/.test(document[position + 9] ?? "")) return false;
725
+ const doctypeName = readXmlName(document, skipXmlWhitespace(document, position + 9));
726
+ if (doctypeName?.name.toLowerCase() !== "svg") return false;
727
+ const doctypeEnd = findDoctypeEnd(document, doctypeName.end);
728
+ if (doctypeEnd === -1) return false;
729
+ doctypeSeen = true;
730
+ position = doctypeEnd;
731
+ continue;
732
+ }
733
+ if (document.startsWith("<!", position)) return false;
734
+ if (document.startsWith("</", position)) {
735
+ const closingTag = readXmlName(document, position + 2);
736
+ if (closingTag == null) return false;
737
+ let tagEnd = skipXmlWhitespace(document, closingTag.end);
738
+ if (document[tagEnd] !== ">") return false;
739
+ if (elements.pop() !== closingTag.name) return false;
740
+ tagEnd += 1;
741
+ if (elements.length === 0) rootClosed = true;
742
+ position = tagEnd;
743
+ continue;
744
+ }
745
+ if (rootClosed) return false;
746
+ const openingTag = readXmlName(document, position + 1);
747
+ if (openingTag == null) return false;
748
+ if (!rootSeen) {
749
+ if (openingTag.name.toLowerCase() !== "svg") return false;
750
+ rootSeen = true;
751
+ }
752
+ const attributes = /* @__PURE__ */ new Set();
753
+ let tagPosition = openingTag.end;
754
+ while (tagPosition < document.length) {
755
+ const beforeWhitespace = tagPosition;
756
+ tagPosition = skipXmlWhitespace(document, tagPosition);
757
+ if (document.startsWith("/>", tagPosition)) {
758
+ tagPosition += 2;
759
+ if (elements.length === 0) rootClosed = true;
760
+ position = tagPosition;
761
+ break;
762
+ }
763
+ if (document[tagPosition] === ">") {
764
+ elements.push(openingTag.name);
765
+ position = tagPosition + 1;
766
+ break;
767
+ }
768
+ if (tagPosition === beforeWhitespace) return false;
769
+ const attribute = readXmlName(document, tagPosition);
770
+ if (attribute == null || attributes.has(attribute.name)) return false;
771
+ attributes.add(attribute.name);
772
+ tagPosition = skipXmlWhitespace(document, attribute.end);
773
+ if (document[tagPosition] !== "=") return false;
774
+ tagPosition = skipXmlWhitespace(document, tagPosition + 1);
775
+ const quote = document[tagPosition];
776
+ if (quote !== "\"" && quote !== "'") return false;
777
+ const valueEnd = document.indexOf(quote, tagPosition + 1);
778
+ if (valueEnd === -1 || document.slice(tagPosition + 1, valueEnd).includes("<") || !hasValidXmlReferences(document.slice(tagPosition + 1, valueEnd))) return false;
779
+ tagPosition = valueEnd + 1;
780
+ }
781
+ if (tagPosition >= document.length && position !== document.length) return false;
782
+ }
783
+ return rootSeen && rootClosed && elements.length === 0;
1024
784
  }
1025
785
  function isXmlNameStart(character) {
1026
- return character != null && /[A-Z_a-z:\u0080-\uFFFF]/.test(character);
786
+ return character != null && /[A-Z_a-z:\u0080-\uFFFF]/.test(character);
1027
787
  }
1028
788
  function isXmlNameCharacter(character) {
1029
- return character != null && /[-.0-9A-Z_a-z:\u00B7\u0080-\uFFFF]/.test(character);
789
+ return character != null && /[-.0-9A-Z_a-z:\u00B7\u0080-\uFFFF]/.test(character);
1030
790
  }
1031
791
  function readXmlName(value, position) {
1032
- if (!isXmlNameStart(value[position])) {
1033
- return void 0;
1034
- }
1035
- const start = position;
1036
- position += 1;
1037
- while (isXmlNameCharacter(value[position])) {
1038
- position += 1;
1039
- }
1040
- return {
1041
- name: value.slice(start, position),
1042
- end: position
1043
- };
792
+ if (!isXmlNameStart(value[position])) return;
793
+ const start = position;
794
+ position += 1;
795
+ while (isXmlNameCharacter(value[position])) position += 1;
796
+ return {
797
+ name: value.slice(start, position),
798
+ end: position
799
+ };
1044
800
  }
1045
801
  function skipXmlWhitespace(value, position) {
1046
- while (/[\t\n\r ]/.test(value[position] ?? "")) {
1047
- position += 1;
1048
- }
1049
- return position;
802
+ while (/[\t\n\r ]/.test(value[position] ?? "")) position += 1;
803
+ return position;
1050
804
  }
1051
805
  function hasValidXmlReferences(value) {
1052
- let position = value.indexOf("&");
1053
- while (position !== -1) {
1054
- const end = value.indexOf(";", position + 1);
1055
- if (end === -1) {
1056
- return false;
1057
- }
1058
- const reference = value.slice(position + 1, end);
1059
- if (!/^#\d+$/.test(reference) && !/^#x[\dA-Fa-f]+$/.test(reference) && !/^[A-Z_a-z:\u0080-\uFFFF][-.0-9A-Z_a-z:\u00B7\u0080-\uFFFF]*$/.test(
1060
- reference
1061
- )) {
1062
- return false;
1063
- }
1064
- position = value.indexOf("&", end + 1);
1065
- }
1066
- return true;
806
+ let position = value.indexOf("&");
807
+ while (position !== -1) {
808
+ const end = value.indexOf(";", position + 1);
809
+ if (end === -1) return false;
810
+ const reference = value.slice(position + 1, end);
811
+ if (!/^#\d+$/.test(reference) && !/^#x[\dA-Fa-f]+$/.test(reference) && !/^[A-Z_a-z:\u0080-\uFFFF][-.0-9A-Z_a-z:\u00B7\u0080-\uFFFF]*$/.test(reference)) return false;
812
+ position = value.indexOf("&", end + 1);
813
+ }
814
+ return true;
1067
815
  }
1068
816
  function findDoctypeEnd(value, position) {
1069
- let subsetDepth = 0;
1070
- let quote;
1071
- while (position < value.length) {
1072
- const character = value[position];
1073
- if (quote != null) {
1074
- if (character === quote) {
1075
- quote = void 0;
1076
- }
1077
- } else if (character === '"' || character === "'") {
1078
- quote = character;
1079
- } else if (character === "[") {
1080
- subsetDepth += 1;
1081
- } else if (character === "]") {
1082
- if (subsetDepth === 0) {
1083
- return -1;
1084
- }
1085
- subsetDepth -= 1;
1086
- } else if (character === ">" && subsetDepth === 0) {
1087
- return position + 1;
1088
- }
1089
- position += 1;
1090
- }
1091
- return -1;
817
+ let subsetDepth = 0;
818
+ let quote;
819
+ while (position < value.length) {
820
+ const character = value[position];
821
+ if (quote != null) {
822
+ if (character === quote) quote = void 0;
823
+ } else if (character === "\"" || character === "'") quote = character;
824
+ else if (character === "[") subsetDepth += 1;
825
+ else if (character === "]") {
826
+ if (subsetDepth === 0) return -1;
827
+ subsetDepth -= 1;
828
+ } else if (character === ">" && subsetDepth === 0) return position + 1;
829
+ position += 1;
830
+ }
831
+ return -1;
1092
832
  }
1093
- function collectWarnings({
1094
- size,
1095
- aspectRatio,
1096
- seed,
1097
- mask
1098
- }) {
1099
- const warnings = [];
1100
- if (size != null) {
1101
- warnings.push({
1102
- type: "unsupported",
1103
- feature: "size",
1104
- details: "QuiverAI SVG generation does not support the `size` option. The setting was ignored."
1105
- });
1106
- }
1107
- if (aspectRatio != null) {
1108
- warnings.push({
1109
- type: "unsupported",
1110
- feature: "aspectRatio",
1111
- details: "QuiverAI SVG generation does not support the `aspectRatio` option. The setting was ignored."
1112
- });
1113
- }
1114
- if (seed != null) {
1115
- warnings.push({
1116
- type: "unsupported",
1117
- feature: "seed",
1118
- details: "QuiverAI SVG generation does not support the `seed` option. The setting was ignored."
1119
- });
1120
- }
1121
- if (mask != null) {
1122
- warnings.push({
1123
- type: "unsupported",
1124
- feature: "mask",
1125
- details: "QuiverAI SVG generation does not support masks. The mask was ignored."
1126
- });
1127
- }
1128
- return warnings;
833
+ function collectWarnings({ size, aspectRatio, seed, mask }) {
834
+ const warnings = [];
835
+ if (size != null) warnings.push({
836
+ type: "unsupported",
837
+ feature: "size",
838
+ details: "QuiverAI SVG generation does not support the `size` option. The setting was ignored."
839
+ });
840
+ if (aspectRatio != null) warnings.push({
841
+ type: "unsupported",
842
+ feature: "aspectRatio",
843
+ details: "QuiverAI SVG generation does not support the `aspectRatio` option. The setting was ignored."
844
+ });
845
+ if (seed != null) warnings.push({
846
+ type: "unsupported",
847
+ feature: "seed",
848
+ details: "QuiverAI SVG generation does not support the `seed` option. The setting was ignored."
849
+ });
850
+ if (mask != null) warnings.push({
851
+ type: "unsupported",
852
+ feature: "mask",
853
+ details: "QuiverAI SVG generation does not support masks. The mask was ignored."
854
+ });
855
+ return warnings;
1129
856
  }
1130
- var svgUsageSchema = z3.object({
1131
- total_tokens: z3.number().int().nonnegative(),
1132
- input_tokens: z3.number().int().nonnegative(),
1133
- output_tokens: z3.number().int().nonnegative()
857
+ const svgUsageSchema = z.object({
858
+ total_tokens: z.number().int().nonnegative(),
859
+ input_tokens: z.number().int().nonnegative(),
860
+ output_tokens: z.number().int().nonnegative()
1134
861
  });
1135
- var svgDocumentSchema = z3.object({
1136
- svg: z3.string().min(1),
1137
- mime_type: z3.literal("image/svg+xml"),
1138
- loop_period_ms: z3.number().int().nonnegative().nullish(),
1139
- opening_animation_ms: z3.number().int().nonnegative().nullish()
862
+ const svgDocumentSchema = z.object({
863
+ svg: z.string().min(1),
864
+ mime_type: z.literal("image/svg+xml"),
865
+ loop_period_ms: z.number().int().nonnegative().nullish(),
866
+ opening_animation_ms: z.number().int().nonnegative().nullish()
1140
867
  });
1141
- var svgGenerationResponseSchema = z3.object({
1142
- id: z3.string().min(1),
1143
- created: z3.number().int().nonnegative(),
1144
- data: z3.array(svgDocumentSchema).min(1),
1145
- usage: svgUsageSchema.nullish(),
1146
- credits: z3.number().int().nonnegative().nullish()
868
+ const svgGenerationResponseSchema = z.object({
869
+ id: z.string().min(1),
870
+ created: z.number().int().nonnegative(),
871
+ data: z.array(svgDocumentSchema).min(1),
872
+ usage: svgUsageSchema.nullish(),
873
+ credits: z.number().int().nonnegative().nullish()
1147
874
  });
1148
-
1149
- // src/version.ts
1150
- var VERSION = true ? "2.0.52" : "0.0.0-test";
1151
-
1152
- // src/quiverai-provider.ts
1153
- var defaultBaseURL = "https://api.quiver.ai/v1";
875
+ //#endregion
876
+ //#region src/version.ts
877
+ const VERSION = "2.0.54";
878
+ //#endregion
879
+ //#region src/quiverai-provider.ts
880
+ const defaultBaseURL = "https://api.quiver.ai/v1";
1154
881
  function createQuiverAI(options = {}) {
1155
- const baseURL = withoutTrailingSlash(
1156
- loadOptionalSetting({
1157
- settingValue: options.baseURL,
1158
- environmentVariableName: "QUIVERAI_BASE_URL"
1159
- })
1160
- ) ?? defaultBaseURL;
1161
- const getHeaders = () => ({
1162
- Authorization: `Bearer ${loadApiKey({
1163
- apiKey: options.apiKey,
1164
- environmentVariableName: "QUIVERAI_API_KEY",
1165
- description: "QuiverAI"
1166
- })}`,
1167
- ...options.headers
1168
- });
1169
- const getImageHeaders = () => withUserAgentSuffix(getHeaders(), `ai-sdk-quiverai/${VERSION}`);
1170
- const responsesConfig = {
1171
- name: "quiverai",
1172
- url: `${baseURL}/responses`,
1173
- headers: getHeaders,
1174
- fetch: options.fetch,
1175
- failedResponseHandler: quiveraiFailedResponseHandler,
1176
- getResponseErrorMetadata: getQuiverAIResponseErrorMetadata,
1177
- strictResponseInput: true,
1178
- customToolId: "quiverai.custom",
1179
- structuredOutputs: false,
1180
- userAgentSuffix: `ai-sdk-quiverai/${VERSION}`
1181
- };
1182
- const responsesProvider = createOpenResponses2(responsesConfig);
1183
- const createLanguageModel = (modelId) => new QuiverAILanguageModel(
1184
- responsesProvider.languageModel(modelId),
1185
- responsesConfig
1186
- );
1187
- const createImageModel = (modelId) => new QuiverAIImageModel(modelId, {
1188
- provider: "quiverai.image",
1189
- baseURL,
1190
- headers: getImageHeaders,
1191
- fetch: options.fetch
1192
- });
1193
- const embeddingModel = (modelId) => {
1194
- throw new NoSuchModelError({
1195
- modelId,
1196
- modelType: "embeddingModel"
1197
- });
1198
- };
1199
- const provider = function(modelId) {
1200
- return createLanguageModel(modelId);
1201
- };
1202
- provider.specificationVersion = "v4";
1203
- provider.languageModel = createLanguageModel;
1204
- provider.image = createImageModel;
1205
- provider.imageModel = createImageModel;
1206
- provider.embeddingModel = embeddingModel;
1207
- provider.textEmbeddingModel = embeddingModel;
1208
- provider.tools = responsesProvider.tools;
1209
- return provider;
882
+ const baseURL = withoutTrailingSlash(loadOptionalSetting({
883
+ settingValue: options.baseURL,
884
+ environmentVariableName: "QUIVERAI_BASE_URL"
885
+ })) ?? defaultBaseURL;
886
+ const getHeaders = () => ({
887
+ Authorization: `Bearer ${loadApiKey({
888
+ apiKey: options.apiKey,
889
+ environmentVariableName: "QUIVERAI_API_KEY",
890
+ description: "QuiverAI"
891
+ })}`,
892
+ ...options.headers
893
+ });
894
+ const getImageHeaders = () => withUserAgentSuffix(getHeaders(), `ai-sdk-quiverai/${VERSION}`);
895
+ const responsesConfig = {
896
+ name: "quiverai",
897
+ url: `${baseURL}/responses`,
898
+ headers: getHeaders,
899
+ fetch: options.fetch,
900
+ failedResponseHandler: quiveraiFailedResponseHandler,
901
+ getResponseErrorMetadata: getQuiverAIResponseErrorMetadata,
902
+ strictResponseInput: true,
903
+ customToolId: "quiverai.custom",
904
+ structuredOutputs: false,
905
+ userAgentSuffix: `ai-sdk-quiverai/${VERSION}`
906
+ };
907
+ const responsesProvider = createOpenResponses(responsesConfig);
908
+ const createLanguageModel = (modelId) => new QuiverAILanguageModel(responsesProvider.languageModel(modelId), responsesConfig);
909
+ const createImageModel = (modelId) => new QuiverAIImageModel(modelId, {
910
+ provider: "quiverai.image",
911
+ baseURL,
912
+ headers: getImageHeaders,
913
+ fetch: options.fetch
914
+ });
915
+ const embeddingModel = (modelId) => {
916
+ throw new NoSuchModelError({
917
+ modelId,
918
+ modelType: "embeddingModel"
919
+ });
920
+ };
921
+ const provider = function(modelId) {
922
+ return createLanguageModel(modelId);
923
+ };
924
+ provider.specificationVersion = "v4";
925
+ provider.languageModel = createLanguageModel;
926
+ provider.image = createImageModel;
927
+ provider.imageModel = createImageModel;
928
+ provider.embeddingModel = embeddingModel;
929
+ provider.textEmbeddingModel = embeddingModel;
930
+ provider.tools = responsesProvider.tools;
931
+ return provider;
1210
932
  }
1211
- var quiverai = createQuiverAI();
1212
- export {
1213
- VERSION,
1214
- createQuiverAI,
1215
- prepareQuiverAIImageReference,
1216
- quiverai
1217
- };
933
+ const quiverai = createQuiverAI();
934
+ //#endregion
935
+ export { VERSION, createQuiverAI, prepareQuiverAIImageReference, quiverai };
936
+
1218
937
  //# sourceMappingURL=index.js.map