@ai-sdk/quiverai 2.0.44 → 2.0.46

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/quiverai-provider.ts","../src/quiverai-image-model.ts","../src/quiverai-image-model-options.ts","../src/version.ts"],"sourcesContent":["import {\n NoSuchModelError,\n type ImageModelV4,\n type ProviderV4,\n} from '@ai-sdk/provider';\nimport {\n loadApiKey,\n loadOptionalSetting,\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { QuiverAIImageModel } from './quiverai-image-model';\nimport type { QuiverAIImageModelId } from './quiverai-image-settings';\nimport { VERSION } from './version';\n\nexport interface QuiverAIProviderSettings {\n /**\n * QuiverAI API key. Default value is taken from the `QUIVERAI_API_KEY`\n * environment variable.\n */\n apiKey?: string;\n\n /**\n * Base URL for the API calls. Defaults to `https://api.quiver.ai/v1` and\n * falls back to the `QUIVERAI_BASE_URL` environment variable.\n */\n baseURL?: string;\n\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept\n * requests, or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface QuiverAIProvider extends ProviderV4 {\n /**\n * Creates a model for image generation.\n */\n image(modelId: QuiverAIImageModelId): ImageModelV4;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: QuiverAIImageModelId): ImageModelV4;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: string): never;\n}\n\nconst defaultBaseURL = 'https://api.quiver.ai/v1';\n\nexport function createQuiverAI(\n options: QuiverAIProviderSettings = {},\n): QuiverAIProvider {\n const baseURL =\n withoutTrailingSlash(\n loadOptionalSetting({\n settingValue: options.baseURL,\n environmentVariableName: 'QUIVERAI_BASE_URL',\n }),\n ) ?? defaultBaseURL;\n\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'QUIVERAI_API_KEY',\n description: 'QuiverAI',\n })}`,\n ...options.headers,\n },\n `ai-sdk/quiverai/${VERSION}`,\n );\n\n const createImageModel = (modelId: QuiverAIImageModelId) =>\n new QuiverAIImageModel(modelId, {\n provider: 'quiverai.image',\n baseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'embeddingModel',\n });\n };\n\n return {\n specificationVersion: 'v4',\n image: createImageModel,\n imageModel: createImageModel,\n languageModel: (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'languageModel',\n });\n },\n embeddingModel,\n textEmbeddingModel: embeddingModel,\n };\n}\n\nexport const quiverai = createQuiverAI();\n","import {\n InvalidArgumentError,\n type ImageModelV4,\n type ImageModelV4CallOptions,\n type ImageModelV4File,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertBase64ToUint8Array,\n convertUint8ArrayToBase64,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n parseProviderOptions,\n postJsonToApi,\n serializeModelOptions,\n WORKFLOW_DESERIALIZE,\n WORKFLOW_SERIALIZE,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport {\n quiveraiImageModelOptionsSchema,\n type QuiverAIImageModelOptions,\n} from './quiverai-image-model-options';\nimport type {\n QuiverAIImageModelId,\n QuiverAIOperation,\n} from './quiverai-image-settings';\n\ninterface QuiverAIImageModelConfig {\n provider: string;\n baseURL: string;\n headers?: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class QuiverAIImageModel implements ImageModelV4 {\n readonly specificationVersion = 'v4';\n readonly maxImagesPerCall = 16;\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: QuiverAIImageModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: QuiverAIImageModelId;\n config: QuiverAIImageModelConfig;\n }) {\n return new QuiverAIImageModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: QuiverAIImageModelId,\n private readonly config: QuiverAIImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n files,\n mask,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: ImageModelV4CallOptions): Promise<\n Awaited<ReturnType<ImageModelV4['doGenerate']>>\n > {\n const quiveraiOptions = await parseProviderOptions({\n provider: 'quiverai',\n providerOptions,\n schema: quiveraiImageModelOptionsSchema,\n });\n\n const operation: QuiverAIOperation =\n quiveraiOptions?.operation ?? 'generate';\n\n const warnings = collectWarnings({ size, aspectRatio, seed, mask });\n\n const body = buildRequestBody({\n modelId: this.modelId,\n n,\n prompt,\n files,\n mask,\n operation,\n options: quiveraiOptions ?? {},\n });\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const combinedHeaders = combineHeaders(this.config.headers?.(), headers);\n\n const { value: response, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}${getOperationPath(operation)}`,\n headers: combinedHeaders,\n body,\n failedResponseHandler: quiveraiFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n svgGenerationResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n const encoder = new TextEncoder();\n const images = response.data.map(image => encoder.encode(image.svg));\n\n return {\n images,\n warnings,\n providerMetadata: {\n quiverai: {\n ...(response.credits != null && { credits: response.credits }),\n images: response.data.map((image, index) => ({\n index,\n mimeType: image.mime_type,\n ...(image.loop_period_ms !== undefined && {\n loopPeriodMs: image.loop_period_ms,\n }),\n ...(image.opening_animation_ms !== undefined && {\n openingAnimationMs: image.opening_animation_ms,\n }),\n })),\n },\n },\n response: {\n timestamp: response.created\n ? new Date(response.created * 1000)\n : currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n ...(response.usage && {\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n totalTokens: response.usage.total_tokens,\n },\n }),\n };\n }\n}\n\nfunction getOperationPath(operation: QuiverAIOperation) {\n switch (operation) {\n case 'generate':\n return '/svgs/generations';\n case 'vectorize':\n return '/svgs/vectorizations';\n case 'animate':\n return '/svgs/animations';\n }\n}\n\nfunction getGenerateReferenceLimit(modelId: string) {\n // Only apply the lower limit to documented Arrow 1.x models. The API\n // enforces model-specific limits within its 16-reference request limit.\n return ['arrow-1', 'arrow-1.0', 'arrow-1.1'].includes(modelId) ? 4 : 16;\n}\n\nfunction toQuiverAIImageReference(image: ImageModelV4File) {\n if (image.type === 'url') {\n return { url: image.url };\n }\n return {\n base64:\n typeof image.data === 'string'\n ? image.data\n : convertUint8ArrayToBase64(image.data),\n };\n}\n\nconst maxAnimationSourceBase64Length = 1_066_668;\n\nfunction toQuiverAIAnimationSource(image: ImageModelV4File) {\n if (image.type === 'url') {\n let url: URL;\n try {\n url = new URL(image.url);\n } catch {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI animate requires a valid HTTP or HTTPS SVG URL.',\n });\n }\n\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI animate requires an HTTP or HTTPS SVG URL.',\n });\n }\n\n return { url: image.url };\n }\n\n let base64: string;\n let bytes: Uint8Array;\n\n if (typeof image.data === 'string') {\n const dataUrlMatch =\n /^data:image\\/svg\\+xml(?:;[^,]*)?;base64,([\\s\\S]+)$/i.exec(image.data);\n const encodedData = dataUrlMatch?.[1] ?? image.data;\n\n try {\n bytes = convertBase64ToUint8Array(encodedData);\n } catch {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI animate requires the source SVG string to be valid base64 or an SVG data URL.',\n });\n }\n base64 = convertUint8ArrayToBase64(bytes);\n } else {\n bytes = image.data;\n base64 = convertUint8ArrayToBase64(bytes);\n }\n\n if (!isSvg(bytes)) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI animate requires the input file to contain SVG data.',\n });\n }\n\n if (base64.length > maxAnimationSourceBase64Length) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: `QuiverAI animate accepts at most ${maxAnimationSourceBase64Length} base64 characters for the source SVG.`,\n });\n }\n\n return { base64 };\n}\n\nfunction isSvg(data: Uint8Array): boolean {\n const head = new TextDecoder('utf-8', { fatal: false })\n .decode(data.subarray(0, 4096))\n .trimStart();\n\n return /^(?:(?:<\\?xml[\\s\\S]*?\\?>|<!--[\\s\\S]*?-->|<!DOCTYPE[\\s\\S]*?>)\\s*)*<svg(?:\\s|>)/i.test(\n head,\n );\n}\n\nfunction buildRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n operation,\n options,\n}: {\n modelId: string;\n n: number;\n prompt: string | undefined;\n files: ImageModelV4File[] | undefined;\n mask: ImageModelV4File | undefined;\n operation: QuiverAIOperation;\n options: QuiverAIImageModelOptions;\n}) {\n if (\n (modelId === 'arrow-2' || modelId === 'arrow-2-telos') &&\n options.maxOutputTokens != null &&\n options.maxOutputTokens > 65536\n ) {\n throw new InvalidArgumentError({\n argument: 'maxOutputTokens',\n message: `QuiverAI model \"${modelId}\" supports at most 65536 output tokens.`,\n });\n }\n\n const sharedOptions = {\n temperature: options.temperature,\n top_p: options.topP,\n presence_penalty: options.presencePenalty,\n max_output_tokens: options.maxOutputTokens,\n reasoning_effort: options.reasoningEffort,\n attributes: options.attributes,\n stream: false as const,\n };\n\n if (operation === 'generate') {\n if (prompt == null || prompt.trim().length === 0) {\n throw new InvalidArgumentError({\n argument: 'prompt',\n message:\n 'QuiverAI image generation requires a non-empty prompt for generateImage.',\n });\n }\n\n const references = files?.map(toQuiverAIImageReference);\n const maxReferences = getGenerateReferenceLimit(modelId);\n\n if (references != null && references.length > maxReferences) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: `QuiverAI generate supports up to ${maxReferences} reference images for model \"${modelId}\".`,\n });\n }\n\n return {\n model: modelId,\n n,\n prompt,\n ...sharedOptions,\n instructions: options.instructions,\n references,\n };\n }\n\n if (operation === 'animate') {\n return buildAnimationRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n options,\n });\n }\n\n if (files == null || files.length === 0) {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI vectorize requires an input image. Pass an image in the generateImage prompt and set providerOptions.quiverai.operation to \"vectorize\".',\n });\n }\n\n if (files.length > 1) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI vectorize accepts a single input image.',\n });\n }\n\n if (n !== 1) {\n throw new InvalidArgumentError({\n argument: 'n',\n message:\n 'QuiverAI vectorize returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to vectorize multiple times.',\n });\n }\n\n return {\n model: modelId,\n image: toQuiverAIImageReference(files[0]),\n ...sharedOptions,\n auto_crop: options.autoCrop,\n target_size: options.targetSize,\n };\n}\n\nfunction buildAnimationRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n options,\n}: {\n modelId: string;\n n: number;\n prompt: string | undefined;\n files: ImageModelV4File[] | undefined;\n mask: ImageModelV4File | undefined;\n options: QuiverAIImageModelOptions;\n}) {\n if (modelId !== 'arrow-2' && modelId !== 'arrow-2-telos') {\n throw new InvalidArgumentError({\n argument: 'modelId',\n message:\n 'QuiverAI animate is supported by the \"arrow-2\" and \"arrow-2-telos\" models.',\n });\n }\n\n if (files == null || files.length === 0) {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI animate requires exactly one source SVG in prompt.images.',\n });\n }\n\n if (files.length !== 1) {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI animate accepts exactly one source SVG in prompt.images.',\n });\n }\n\n if (n !== 1) {\n throw new InvalidArgumentError({\n argument: 'n',\n message:\n 'QuiverAI animate returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to animate multiple times.',\n });\n }\n\n if (mask != null) {\n throw new InvalidArgumentError({\n argument: 'mask',\n message: 'QuiverAI animate does not support masks.',\n });\n }\n\n if (prompt != null && prompt.trim().length === 0) {\n throw new InvalidArgumentError({\n argument: 'prompt',\n message:\n 'QuiverAI animate requires a non-empty prompt when an animation instruction is provided.',\n });\n }\n\n const unsupportedOptions = [\n ['instructions', options.instructions],\n ['topP', options.topP],\n ['presencePenalty', options.presencePenalty],\n ['attributes', options.attributes],\n ['autoCrop', options.autoCrop],\n ['targetSize', options.targetSize],\n ].filter((option): option is [string, NonNullable<unknown>] => {\n return option[1] !== undefined;\n });\n\n if (unsupportedOptions.length > 0) {\n throw new InvalidArgumentError({\n argument: `providerOptions.quiverai.${unsupportedOptions[0][0]}`,\n message: `QuiverAI animate does not support providerOptions.quiverai.${unsupportedOptions[0][0]}.`,\n });\n }\n\n return {\n model: modelId,\n svg_source: toQuiverAIAnimationSource(files[0]),\n prompt,\n temperature: options.temperature,\n max_output_tokens: options.maxOutputTokens,\n reasoning_effort: options.reasoningEffort,\n stream: false as const,\n };\n}\n\nfunction collectWarnings({\n size,\n aspectRatio,\n seed,\n mask,\n}: {\n size: `${number}x${number}` | undefined;\n aspectRatio: `${number}:${number}` | undefined;\n seed: number | undefined;\n mask: ImageModelV4File | undefined;\n}): SharedV4Warning[] {\n const warnings: SharedV4Warning[] = [];\n\n if (size != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'size',\n details:\n 'QuiverAI SVG generation does not support the `size` option. The setting was ignored.',\n });\n }\n\n if (aspectRatio != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'aspectRatio',\n details:\n 'QuiverAI SVG generation does not support the `aspectRatio` option. The setting was ignored.',\n });\n }\n\n if (seed != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'seed',\n details:\n 'QuiverAI SVG generation does not support the `seed` option. The setting was ignored.',\n });\n }\n\n if (mask != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'mask',\n details:\n 'QuiverAI SVG generation does not support masks. The mask was ignored.',\n });\n }\n\n return warnings;\n}\n\n// Limited schemas focused on what is needed for the implementation.\n// This approach limits breakages when the API changes and keeps the\n// response handler efficient.\nconst svgUsageSchema = z.object({\n total_tokens: z.number().int().nonnegative(),\n input_tokens: z.number().int().nonnegative(),\n output_tokens: z.number().int().nonnegative(),\n});\n\nconst svgDocumentSchema = z.object({\n svg: z.string().min(1),\n mime_type: z.literal('image/svg+xml'),\n loop_period_ms: z.number().int().nonnegative().nullish(),\n opening_animation_ms: z.number().int().nonnegative().nullish(),\n});\n\nconst svgGenerationResponseSchema = z.object({\n id: z.string().min(1),\n created: z.number().int().nonnegative(),\n data: z.array(svgDocumentSchema).min(1),\n usage: svgUsageSchema.nullish(),\n credits: z.number().int().nonnegative().nullish(),\n});\n\nconst quiveraiErrorSchema = z.object({\n status: z.number().int(),\n code: z.string().min(1),\n message: z.string().min(1),\n request_id: z.string().min(1),\n});\n\nexport const quiveraiFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: quiveraiErrorSchema,\n errorToMessage: error => error.message,\n isRetryable: response => response.status === 429 || response.status >= 500,\n});\n","import {\n lazySchema,\n zodSchema,\n type InferSchema,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\n/**\n * Provider options schema for QuiverAI image generation.\n *\n * @see https://quiver.ai/\n */\nexport const quiveraiImageModelOptionsSchema = lazySchema(() =>\n zodSchema(\n z.object({\n /**\n * The operation to perform. Defaults to `generate`.\n *\n * - `generate`: Text-to-SVG generation. Requires `prompt`.\n * - `vectorize`: Convert an input raster image into an SVG. Requires a\n * single image in `prompt.images` / `files`.\n * - `animate`: Animate an input SVG. Requires a single SVG in\n * `prompt.images` / `files`; the text prompt is optional.\n */\n operation: z.enum(['generate', 'vectorize', 'animate']).optional(),\n\n /**\n * Extra style guidance for prompt-based generation.\n */\n instructions: z.string().min(1).optional(),\n\n /**\n * Reasoning effort applied to generation or vectorization.\n */\n reasoningEffort: z.enum(['low', 'medium', 'high', 'xhigh']).optional(),\n\n /**\n * SVG root attributes requested for generation or vectorization.\n */\n attributes: z\n .object({\n viewBox: z\n .object({\n minX: z.number(),\n minY: z.number(),\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .optional(),\n })\n .optional(),\n\n /**\n * Sampling temperature (0-2).\n */\n temperature: z.number().min(0).max(2).optional(),\n\n /**\n * Nucleus sampling top-p (0-1).\n */\n topP: z.number().min(0).max(1).optional(),\n\n /**\n * Presence penalty (-2 to 2).\n */\n presencePenalty: z.number().min(-2).max(2).nullable().optional(),\n\n /**\n * Maximum number of output tokens (1 - 65536 for Arrow 2 models).\n * The legacy upper bound of 131072 is retained for other model IDs.\n */\n maxOutputTokens: z.number().int().min(1).max(131072).optional(),\n\n /**\n * Whether to auto-crop the input image before vectorization.\n * Only used when `operation` is `vectorize`.\n */\n autoCrop: z.boolean().optional(),\n\n /**\n * Target canvas size in pixels for vectorization (128 - 4096).\n * Only used when `operation` is `vectorize`.\n */\n targetSize: z.number().int().min(128).max(4096).optional(),\n }),\n ),\n);\n\nexport type QuiverAIImageModelOptions = InferSchema<\n typeof quiveraiImageModelOptionsSchema\n>;\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["z","z"]}
1
+ {"version":3,"sources":["../src/quiverai-provider.ts","../src/quiverai-image-model.ts","../src/quiverai-image-model-options.ts","../src/prepare-quiverai-image-reference.ts","../src/version.ts"],"sourcesContent":["import {\n NoSuchModelError,\n type ImageModelV4,\n type ProviderV4,\n} from '@ai-sdk/provider';\nimport {\n loadApiKey,\n loadOptionalSetting,\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { QuiverAIImageModel } from './quiverai-image-model';\nimport type { QuiverAIImageModelId } from './quiverai-image-settings';\nimport { VERSION } from './version';\n\nexport interface QuiverAIProviderSettings {\n /**\n * QuiverAI API key. Default value is taken from the `QUIVERAI_API_KEY`\n * environment variable.\n */\n apiKey?: string;\n\n /**\n * Base URL for the API calls. Defaults to `https://api.quiver.ai/v1` and\n * falls back to the `QUIVERAI_BASE_URL` environment variable.\n */\n baseURL?: string;\n\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept\n * requests, or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface QuiverAIProvider extends ProviderV4 {\n /**\n * Creates a model for image generation.\n */\n image(modelId: QuiverAIImageModelId): ImageModelV4;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: QuiverAIImageModelId): ImageModelV4;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: string): never;\n}\n\nconst defaultBaseURL = 'https://api.quiver.ai/v1';\n\nexport function createQuiverAI(\n options: QuiverAIProviderSettings = {},\n): QuiverAIProvider {\n const baseURL =\n withoutTrailingSlash(\n loadOptionalSetting({\n settingValue: options.baseURL,\n environmentVariableName: 'QUIVERAI_BASE_URL',\n }),\n ) ?? defaultBaseURL;\n\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'QUIVERAI_API_KEY',\n description: 'QuiverAI',\n })}`,\n ...options.headers,\n },\n `ai-sdk/quiverai/${VERSION}`,\n );\n\n const createImageModel = (modelId: QuiverAIImageModelId) =>\n new QuiverAIImageModel(modelId, {\n provider: 'quiverai.image',\n baseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'embeddingModel',\n });\n };\n\n return {\n specificationVersion: 'v4',\n image: createImageModel,\n imageModel: createImageModel,\n languageModel: (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'languageModel',\n });\n },\n embeddingModel,\n textEmbeddingModel: embeddingModel,\n };\n}\n\nexport const quiverai = createQuiverAI();\n","import {\n InvalidArgumentError,\n type ImageModelV4,\n type ImageModelV4CallOptions,\n type ImageModelV4File,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertBase64ToUint8Array,\n convertUint8ArrayToBase64,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n parseProviderOptions,\n postJsonToApi,\n serializeModelOptions,\n WORKFLOW_DESERIALIZE,\n WORKFLOW_SERIALIZE,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport {\n quiveraiImageModelOptionsSchema,\n type QuiverAIImageModelOptions,\n} from './quiverai-image-model-options';\nimport {\n validateQuiverAIImageUrl,\n validateQuiverAIReferenceBase64,\n} from './prepare-quiverai-image-reference';\nimport type {\n QuiverAIImageModelId,\n QuiverAIOperation,\n} from './quiverai-image-settings';\n\ninterface QuiverAIImageModelConfig {\n provider: string;\n baseURL: string;\n headers?: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class QuiverAIImageModel implements ImageModelV4 {\n readonly specificationVersion = 'v4';\n readonly maxImagesPerCall = 16;\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: QuiverAIImageModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: QuiverAIImageModelId;\n config: QuiverAIImageModelConfig;\n }) {\n return new QuiverAIImageModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: QuiverAIImageModelId,\n private readonly config: QuiverAIImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n files,\n mask,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: ImageModelV4CallOptions): Promise<\n Awaited<ReturnType<ImageModelV4['doGenerate']>>\n > {\n const quiveraiOptions = await parseProviderOptions({\n provider: 'quiverai',\n providerOptions,\n schema: quiveraiImageModelOptionsSchema,\n });\n\n const operation: QuiverAIOperation =\n quiveraiOptions?.operation ?? 'generate';\n\n const warnings = collectWarnings({ size, aspectRatio, seed, mask });\n\n const body = buildRequestBody({\n modelId: this.modelId,\n n,\n prompt,\n files,\n mask,\n operation,\n options: quiveraiOptions ?? {},\n });\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const combinedHeaders = combineHeaders(this.config.headers?.(), headers);\n\n const { value: response, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}${getOperationPath(operation)}`,\n headers: combinedHeaders,\n body,\n failedResponseHandler: quiveraiFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n svgGenerationResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n const encoder = new TextEncoder();\n const images = response.data.map(image => encoder.encode(image.svg));\n\n return {\n images,\n warnings,\n providerMetadata: {\n quiverai: {\n ...(response.credits != null && { credits: response.credits }),\n images: response.data.map((image, index) => ({\n index,\n mimeType: image.mime_type,\n ...(image.loop_period_ms !== undefined && {\n loopPeriodMs: image.loop_period_ms,\n }),\n ...(image.opening_animation_ms !== undefined && {\n openingAnimationMs: image.opening_animation_ms,\n }),\n })),\n },\n },\n response: {\n timestamp: response.created\n ? new Date(response.created * 1000)\n : currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n ...(response.usage && {\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n totalTokens: response.usage.total_tokens,\n },\n }),\n };\n }\n}\n\nfunction getOperationPath(operation: QuiverAIOperation) {\n switch (operation) {\n case 'generate':\n return '/svgs/generations';\n case 'vectorize':\n return '/svgs/vectorizations';\n case 'edit':\n return '/svgs/edits';\n case 'animate':\n return '/svgs/animations';\n }\n}\n\nfunction getGenerateReferenceLimit(modelId: string) {\n // Only apply the lower limit to documented Arrow 1.x models. The API\n // enforces model-specific limits within its 16-reference request limit.\n return ['arrow-1', 'arrow-1.0', 'arrow-1.1'].includes(modelId) ? 4 : 16;\n}\n\nfunction toQuiverAIImageReference(image: ImageModelV4File) {\n if (image.type === 'url') {\n return { url: image.url };\n }\n return {\n base64:\n typeof image.data === 'string'\n ? image.data\n : convertUint8ArrayToBase64(image.data),\n };\n}\n\nconst maxAnimationSourceBase64Length = 1_066_668;\n\nfunction toQuiverAIAnimationSource(image: ImageModelV4File) {\n if (image.type === 'url') {\n let url: URL;\n try {\n url = new URL(image.url);\n } catch {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI animate requires a valid HTTP or HTTPS SVG URL.',\n });\n }\n\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI animate requires an HTTP or HTTPS SVG URL.',\n });\n }\n\n return { url: image.url };\n }\n\n let base64: string;\n let bytes: Uint8Array;\n\n if (typeof image.data === 'string') {\n const dataUrlMatch =\n /^data:image\\/svg\\+xml(?:;[^,]*)?;base64,([\\s\\S]+)$/i.exec(image.data);\n const encodedData = dataUrlMatch?.[1] ?? image.data;\n\n try {\n bytes = convertBase64ToUint8Array(encodedData);\n } catch {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI animate requires the source SVG string to be valid base64 or an SVG data URL.',\n });\n }\n base64 = convertUint8ArrayToBase64(bytes);\n } else {\n bytes = image.data;\n base64 = convertUint8ArrayToBase64(bytes);\n }\n\n if (!isSvg(bytes)) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI animate requires the input file to contain SVG data.',\n });\n }\n\n if (base64.length > maxAnimationSourceBase64Length) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: `QuiverAI animate accepts at most ${maxAnimationSourceBase64Length} base64 characters for the source SVG.`,\n });\n }\n\n return { base64 };\n}\n\nfunction isSvg(data: Uint8Array): boolean {\n const head = new TextDecoder('utf-8', { fatal: false })\n .decode(data.subarray(0, 4096))\n .trimStart();\n\n return /^(?:(?:<\\?xml[\\s\\S]*?\\?>|<!--[\\s\\S]*?-->|<!DOCTYPE[\\s\\S]*?>)\\s*)*<svg(?:\\s|>)/i.test(\n head,\n );\n}\n\nfunction buildRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n operation,\n options,\n}: {\n modelId: string;\n n: number;\n prompt: string | undefined;\n files: ImageModelV4File[] | undefined;\n mask: ImageModelV4File | undefined;\n operation: QuiverAIOperation;\n options: QuiverAIImageModelOptions;\n}) {\n if (\n (modelId === 'arrow-2' || modelId === 'arrow-2-telos') &&\n options.maxOutputTokens != null &&\n options.maxOutputTokens > 65536\n ) {\n throw new InvalidArgumentError({\n argument: 'maxOutputTokens',\n message: `QuiverAI model \"${modelId}\" supports at most 65536 output tokens.`,\n });\n }\n\n const sharedOptions = {\n temperature: options.temperature,\n top_p: options.topP,\n presence_penalty: options.presencePenalty,\n max_output_tokens: options.maxOutputTokens,\n reasoning_effort: options.reasoningEffort,\n attributes: options.attributes,\n stream: false as const,\n };\n\n if (operation !== 'edit') {\n rejectEditOnlyOptions(operation, options);\n }\n\n if (operation === 'generate') {\n if (prompt == null || prompt.trim().length === 0) {\n throw new InvalidArgumentError({\n argument: 'prompt',\n message:\n 'QuiverAI image generation requires a non-empty prompt for generateImage.',\n });\n }\n\n const references = files?.map(toQuiverAIImageReference);\n const maxReferences = getGenerateReferenceLimit(modelId);\n\n if (references != null && references.length > maxReferences) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: `QuiverAI generate supports up to ${maxReferences} reference images for model \"${modelId}\".`,\n });\n }\n\n return {\n model: modelId,\n n,\n prompt,\n ...sharedOptions,\n instructions: options.instructions,\n references,\n };\n }\n\n if (operation === 'edit') {\n return buildEditRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n options,\n });\n }\n\n if (operation === 'animate') {\n return buildAnimationRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n options,\n });\n }\n\n if (files == null || files.length === 0) {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI vectorize requires an input image. Pass an image in the generateImage prompt and set providerOptions.quiverai.operation to \"vectorize\".',\n });\n }\n\n if (files.length > 1) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI vectorize accepts a single input image.',\n });\n }\n\n if (n !== 1) {\n throw new InvalidArgumentError({\n argument: 'n',\n message:\n 'QuiverAI vectorize returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to vectorize multiple times.',\n });\n }\n\n return {\n model: modelId,\n image: toQuiverAIImageReference(files[0]),\n ...sharedOptions,\n auto_crop: options.autoCrop,\n target_size: options.targetSize,\n };\n}\n\nfunction buildAnimationRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n options,\n}: {\n modelId: string;\n n: number;\n prompt: string | undefined;\n files: ImageModelV4File[] | undefined;\n mask: ImageModelV4File | undefined;\n options: QuiverAIImageModelOptions;\n}) {\n if (modelId !== 'arrow-2' && modelId !== 'arrow-2-telos') {\n throw new InvalidArgumentError({\n argument: 'modelId',\n message:\n 'QuiverAI animate is supported by the \"arrow-2\" and \"arrow-2-telos\" models.',\n });\n }\n\n if (files == null || files.length === 0) {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI animate requires exactly one source SVG in prompt.images.',\n });\n }\n\n if (files.length !== 1) {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI animate accepts exactly one source SVG in prompt.images.',\n });\n }\n\n if (n !== 1) {\n throw new InvalidArgumentError({\n argument: 'n',\n message:\n 'QuiverAI animate returns one SVG per request. Set maxImagesPerCall to 1 in generateImage to animate multiple times.',\n });\n }\n\n if (mask != null) {\n throw new InvalidArgumentError({\n argument: 'mask',\n message: 'QuiverAI animate does not support masks.',\n });\n }\n\n if (prompt != null && prompt.trim().length === 0) {\n throw new InvalidArgumentError({\n argument: 'prompt',\n message:\n 'QuiverAI animate requires a non-empty prompt when an animation instruction is provided.',\n });\n }\n\n const unsupportedOptions = [\n ['instructions', options.instructions],\n ['topP', options.topP],\n ['presencePenalty', options.presencePenalty],\n ['attributes', options.attributes],\n ['autoCrop', options.autoCrop],\n ['targetSize', options.targetSize],\n ].filter((option): option is [string, NonNullable<unknown>] => {\n return option[1] !== undefined;\n });\n\n if (unsupportedOptions.length > 0) {\n throw new InvalidArgumentError({\n argument: `providerOptions.quiverai.${unsupportedOptions[0][0]}`,\n message: `QuiverAI animate does not support providerOptions.quiverai.${unsupportedOptions[0][0]}.`,\n });\n }\n\n return {\n model: modelId,\n svg_source: toQuiverAIAnimationSource(files[0]),\n prompt,\n temperature: options.temperature,\n max_output_tokens: options.maxOutputTokens,\n reasoning_effort: options.reasoningEffort,\n stream: false as const,\n };\n}\n\nconst editModelIds = new Set(['arrow-2', 'arrow-2-telos']);\nconst MAX_EDIT_SVG_BYTES = 200_000;\n\nfunction buildEditRequestBody({\n modelId,\n n,\n prompt,\n files,\n mask,\n options,\n}: {\n modelId: string;\n n: number;\n prompt: string | undefined;\n files: ImageModelV4File[] | undefined;\n mask: ImageModelV4File | undefined;\n options: QuiverAIImageModelOptions;\n}) {\n if (!editModelIds.has(modelId)) {\n throw new InvalidArgumentError({\n argument: 'modelId',\n message:\n 'QuiverAI SVG editing is supported by the \"arrow-2\" and \"arrow-2-telos\" models.',\n });\n }\n\n if (prompt == null || prompt.trim().length === 0) {\n throw new InvalidArgumentError({\n argument: 'prompt',\n message:\n 'QuiverAI SVG editing requires a non-empty instruction in generateImage prompt.text.',\n });\n }\n\n if (prompt.length > 4000) {\n throw new InvalidArgumentError({\n argument: 'prompt',\n message:\n 'QuiverAI SVG editing instructions must contain at most 4000 characters.',\n });\n }\n\n if (files == null || files.length === 0) {\n throw new InvalidArgumentError({\n argument: 'files',\n message:\n 'QuiverAI SVG editing requires one source SVG in generateImage prompt.images.',\n });\n }\n\n if (files.length !== 1) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI SVG editing accepts exactly one source SVG.',\n });\n }\n\n if (n !== 1) {\n throw new InvalidArgumentError({\n argument: 'n',\n message:\n 'QuiverAI SVG editing returns exactly one SVG per request. Set maxImagesPerCall to 1 in generateImage to edit multiple times.',\n });\n }\n\n if (mask != null) {\n throw new InvalidArgumentError({\n argument: 'mask',\n message: 'QuiverAI SVG editing does not support masks.',\n });\n }\n\n const unsupportedOptions = [\n ['instructions', options.instructions],\n ['attributes', options.attributes],\n ['topP', options.topP],\n ['presencePenalty', options.presencePenalty],\n ['autoCrop', options.autoCrop],\n ['targetSize', options.targetSize],\n ].flatMap(([name, value]) => (value == null ? [] : [name]));\n\n if (unsupportedOptions.length > 0) {\n throw new InvalidArgumentError({\n argument: 'providerOptions',\n message: `QuiverAI SVG editing does not support these provider options: ${unsupportedOptions.join(\n ', ',\n )}.`,\n });\n }\n\n const referenceImages = options.referenceImages?.map((reference, index) => {\n if ('url' in reference) {\n return {\n url: validateQuiverAIImageUrl(reference.url),\n };\n }\n\n validateQuiverAIReferenceBase64(\n reference.base64,\n `providerOptions.quiverai.referenceImages[${index}]`,\n );\n return { base64: reference.base64 };\n });\n const settings = {\n max_output_tokens: options.maxOutputTokens,\n orchestrator_max_output_tokens: options.orchestratorMaxOutputTokens,\n shallow_max_output_tokens: options.shallowMaxOutputTokens,\n temperature: options.temperature,\n };\n const hasSettings = Object.values(settings).some(value => value != null);\n\n return {\n model: modelId,\n prompt,\n ...toQuiverAIEditSource(files[0]),\n reference_images: referenceImages,\n max_review_steps: options.maxReviewSteps,\n reasoning_effort: options.reasoningEffort,\n ...(hasSettings && { settings }),\n stream: false as const,\n };\n}\n\nfunction rejectEditOnlyOptions(\n operation: Exclude<QuiverAIOperation, 'edit'>,\n options: QuiverAIImageModelOptions,\n) {\n const editOnlyOptions = [\n ['referenceImages', options.referenceImages],\n ['maxReviewSteps', options.maxReviewSteps],\n ['orchestratorMaxOutputTokens', options.orchestratorMaxOutputTokens],\n ['shallowMaxOutputTokens', options.shallowMaxOutputTokens],\n ].flatMap(([name, value]) => (value == null ? [] : [name]));\n\n if (editOnlyOptions.length > 0) {\n throw new InvalidArgumentError({\n argument: 'providerOptions',\n message: `QuiverAI ${operation} does not support these edit-only provider options: ${editOnlyOptions.join(\n ', ',\n )}.`,\n });\n }\n}\n\nfunction toQuiverAIEditSource(file: ImageModelV4File) {\n if (file.type === 'url') {\n return {\n svg_source: {\n url: validateQuiverAIImageUrl(file.url),\n },\n };\n }\n\n let data: Uint8Array;\n try {\n data =\n typeof file.data === 'string'\n ? convertBase64ToUint8Array(file.data)\n : file.data;\n } catch (cause) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI SVG source data must be valid base64 or binary data.',\n cause,\n });\n }\n\n if (data.length === 0 || data.length > MAX_EDIT_SVG_BYTES) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: `QuiverAI SVG source data must contain 1-${MAX_EDIT_SVG_BYTES} bytes.`,\n });\n }\n\n let svg: string;\n try {\n svg = new TextDecoder('utf-8', { fatal: true }).decode(data);\n } catch (cause) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI SVG source data must be valid UTF-8.',\n cause,\n });\n }\n\n if (svg.length > MAX_EDIT_SVG_BYTES || !isSvgMarkup(svg)) {\n throw new InvalidArgumentError({\n argument: 'files',\n message: 'QuiverAI SVG source data must contain a complete SVG document.',\n });\n }\n\n return {\n svg_source: {\n base64: convertUint8ArrayToBase64(data),\n },\n };\n}\n\nfunction isSvgMarkup(svg: string) {\n const document = svg.replace(/^\\uFEFF/, '');\n const elements: string[] = [];\n let position = 0;\n let rootSeen = false;\n let rootClosed = false;\n let doctypeSeen = false;\n\n while (position < document.length) {\n if (document[position] !== '<') {\n const nextTag = document.indexOf('<', position);\n const end = nextTag === -1 ? document.length : nextTag;\n const text = document.slice(position, end);\n\n if (\n (elements.length === 0 && text.trim().length > 0) ||\n text.includes(']]>') ||\n !hasValidXmlReferences(text)\n ) {\n return false;\n }\n\n position = end;\n continue;\n }\n\n if (document.startsWith('<!--', position)) {\n const commentEnd = document.indexOf('-->', position + 4);\n if (\n commentEnd === -1 ||\n document.slice(position + 4, commentEnd).includes('--')\n ) {\n return false;\n }\n position = commentEnd + 3;\n continue;\n }\n\n if (document.startsWith('<?', position)) {\n const instructionEnd = document.indexOf('?>', position + 2);\n if (instructionEnd === -1) {\n return false;\n }\n position = instructionEnd + 2;\n continue;\n }\n\n if (document.startsWith('<![CDATA[', position)) {\n if (elements.length === 0) {\n return false;\n }\n const cdataEnd = document.indexOf(']]>', position + 9);\n if (cdataEnd === -1) {\n return false;\n }\n position = cdataEnd + 3;\n continue;\n }\n\n if (document.slice(position, position + 9).toUpperCase() === '<!DOCTYPE') {\n if (\n rootSeen ||\n doctypeSeen ||\n elements.length > 0 ||\n !/[\\t\\n\\r ]/.test(document[position + 9] ?? '')\n ) {\n return false;\n }\n const doctypeName = readXmlName(\n document,\n skipXmlWhitespace(document, position + 9),\n );\n if (doctypeName?.name.toLowerCase() !== 'svg') {\n return false;\n }\n const doctypeEnd = findDoctypeEnd(document, doctypeName.end);\n if (doctypeEnd === -1) {\n return false;\n }\n doctypeSeen = true;\n position = doctypeEnd;\n continue;\n }\n\n if (document.startsWith('<!', position)) {\n return false;\n }\n\n if (document.startsWith('</', position)) {\n const closingTag = readXmlName(document, position + 2);\n if (closingTag == null) {\n return false;\n }\n let tagEnd = skipXmlWhitespace(document, closingTag.end);\n if (document[tagEnd] !== '>') {\n return false;\n }\n const expectedTag = elements.pop();\n if (expectedTag !== closingTag.name) {\n return false;\n }\n tagEnd += 1;\n if (elements.length === 0) {\n rootClosed = true;\n }\n position = tagEnd;\n continue;\n }\n\n if (rootClosed) {\n return false;\n }\n\n const openingTag = readXmlName(document, position + 1);\n if (openingTag == null) {\n return false;\n }\n if (!rootSeen) {\n if (openingTag.name.toLowerCase() !== 'svg') {\n return false;\n }\n rootSeen = true;\n }\n\n const attributes = new Set<string>();\n let tagPosition = openingTag.end;\n while (tagPosition < document.length) {\n const beforeWhitespace = tagPosition;\n tagPosition = skipXmlWhitespace(document, tagPosition);\n\n if (document.startsWith('/>', tagPosition)) {\n tagPosition += 2;\n if (elements.length === 0) {\n rootClosed = true;\n }\n position = tagPosition;\n break;\n }\n\n if (document[tagPosition] === '>') {\n elements.push(openingTag.name);\n position = tagPosition + 1;\n break;\n }\n\n if (tagPosition === beforeWhitespace) {\n return false;\n }\n\n const attribute = readXmlName(document, tagPosition);\n if (attribute == null || attributes.has(attribute.name)) {\n return false;\n }\n attributes.add(attribute.name);\n\n tagPosition = skipXmlWhitespace(document, attribute.end);\n if (document[tagPosition] !== '=') {\n return false;\n }\n tagPosition = skipXmlWhitespace(document, tagPosition + 1);\n\n const quote = document[tagPosition];\n if (quote !== '\"' && quote !== \"'\") {\n return false;\n }\n const valueEnd = document.indexOf(quote, tagPosition + 1);\n if (\n valueEnd === -1 ||\n document.slice(tagPosition + 1, valueEnd).includes('<') ||\n !hasValidXmlReferences(document.slice(tagPosition + 1, valueEnd))\n ) {\n return false;\n }\n tagPosition = valueEnd + 1;\n }\n\n if (tagPosition >= document.length && position !== document.length) {\n return false;\n }\n }\n\n return rootSeen && rootClosed && elements.length === 0;\n}\n\nfunction isXmlNameStart(character: string | undefined) {\n return character != null && /[A-Z_a-z:\\u0080-\\uFFFF]/.test(character);\n}\n\nfunction isXmlNameCharacter(character: string | undefined) {\n return (\n character != null && /[-.0-9A-Z_a-z:\\u00B7\\u0080-\\uFFFF]/.test(character)\n );\n}\n\nfunction readXmlName(value: string, position: number) {\n if (!isXmlNameStart(value[position])) {\n return undefined;\n }\n\n const start = position;\n position += 1;\n while (isXmlNameCharacter(value[position])) {\n position += 1;\n }\n\n return {\n name: value.slice(start, position),\n end: position,\n };\n}\n\nfunction skipXmlWhitespace(value: string, position: number) {\n while (/[\\t\\n\\r ]/.test(value[position] ?? '')) {\n position += 1;\n }\n return position;\n}\n\nfunction hasValidXmlReferences(value: string) {\n let position = value.indexOf('&');\n while (position !== -1) {\n const end = value.indexOf(';', position + 1);\n if (end === -1) {\n return false;\n }\n const reference = value.slice(position + 1, end);\n if (\n !/^#\\d+$/.test(reference) &&\n !/^#x[\\dA-Fa-f]+$/.test(reference) &&\n !/^[A-Z_a-z:\\u0080-\\uFFFF][-.0-9A-Z_a-z:\\u00B7\\u0080-\\uFFFF]*$/.test(\n reference,\n )\n ) {\n return false;\n }\n position = value.indexOf('&', end + 1);\n }\n return true;\n}\n\nfunction findDoctypeEnd(value: string, position: number) {\n let subsetDepth = 0;\n let quote: '\"' | \"'\" | undefined;\n\n while (position < value.length) {\n const character = value[position];\n if (quote != null) {\n if (character === quote) {\n quote = undefined;\n }\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (character === '[') {\n subsetDepth += 1;\n } else if (character === ']') {\n if (subsetDepth === 0) {\n return -1;\n }\n subsetDepth -= 1;\n } else if (character === '>' && subsetDepth === 0) {\n return position + 1;\n }\n position += 1;\n }\n\n return -1;\n}\n\nfunction collectWarnings({\n size,\n aspectRatio,\n seed,\n mask,\n}: {\n size: `${number}x${number}` | undefined;\n aspectRatio: `${number}:${number}` | undefined;\n seed: number | undefined;\n mask: ImageModelV4File | undefined;\n}): SharedV4Warning[] {\n const warnings: SharedV4Warning[] = [];\n\n if (size != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'size',\n details:\n 'QuiverAI SVG generation does not support the `size` option. The setting was ignored.',\n });\n }\n\n if (aspectRatio != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'aspectRatio',\n details:\n 'QuiverAI SVG generation does not support the `aspectRatio` option. The setting was ignored.',\n });\n }\n\n if (seed != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'seed',\n details:\n 'QuiverAI SVG generation does not support the `seed` option. The setting was ignored.',\n });\n }\n\n if (mask != null) {\n warnings.push({\n type: 'unsupported',\n feature: 'mask',\n details:\n 'QuiverAI SVG generation does not support masks. The mask was ignored.',\n });\n }\n\n return warnings;\n}\n\n// Limited schemas focused on what is needed for the implementation.\n// This approach limits breakages when the API changes and keeps the\n// response handler efficient.\nconst svgUsageSchema = z.object({\n total_tokens: z.number().int().nonnegative(),\n input_tokens: z.number().int().nonnegative(),\n output_tokens: z.number().int().nonnegative(),\n});\n\nconst svgDocumentSchema = z.object({\n svg: z.string().min(1),\n mime_type: z.literal('image/svg+xml'),\n loop_period_ms: z.number().int().nonnegative().nullish(),\n opening_animation_ms: z.number().int().nonnegative().nullish(),\n});\n\nconst svgGenerationResponseSchema = z.object({\n id: z.string().min(1),\n created: z.number().int().nonnegative(),\n data: z.array(svgDocumentSchema).min(1),\n usage: svgUsageSchema.nullish(),\n credits: z.number().int().nonnegative().nullish(),\n});\n\nconst quiveraiErrorSchema = z.object({\n status: z.number().int(),\n code: z.string().min(1),\n message: z.string().min(1),\n request_id: z.string().min(1),\n});\n\nexport const quiveraiFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: quiveraiErrorSchema,\n errorToMessage: error => error.message,\n isRetryable: response => response.status === 429 || response.status >= 500,\n});\n","import {\n lazySchema,\n zodSchema,\n type InferSchema,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\n/**\n * Provider options schema for QuiverAI image generation.\n *\n * @see https://quiver.ai/\n */\nexport const quiveraiImageModelOptionsSchema = lazySchema(() =>\n zodSchema(\n z.object({\n /**\n * The operation to perform. Defaults to `generate`.\n *\n * - `generate`: Text-to-SVG generation. Requires `prompt`.\n * - `vectorize`: Convert an input raster image into an SVG. Requires a\n * single image in `prompt.images` / `files`.\n * - `animate`: Animate an input SVG. Requires a single SVG in\n * `prompt.images` / `files`; the text prompt is optional.\n * - `edit`: Edit a single SVG from `prompt.images` using `prompt.text`\n * as the required instruction.\n */\n operation: z\n .enum(['generate', 'vectorize', 'animate', 'edit'])\n .optional(),\n\n /**\n * Extra style guidance for prompt-based generation.\n */\n instructions: z.string().min(1).optional(),\n\n /**\n * Reasoning effort applied to generation or vectorization.\n */\n reasoningEffort: z.enum(['low', 'medium', 'high', 'xhigh']).optional(),\n\n /**\n * Optional reference images for SVG editing. Use\n * `prepareQuiverAIImageReference` to convert binary inputs.\n */\n referenceImages: z\n .array(\n z.union([\n z.object({ url: z.string().min(1) }).strict(),\n z.object({ base64: z.string().min(1).max(16_777_216) }).strict(),\n ]),\n )\n .max(4)\n .optional(),\n\n /**\n * Maximum number of edit review and redo steps (0-5).\n */\n maxReviewSteps: z.number().int().min(0).max(5).optional(),\n\n /**\n * SVG root attributes requested for generation or vectorization.\n */\n attributes: z\n .object({\n viewBox: z\n .object({\n minX: z.number(),\n minY: z.number(),\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .optional(),\n })\n .optional(),\n\n /**\n * Sampling temperature (0-2).\n */\n temperature: z.number().min(0).max(2).optional(),\n\n /**\n * Nucleus sampling top-p (0-1).\n */\n topP: z.number().min(0).max(1).optional(),\n\n /**\n * Presence penalty (-2 to 2).\n */\n presencePenalty: z.number().min(-2).max(2).nullable().optional(),\n\n /**\n * Maximum number of output tokens (1 - 65536 for Arrow 2 models).\n * The legacy upper bound of 131072 is retained for other model IDs.\n */\n maxOutputTokens: z.number().int().min(1).max(131072).optional(),\n\n /**\n * Provider orchestrator token budget for SVG editing (1-65536).\n */\n orchestratorMaxOutputTokens: z\n .number()\n .int()\n .min(1)\n .max(65536)\n .optional(),\n\n /**\n * Provider shallow edit token budget for SVG editing (1-65536).\n */\n shallowMaxOutputTokens: z.number().int().min(1).max(65536).optional(),\n\n /**\n * Whether to auto-crop the input image before vectorization.\n * Only used when `operation` is `vectorize`.\n */\n autoCrop: z.boolean().optional(),\n\n /**\n * Target canvas size in pixels for vectorization (128 - 4096).\n * Only used when `operation` is `vectorize`.\n */\n targetSize: z.number().int().min(128).max(4096).optional(),\n }),\n ),\n);\n\nexport type QuiverAIImageModelOptions = InferSchema<\n typeof quiveraiImageModelOptionsSchema\n>;\n","import { InvalidArgumentError } from '@ai-sdk/provider';\nimport {\n convertBase64ToUint8Array,\n convertUint8ArrayToBase64,\n detectMediaType,\n} from '@ai-sdk/provider-utils';\n\nconst MAX_REFERENCE_BASE64_LENGTH = 16_777_216;\nconst MAX_REFERENCE_BYTES = 12_582_912;\nconst supportedReferenceMediaTypes = new Set([\n 'image/gif',\n 'image/jpeg',\n 'image/png',\n 'image/svg+xml',\n 'image/webp',\n]);\n\nexport type QuiverAIImageReference =\n | { url: string }\n | {\n /**\n * Base64-encoded image data without a data URL prefix.\n */\n base64: string;\n };\n\nexport type QuiverAIImageReferenceInput =\n | string\n | URL\n | Uint8Array\n | ArrayBuffer;\n\n/**\n * Converts URL, binary, data URL, or base64 image input into the JSON-safe\n * reference shape accepted by QuiverAI provider options.\n */\nexport function prepareQuiverAIImageReference(\n input: QuiverAIImageReferenceInput,\n): QuiverAIImageReference {\n if (input instanceof URL) {\n return { url: validateQuiverAIImageUrl(input.toString()) };\n }\n\n if (typeof input === 'string') {\n if (/^[a-z][a-z\\d+.-]*:\\/\\//i.test(input)) {\n return { url: validateQuiverAIImageUrl(input) };\n }\n\n if (input.startsWith('data:')) {\n const match = /^data:([^;,]+);base64,(.+)$/s.exec(input);\n if (match == null || !supportedReferenceMediaTypes.has(match[1])) {\n throw new InvalidArgumentError({\n argument: 'input',\n message:\n 'QuiverAI reference image data URLs must use base64 encoding and a supported image media type.',\n });\n }\n\n validateQuiverAIReferenceBase64(match[2], 'input');\n return { base64: match[2] };\n }\n\n validateQuiverAIReferenceBase64(input, 'input');\n return { base64: input };\n }\n\n const data =\n input instanceof ArrayBuffer\n ? new Uint8Array(input)\n : new Uint8Array(input);\n validateQuiverAIReferenceBytes(data, 'input');\n return { base64: convertUint8ArrayToBase64(data) };\n}\n\nexport function validateQuiverAIImageUrl(url: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new InvalidArgumentError({\n argument: 'url',\n message: 'QuiverAI image URLs must be valid HTTP or HTTPS URLs.',\n });\n }\n\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new InvalidArgumentError({\n argument: 'url',\n message: 'QuiverAI image URLs must use HTTP or HTTPS.',\n });\n }\n\n return parsed.toString();\n}\n\nexport function validateQuiverAIReferenceBase64(\n base64: string,\n argument: string,\n): void {\n if (base64.length === 0 || base64.length > MAX_REFERENCE_BASE64_LENGTH) {\n throw new InvalidArgumentError({\n argument,\n message: `QuiverAI reference images must contain 1-${MAX_REFERENCE_BASE64_LENGTH} base64 characters.`,\n });\n }\n\n let data: Uint8Array;\n try {\n data = convertBase64ToUint8Array(base64);\n } catch (cause) {\n throw new InvalidArgumentError({\n argument,\n message: 'QuiverAI reference image data must be valid base64.',\n cause,\n });\n }\n\n validateQuiverAIReferenceBytes(data, argument);\n}\n\nfunction validateQuiverAIReferenceBytes(\n data: Uint8Array,\n argument: string,\n): void {\n if (data.length === 0 || data.length > MAX_REFERENCE_BYTES) {\n throw new InvalidArgumentError({\n argument,\n message: `QuiverAI reference images must decode to 1-${MAX_REFERENCE_BYTES} bytes.`,\n });\n }\n\n const mediaType = isSvg(data)\n ? 'image/svg+xml'\n : detectMediaType({ data, topLevelType: 'image' });\n\n if (mediaType == null || !supportedReferenceMediaTypes.has(mediaType)) {\n throw new InvalidArgumentError({\n argument,\n message:\n 'QuiverAI reference images must be PNG, JPEG, WebP, GIF, or SVG data.',\n });\n }\n}\n\nfunction isSvg(data: Uint8Array): boolean {\n let text: string;\n try {\n text = new TextDecoder('utf-8', { fatal: true }).decode(data);\n } catch {\n return false;\n }\n\n const normalized = text.replace(/^\\uFEFF/, '').trim();\n return (\n /^(?:<\\?xml[\\s\\S]*?\\?>\\s*)?(?:<!--[\\s\\S]*?-->\\s*)?(?:<!DOCTYPE[\\s\\S]*?>\\s*)?<svg[\\s>]/i.test(\n normalized,\n ) &&\n (/<\\/svg>\\s*$/i.test(normalized) ||\n /<svg(?:\\s[^>]*)?\\/>\\s*$/is.test(normalized))\n );\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["InvalidArgumentError","convertBase64ToUint8Array","convertUint8ArrayToBase64","z","convertUint8ArrayToBase64","InvalidArgumentError","convertBase64ToUint8Array","isSvg","z"]}
@@ -5,7 +5,7 @@ description: Learn how to use QuiverAI models with the AI SDK.
5
5
 
6
6
  # QuiverAI Provider
7
7
 
8
- [QuiverAI](https://quiver.ai/) generates SVG documents directly from text prompts, vectorizes raster images, and animates existing SVGs. The QuiverAI provider for the AI SDK exposes these operations through `generateImage`.
8
+ [QuiverAI](https://quiver.ai/) generates SVG documents directly from text prompts, vectorizes raster images into clean SVGs, and edits and animates existing SVGs. The QuiverAI provider for the AI SDK exposes these operations through `generateImage`.
9
9
 
10
10
  ## Setup
11
11
 
@@ -85,13 +85,13 @@ QuiverAI returns SVG documents. The generated SVG bytes are available through `r
85
85
 
86
86
  QuiverAI supports the following Arrow models:
87
87
 
88
- | Model | Description |
89
- | --------------- | -------------------------------------------------------------------------------- |
90
- | `arrow-2` | Arrow 2 balances SVG generation quality and speed. Uses token-based billing. |
91
- | `arrow-2-telos` | Higher-fidelity Arrow 2 variant for complex designs. Uses token-based billing. |
92
- | `arrow-1` | Base text-to-SVG model. Accepts up to 4 reference images. |
93
- | `arrow-1.1` | Improved text-to-SVG model. Accepts up to 4 reference images. |
94
- | `arrow-1.1-max` | Higher quality variant with extended context. Accepts up to 16 reference images. |
88
+ | Model | Description |
89
+ | --------------- | --------------------------------------------------------------------------------------------------------------------------------- |
90
+ | `arrow-2` | Arrow 2 balances SVG generation quality and speed. Supports SVG editing when enabled for the API key. Uses token-based billing. |
91
+ | `arrow-2-telos` | Higher-fidelity Arrow 2 variant for complex designs. Supports SVG editing when enabled for the API key. Uses token-based billing. |
92
+ | `arrow-1` | Base text-to-SVG model. Accepts up to 4 reference images. |
93
+ | `arrow-1.1` | Improved text-to-SVG model. Accepts up to 4 reference images. |
94
+ | `arrow-1.1-max` | Higher quality variant with extended context. Accepts up to 16 reference images. |
95
95
 
96
96
  ### Provider Options
97
97
 
@@ -119,17 +119,17 @@ await generateImage({
119
119
 
120
120
  Supported options:
121
121
 
122
- - **operation** _'generate' | 'vectorize' | 'animate'_
122
+ - **operation** _'generate' | 'vectorize' | 'edit' | 'animate'_
123
123
 
124
- Choose between text-to-SVG generation (`generate`, default), image-to-SVG vectorization (`vectorize`), and SVG animation (`animate`).
124
+ Choose between text-to-SVG generation (`generate`, default), image-to-SVG vectorization (`vectorize`), SVG editing (`edit`), and SVG animation (`animate`).
125
125
 
126
126
  - **instructions** _string_
127
127
 
128
- Extra style guidance for prompt-based generation.
128
+ Extra style guidance for prompt-based generation. This option is not used as the SVG edit instruction; use `prompt.text` for editing.
129
129
 
130
130
  - **reasoningEffort** _'low' | 'medium' | 'high' | 'xhigh'_
131
131
 
132
- Reasoning effort for generation or vectorization. When omitted, QuiverAI uses its default.
132
+ Reasoning effort for generation, vectorization, or editing. When omitted, QuiverAI uses its default.
133
133
 
134
134
  - **attributes** _object_
135
135
 
@@ -151,6 +151,22 @@ Supported options:
151
151
 
152
152
  Maximum number of output tokens. Arrow 2 and Arrow 2 Telos accept 1-65536. The provider retains its legacy validation bound of 131072 for other model IDs; the API may enforce a lower model-specific limit.
153
153
 
154
+ - **referenceImages** `Array<{ url: string } | { base64: string }>`
155
+
156
+ Up to four optional reference images for SVG editing. URL references must use HTTP or HTTPS. Base64 references must decode to PNG, JPEG, WebP, GIF, or SVG data. Use `prepareQuiverAIImageReference` to convert binary, data URL, or URL inputs into this JSON-safe provider option shape.
157
+
158
+ - **maxReviewSteps** _number_ (0-5)
159
+
160
+ Maximum number of edit review and redo steps after the initial edit.
161
+
162
+ - **orchestratorMaxOutputTokens** _number_ (1-65536)
163
+
164
+ Optional provider orchestrator token budget for SVG editing.
165
+
166
+ - **shallowMaxOutputTokens** _number_ (1-65536)
167
+
168
+ Optional provider shallow edit token budget for SVG editing.
169
+
154
170
  - **autoCrop** _boolean_
155
171
 
156
172
  When vectorizing, automatically crop the input image. Only used with `operation: 'vectorize'`.
@@ -203,6 +219,64 @@ fs.writeFileSync('logo.svg', image.uint8Array);
203
219
 
204
220
  Vectorization returns one SVG per API request. To request multiple vectorizations with `n`, also set `maxImagesPerCall: 1` so `generateImage` splits them into separate calls.
205
221
 
222
+ ### Editing an SVG
223
+
224
+ Set `operation` to `edit`, put exactly one source SVG in `prompt.images`, and provide the edit instruction in `prompt.text`:
225
+
226
+ ```ts
227
+ import {
228
+ prepareQuiverAIImageReference,
229
+ quiverai,
230
+ type QuiverAIImageModelOptions,
231
+ } from '@ai-sdk/quiverai';
232
+ import { generateImage } from 'ai';
233
+ import fs from 'node:fs/promises';
234
+
235
+ const { image } = await generateImage({
236
+ model: quiverai.image('arrow-2'),
237
+ prompt: {
238
+ text: 'Make the logo blue and simplify the star points.',
239
+ images: [await fs.readFile('./logo.svg')],
240
+ },
241
+ providerOptions: {
242
+ quiverai: {
243
+ operation: 'edit',
244
+ referenceImages: [
245
+ prepareQuiverAIImageReference(
246
+ await fs.readFile('./blue-reference.png'),
247
+ ),
248
+ { url: 'https://example.com/second-reference.png' },
249
+ ],
250
+ maxReviewSteps: 2,
251
+ reasoningEffort: 'medium',
252
+ maxOutputTokens: 4096,
253
+ orchestratorMaxOutputTokens: 4096,
254
+ shallowMaxOutputTokens: 2048,
255
+ temperature: 0.4,
256
+ } satisfies QuiverAIImageModelOptions,
257
+ },
258
+ });
259
+
260
+ await fs.writeFile('./edited-logo.svg', image.uint8Array);
261
+ ```
262
+
263
+ The source SVG can be an HTTP/HTTPS URL, binary data such as a `Buffer` or `Uint8Array`, a base64 string, or an SVG data URL. Binary and base64 sources are validated as complete UTF-8 SVG documents and sent to QuiverAI as base64 SVG sources. Remote source URLs are fetched by QuiverAI and must resolve to an SVG.
264
+
265
+ Edit reference images are separate from the source SVG. Put them in `providerOptions.quiverai.referenceImages`, not `prompt.images`. Direct provider-option values use `{ url }` or `{ base64 }`; `prepareQuiverAIImageReference` converts an HTTP/HTTPS URL, `URL`, `Uint8Array`, `ArrayBuffer`, base64 string, or supported image data URL to that JSON-safe shape.
266
+
267
+ SVG editing has these validation constraints:
268
+
269
+ - The model must be `arrow-2` or `arrow-2-telos`, and the API key's live model catalog must include the `svg_edit` operation.
270
+ - `prompt.images` must contain exactly one source SVG.
271
+ - `prompt.text` is required, must not be blank, and must contain at most 4000 characters.
272
+ - Binary source SVGs must be complete UTF-8 SVG documents no larger than 200000 bytes.
273
+ - At most four reference images are accepted. Inline references can contain up to 12582912 decoded bytes.
274
+ - Editing returns exactly one SVG per API request. To request multiple edits with `n`, set `maxImagesPerCall: 1` so `generateImage` splits them into separate calls.
275
+ - Masks and generation/vectorization-only provider options are rejected for edits.
276
+ - Edit-only provider options are rejected for generation, vectorization, and animation.
277
+
278
+ The edited SVG is returned as bytes in `result.image.uint8Array`.
279
+
206
280
  ### Animating an SVG
207
281
 
208
282
  Arrow 2 and Arrow 2 Telos can animate an existing SVG. Set `operation` to `animate` and pass exactly one source SVG in `prompt.images`. The text instruction is optional; omit `text` to let QuiverAI choose an animation.
@@ -245,4 +319,4 @@ Source SVGs, text instructions, and remote source URLs are sent to QuiverAI. Ani
245
319
 
246
320
  Arrow 2 models return measured token counts in `result.usage`. Fixed-credit models may return compatibility token counts of zero; their credit charge is available in `result.providerMetadata?.quiverai?.credits` when supplied by the API.
247
321
 
248
- Model availability and supported operations depend on your organization and API key permissions. Consult QuiverAI's [model catalog](https://docs.quiver.ai/developers/models) for current capabilities and billing. Editing and the Responses API are not yet exposed by this provider.
322
+ Model availability and supported operations depend on your organization and API key permissions. Consult QuiverAI's [model catalog](https://docs.quiver.ai/developers/models) for current capabilities and billing. The Responses API is not yet exposed by this provider.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/quiverai",
3
- "version": "2.0.44",
3
+ "version": "2.0.46",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -29,13 +29,14 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/provider": "4.0.17",
33
- "@ai-sdk/provider-utils": "5.0.44"
32
+ "@ai-sdk/provider": "4.0.18",
33
+ "@ai-sdk/provider-utils": "5.0.46"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@ai-sdk/test-server": "2.0.1",
37
37
  "@types/node": "22.19.19",
38
38
  "@vercel/ai-tsconfig": "0.0.0",
39
+ "ai": "7.0.112",
39
40
  "tsup": "^8.5.1",
40
41
  "typescript": "5.8.3",
41
42
  "zod": "3.25.76"
package/src/index.ts CHANGED
@@ -5,4 +5,9 @@ export type {
5
5
  } from './quiverai-provider';
6
6
  export type { QuiverAIImageModelId } from './quiverai-image-settings';
7
7
  export type { QuiverAIImageModelOptions } from './quiverai-image-model-options';
8
+ export {
9
+ prepareQuiverAIImageReference,
10
+ type QuiverAIImageReference,
11
+ type QuiverAIImageReferenceInput,
12
+ } from './prepare-quiverai-image-reference';
8
13
  export { VERSION } from './version';
@@ -0,0 +1,161 @@
1
+ import { InvalidArgumentError } from '@ai-sdk/provider';
2
+ import {
3
+ convertBase64ToUint8Array,
4
+ convertUint8ArrayToBase64,
5
+ detectMediaType,
6
+ } from '@ai-sdk/provider-utils';
7
+
8
+ const MAX_REFERENCE_BASE64_LENGTH = 16_777_216;
9
+ const MAX_REFERENCE_BYTES = 12_582_912;
10
+ const supportedReferenceMediaTypes = new Set([
11
+ 'image/gif',
12
+ 'image/jpeg',
13
+ 'image/png',
14
+ 'image/svg+xml',
15
+ 'image/webp',
16
+ ]);
17
+
18
+ export type QuiverAIImageReference =
19
+ | { url: string }
20
+ | {
21
+ /**
22
+ * Base64-encoded image data without a data URL prefix.
23
+ */
24
+ base64: string;
25
+ };
26
+
27
+ export type QuiverAIImageReferenceInput =
28
+ | string
29
+ | URL
30
+ | Uint8Array
31
+ | ArrayBuffer;
32
+
33
+ /**
34
+ * Converts URL, binary, data URL, or base64 image input into the JSON-safe
35
+ * reference shape accepted by QuiverAI provider options.
36
+ */
37
+ export function prepareQuiverAIImageReference(
38
+ input: QuiverAIImageReferenceInput,
39
+ ): QuiverAIImageReference {
40
+ if (input instanceof URL) {
41
+ return { url: validateQuiverAIImageUrl(input.toString()) };
42
+ }
43
+
44
+ if (typeof input === 'string') {
45
+ if (/^[a-z][a-z\d+.-]*:\/\//i.test(input)) {
46
+ return { url: validateQuiverAIImageUrl(input) };
47
+ }
48
+
49
+ if (input.startsWith('data:')) {
50
+ const match = /^data:([^;,]+);base64,(.+)$/s.exec(input);
51
+ if (match == null || !supportedReferenceMediaTypes.has(match[1])) {
52
+ throw new InvalidArgumentError({
53
+ argument: 'input',
54
+ message:
55
+ 'QuiverAI reference image data URLs must use base64 encoding and a supported image media type.',
56
+ });
57
+ }
58
+
59
+ validateQuiverAIReferenceBase64(match[2], 'input');
60
+ return { base64: match[2] };
61
+ }
62
+
63
+ validateQuiverAIReferenceBase64(input, 'input');
64
+ return { base64: input };
65
+ }
66
+
67
+ const data =
68
+ input instanceof ArrayBuffer
69
+ ? new Uint8Array(input)
70
+ : new Uint8Array(input);
71
+ validateQuiverAIReferenceBytes(data, 'input');
72
+ return { base64: convertUint8ArrayToBase64(data) };
73
+ }
74
+
75
+ export function validateQuiverAIImageUrl(url: string): string {
76
+ let parsed: URL;
77
+ try {
78
+ parsed = new URL(url);
79
+ } catch {
80
+ throw new InvalidArgumentError({
81
+ argument: 'url',
82
+ message: 'QuiverAI image URLs must be valid HTTP or HTTPS URLs.',
83
+ });
84
+ }
85
+
86
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
87
+ throw new InvalidArgumentError({
88
+ argument: 'url',
89
+ message: 'QuiverAI image URLs must use HTTP or HTTPS.',
90
+ });
91
+ }
92
+
93
+ return parsed.toString();
94
+ }
95
+
96
+ export function validateQuiverAIReferenceBase64(
97
+ base64: string,
98
+ argument: string,
99
+ ): void {
100
+ if (base64.length === 0 || base64.length > MAX_REFERENCE_BASE64_LENGTH) {
101
+ throw new InvalidArgumentError({
102
+ argument,
103
+ message: `QuiverAI reference images must contain 1-${MAX_REFERENCE_BASE64_LENGTH} base64 characters.`,
104
+ });
105
+ }
106
+
107
+ let data: Uint8Array;
108
+ try {
109
+ data = convertBase64ToUint8Array(base64);
110
+ } catch (cause) {
111
+ throw new InvalidArgumentError({
112
+ argument,
113
+ message: 'QuiverAI reference image data must be valid base64.',
114
+ cause,
115
+ });
116
+ }
117
+
118
+ validateQuiverAIReferenceBytes(data, argument);
119
+ }
120
+
121
+ function validateQuiverAIReferenceBytes(
122
+ data: Uint8Array,
123
+ argument: string,
124
+ ): void {
125
+ if (data.length === 0 || data.length > MAX_REFERENCE_BYTES) {
126
+ throw new InvalidArgumentError({
127
+ argument,
128
+ message: `QuiverAI reference images must decode to 1-${MAX_REFERENCE_BYTES} bytes.`,
129
+ });
130
+ }
131
+
132
+ const mediaType = isSvg(data)
133
+ ? 'image/svg+xml'
134
+ : detectMediaType({ data, topLevelType: 'image' });
135
+
136
+ if (mediaType == null || !supportedReferenceMediaTypes.has(mediaType)) {
137
+ throw new InvalidArgumentError({
138
+ argument,
139
+ message:
140
+ 'QuiverAI reference images must be PNG, JPEG, WebP, GIF, or SVG data.',
141
+ });
142
+ }
143
+ }
144
+
145
+ function isSvg(data: Uint8Array): boolean {
146
+ let text: string;
147
+ try {
148
+ text = new TextDecoder('utf-8', { fatal: true }).decode(data);
149
+ } catch {
150
+ return false;
151
+ }
152
+
153
+ const normalized = text.replace(/^\uFEFF/, '').trim();
154
+ return (
155
+ /^(?:<\?xml[\s\S]*?\?>\s*)?(?:<!--[\s\S]*?-->\s*)?(?:<!DOCTYPE[\s\S]*?>\s*)?<svg[\s>]/i.test(
156
+ normalized,
157
+ ) &&
158
+ (/<\/svg>\s*$/i.test(normalized) ||
159
+ /<svg(?:\s[^>]*)?\/>\s*$/is.test(normalized))
160
+ );
161
+ }
@@ -21,8 +21,12 @@ export const quiveraiImageModelOptionsSchema = lazySchema(() =>
21
21
  * single image in `prompt.images` / `files`.
22
22
  * - `animate`: Animate an input SVG. Requires a single SVG in
23
23
  * `prompt.images` / `files`; the text prompt is optional.
24
+ * - `edit`: Edit a single SVG from `prompt.images` using `prompt.text`
25
+ * as the required instruction.
24
26
  */
25
- operation: z.enum(['generate', 'vectorize', 'animate']).optional(),
27
+ operation: z
28
+ .enum(['generate', 'vectorize', 'animate', 'edit'])
29
+ .optional(),
26
30
 
27
31
  /**
28
32
  * Extra style guidance for prompt-based generation.
@@ -34,6 +38,25 @@ export const quiveraiImageModelOptionsSchema = lazySchema(() =>
34
38
  */
35
39
  reasoningEffort: z.enum(['low', 'medium', 'high', 'xhigh']).optional(),
36
40
 
41
+ /**
42
+ * Optional reference images for SVG editing. Use
43
+ * `prepareQuiverAIImageReference` to convert binary inputs.
44
+ */
45
+ referenceImages: z
46
+ .array(
47
+ z.union([
48
+ z.object({ url: z.string().min(1) }).strict(),
49
+ z.object({ base64: z.string().min(1).max(16_777_216) }).strict(),
50
+ ]),
51
+ )
52
+ .max(4)
53
+ .optional(),
54
+
55
+ /**
56
+ * Maximum number of edit review and redo steps (0-5).
57
+ */
58
+ maxReviewSteps: z.number().int().min(0).max(5).optional(),
59
+
37
60
  /**
38
61
  * SVG root attributes requested for generation or vectorization.
39
62
  */
@@ -71,6 +94,21 @@ export const quiveraiImageModelOptionsSchema = lazySchema(() =>
71
94
  */
72
95
  maxOutputTokens: z.number().int().min(1).max(131072).optional(),
73
96
 
97
+ /**
98
+ * Provider orchestrator token budget for SVG editing (1-65536).
99
+ */
100
+ orchestratorMaxOutputTokens: z
101
+ .number()
102
+ .int()
103
+ .min(1)
104
+ .max(65536)
105
+ .optional(),
106
+
107
+ /**
108
+ * Provider shallow edit token budget for SVG editing (1-65536).
109
+ */
110
+ shallowMaxOutputTokens: z.number().int().min(1).max(65536).optional(),
111
+
74
112
  /**
75
113
  * Whether to auto-crop the input image before vectorization.
76
114
  * Only used when `operation` is `vectorize`.