getaiapi 1.0.0-alpha.0 → 1.0.0-alpha.2

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/auth.ts","../src/storage.ts","../src/s3-signer.ts","../src/adapters/fal-ai.ts","../src/adapters/replicate.ts","../src/adapters/wavespeed.ts","../src/adapters/openrouter.ts","../src/retry.ts"],"sourcesContent":["import type { ProviderName } from \"./types.js\";\n\nexport class GetAIApiError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"GetAIApiError\";\n }\n}\n\nexport class AuthError extends GetAIApiError {\n readonly provider: ProviderName;\n readonly envVar: string;\n\n constructor(provider: ProviderName, envVar: string) {\n super(`Missing or invalid API key for ${provider}. Set the ${envVar} environment variable.`);\n this.name = \"AuthError\";\n this.provider = provider;\n this.envVar = envVar;\n }\n}\n\nexport class ModelNotFoundError extends GetAIApiError {\n readonly query: string;\n readonly suggestions: string[];\n\n constructor(query: string, suggestions: string[] = []) {\n const hint =\n suggestions.length > 0\n ? ` Did you mean: ${suggestions.join(\", \")}?`\n : \"\";\n super(`Model \"${query}\" not found.${hint}`);\n this.name = \"ModelNotFoundError\";\n this.query = query;\n this.suggestions = suggestions;\n }\n}\n\nexport class NoProviderError extends GetAIApiError {\n readonly query: string;\n readonly model: string;\n readonly requiredProviders: string[];\n readonly availableProviders: string[];\n\n constructor(\n query: string,\n model: string,\n requiredProviders: string[],\n availableProviders: string[],\n ) {\n const envHints: Record<string, string> = {\n \"fal-ai\": \"FAL_KEY\",\n replicate: \"REPLICATE_API_TOKEN\",\n wavespeed: \"WAVESPEED_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n };\n const needed = requiredProviders\n .map((p) => `${p} (${envHints[p] || \"unknown\"})`)\n .join(\" or \");\n super(\n `Model \"${query}\" found but requires ${needed}. You have: ${availableProviders.length > 0 ? availableProviders.join(\", \") : \"none\"}.`,\n );\n this.name = \"NoProviderError\";\n this.query = query;\n this.model = model;\n this.requiredProviders = requiredProviders;\n this.availableProviders = availableProviders;\n }\n}\n\nexport class ValidationError extends GetAIApiError {\n readonly field: string;\n\n constructor(field: string, message: string) {\n super(`Validation error on \"${field}\": ${message}`);\n this.name = \"ValidationError\";\n this.field = field;\n }\n}\n\nexport class ProviderError extends GetAIApiError {\n readonly provider: ProviderName;\n readonly model: string;\n readonly statusCode: number;\n readonly raw: unknown;\n\n constructor(\n provider: ProviderName,\n model: string,\n statusCode: number,\n raw: unknown,\n ) {\n super(\n `Provider ${provider} returned status ${statusCode} for model \"${model}\".`,\n );\n this.name = \"ProviderError\";\n this.provider = provider;\n this.model = model;\n this.statusCode = statusCode;\n this.raw = raw;\n }\n}\n\nexport class TimeoutError extends GetAIApiError {\n readonly provider: ProviderName;\n readonly model: string;\n readonly timeoutMs: number;\n\n constructor(provider: ProviderName, model: string, timeoutMs: number) {\n super(\n `Generation timed out after ${timeoutMs}ms for model \"${model}\" on ${provider}.`,\n );\n this.name = \"TimeoutError\";\n this.provider = provider;\n this.model = model;\n this.timeoutMs = timeoutMs;\n }\n}\n\nexport class RateLimitError extends GetAIApiError {\n readonly provider: ProviderName;\n readonly retryAfterMs: number;\n\n constructor(provider: ProviderName, retryAfterMs: number) {\n super(\n `Rate limited by ${provider}. Retry after ${retryAfterMs}ms.`,\n );\n this.name = \"RateLimitError\";\n this.provider = provider;\n this.retryAfterMs = retryAfterMs;\n }\n}\n\nexport type StorageOperation = \"upload\" | \"delete\" | \"config\";\n\nexport class StorageError extends GetAIApiError {\n readonly operation: StorageOperation;\n readonly statusCode?: number;\n\n constructor(operation: StorageOperation, message: string, statusCode?: number) {\n super(`Storage ${operation} failed: ${message}`);\n this.name = \"StorageError\";\n this.operation = operation;\n this.statusCode = statusCode;\n }\n}\n","import type { ProviderName, ModelEntry } from \"./types.js\";\nimport { AuthError } from \"./errors.js\";\n\nconst ENV_MAP: Record<ProviderName, string> = {\n \"fal-ai\": \"FAL_KEY\",\n replicate: \"REPLICATE_API_TOKEN\",\n wavespeed: \"WAVESPEED_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n};\n\n// Module-level overrides set via configureAuth()\nconst keyOverrides = new Map<string, string>();\n\nexport function configureAuth(keys: Partial<Record<ProviderName, string>>): void {\n for (const [provider, key] of Object.entries(keys)) {\n if (key?.trim()) {\n keyOverrides.set(provider, key.trim());\n }\n }\n}\n\nexport function resetAuth(): void {\n keyOverrides.clear();\n}\n\nexport class AuthManager {\n private keys: Map<string, string>;\n\n constructor() {\n this.keys = new Map();\n // Overrides take priority over env vars\n for (const [provider, key] of keyOverrides) {\n this.keys.set(provider, key);\n }\n for (const [provider, envVar] of Object.entries(ENV_MAP)) {\n if (!this.keys.has(provider)) {\n const key = process.env[envVar]?.trim();\n if (key) this.keys.set(provider, key);\n }\n }\n }\n\n availableProviders(): ProviderName[] {\n return [...this.keys.keys()] as ProviderName[];\n }\n\n getKey(provider: ProviderName): string {\n const key = this.keys.get(provider);\n if (!key) {\n throw new AuthError(provider, ENV_MAP[provider]);\n }\n return key;\n }\n\n canAccess(model: ModelEntry): boolean {\n return model.providers.some((p) => this.keys.has(p.provider));\n }\n\n listAvailableModels(registry: ModelEntry[]): ModelEntry[] {\n return registry.filter((m) => this.canAccess(m));\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { signS3Request, presignS3Url } from \"./s3-signer.js\";\nimport { StorageError } from \"./errors.js\";\nimport type { StorageConfig, UploadResult, UploadOptions } from \"./types.js\";\n\nconst MAX_PRESIGN_EXPIRES = 604800; // 7 days in seconds (S3/R2 limit)\n\nlet storageConfig: StorageConfig | null = null;\n\nfunction parseExpiresIn(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const parsed = parseInt(value, 10);\n if (Number.isNaN(parsed) || parsed <= 0) {\n throw new StorageError(\"config\", `Invalid R2_PRESIGN_EXPIRES_IN: \"${value}\". Must be a positive integer.`);\n }\n return parsed;\n}\n\nexport function configureStorage(config?: StorageConfig): void {\n if (config) {\n storageConfig = config;\n return;\n }\n\n // Fall back to environment variables\n const accountId = process.env.R2_ACCOUNT_ID;\n const bucketName = process.env.R2_BUCKET_NAME;\n const accessKeyId = process.env.R2_ACCESS_KEY_ID;\n const secretAccessKey = process.env.R2_SECRET_ACCESS_KEY;\n\n if (!accountId || !bucketName || !accessKeyId || !secretAccessKey) {\n throw new StorageError(\n \"config\",\n \"Missing R2 credentials. Provide a config object or set R2_ACCOUNT_ID, R2_BUCKET_NAME, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY environment variables.\",\n );\n }\n\n storageConfig = {\n accountId,\n bucketName,\n accessKeyId,\n secretAccessKey,\n publicUrlBase: process.env.R2_PUBLIC_URL,\n autoUpload: false,\n mode: process.env.R2_STORAGE_MODE === 'presigned' ? 'presigned' : undefined,\n presignExpiresIn: parseExpiresIn(process.env.R2_PRESIGN_EXPIRES_IN),\n };\n}\n\nexport function getStorageConfig(): StorageConfig | null {\n return storageConfig;\n}\n\nexport function resetStorage(): void {\n storageConfig = null;\n}\n\nfunction getConfig(): StorageConfig {\n if (!storageConfig) {\n throw new StorageError(\"config\", \"Storage not configured. Call configureStorage() first.\");\n }\n return storageConfig;\n}\n\nfunction buildR2Url(config: StorageConfig, key: string): string {\n return `https://${config.accountId}.r2.cloudflarestorage.com/${config.bucketName}/${key}`;\n}\n\nfunction buildPublicUrl(config: StorageConfig, key: string): string {\n if (config.publicUrlBase) {\n const base = config.publicUrlBase.replace(/\\/$/, \"\");\n return `${base}/${key}`;\n }\n return buildR2Url(config, key);\n}\n\nfunction detectContentType(input: Buffer | Blob | File | ArrayBuffer): string {\n if (input instanceof File) return input.type || \"application/octet-stream\";\n if (input instanceof Blob) return input.type || \"application/octet-stream\";\n return \"application/octet-stream\";\n}\n\nasync function toBuffer(input: Buffer | Blob | File | ArrayBuffer): Promise<Buffer> {\n if (Buffer.isBuffer(input)) return input;\n if (input instanceof ArrayBuffer) return Buffer.from(input);\n if (input instanceof Blob) return Buffer.from(await input.arrayBuffer());\n return Buffer.from(input as ArrayBuffer);\n}\n\nexport async function uploadAsset(\n input: Buffer | Blob | File | ArrayBuffer,\n options?: UploadOptions,\n): Promise<UploadResult> {\n const config = getConfig();\n const buffer = await toBuffer(input);\n\n const maxBytes = options?.maxBytes ?? DEFAULT_MAX_BYTES;\n if (buffer.length > maxBytes) {\n throw new StorageError(\n \"upload\",\n `Asset too large (${buffer.length} bytes, max ${maxBytes})`,\n );\n }\n\n const contentType = options?.contentType ?? detectContentType(input);\n const prefix = options?.prefix ? `${options.prefix.replace(/\\/$/, \"\")}/` : \"\";\n const key = options?.key ?? `${prefix}${randomUUID()}`;\n\n const r2Url = buildR2Url(config, key);\n\n const signed = signS3Request(\n \"PUT\",\n r2Url,\n { \"Content-Type\": contentType, \"Content-Length\": String(buffer.length) },\n buffer,\n {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n },\n );\n\n const response = await fetch(signed.url, {\n method: \"PUT\",\n headers: signed.headers,\n body: new Uint8Array(buffer),\n });\n\n if (!response.ok) {\n const body = await response.text().catch(() => \"\");\n throw new StorageError(\"upload\", `R2 returned ${response.status}: ${body}`, response.status);\n }\n\n const url = config.mode === 'presigned'\n ? validatedPresign(config, key)\n : buildPublicUrl(config, key);\n\n return {\n url,\n key,\n size_bytes: buffer.length,\n content_type: contentType,\n };\n}\n\nfunction validatedPresign(config: StorageConfig, key: string, expiresIn?: number): string {\n const ttl = expiresIn ?? config.presignExpiresIn ?? 3600;\n if (ttl > MAX_PRESIGN_EXPIRES) {\n throw new StorageError(\n \"config\",\n `Presign expiry ${ttl}s exceeds maximum of ${MAX_PRESIGN_EXPIRES}s (7 days).`,\n );\n }\n return presignS3Url(buildR2Url(config, key), {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n }, { expiresIn: ttl });\n}\n\nexport function presignAsset(\n key: string,\n options?: { expiresIn?: number },\n): string {\n const config = getConfig();\n return validatedPresign(config, key, options?.expiresIn);\n}\n\nexport async function deleteAsset(key: string): Promise<void> {\n const config = getConfig();\n const r2Url = buildR2Url(config, key);\n\n const signed = signS3Request(\n \"DELETE\",\n r2Url,\n {},\n null,\n {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n },\n );\n\n const response = await fetch(signed.url, {\n method: \"DELETE\",\n headers: signed.headers,\n });\n\n if (!response.ok && response.status !== 404) {\n const body = await response.text().catch(() => \"\");\n throw new StorageError(\"delete\", `R2 returned ${response.status}: ${body}`, response.status);\n }\n}\n\nconst DEFAULT_PREFIX = \"getaiapi-tmp\";\nconst DEFAULT_MAX_BYTES = 500 * 1024 * 1024; // 500 MB\n\nfunction isBinaryValue(value: unknown): value is Buffer | Blob | File | ArrayBuffer {\n return (\n Buffer.isBuffer(value) ||\n value instanceof File ||\n value instanceof Blob ||\n value instanceof ArrayBuffer\n );\n}\n\nfunction isUrl(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n (value.startsWith(\"http://\") || value.startsWith(\"https://\"))\n );\n}\n\nasync function fetchAndReupload(url: string, maxBytes: number): Promise<string> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new StorageError(\"upload\", `Failed to fetch URL for re-upload: ${url}`);\n }\n\n const contentLength = response.headers.get(\"content-length\");\n if (contentLength && parseInt(contentLength, 10) > maxBytes) {\n throw new StorageError(\n \"upload\",\n `URL content too large (${contentLength} bytes, max ${maxBytes}): ${url}`,\n );\n }\n\n const buffer = Buffer.from(await response.arrayBuffer());\n if (buffer.length > maxBytes) {\n throw new StorageError(\n \"upload\",\n `URL content too large (${buffer.length} bytes, max ${maxBytes}): ${url}`,\n );\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"application/octet-stream\";\n const uploaded = await uploadAsset(buffer, { contentType, prefix: DEFAULT_PREFIX });\n return uploaded.url;\n}\n\nasync function processValue(\n value: unknown,\n shouldReupload: boolean,\n maxBytes: number,\n): Promise<unknown> {\n if (isBinaryValue(value)) {\n const uploaded = await uploadAsset(value, { prefix: DEFAULT_PREFIX });\n return uploaded.url;\n }\n\n if (isUrl(value) && shouldReupload) {\n return fetchAndReupload(value, maxBytes);\n }\n\n if (Array.isArray(value)) {\n const results = await Promise.all(\n value.map((item) => processValue(item, shouldReupload, maxBytes)),\n );\n return results;\n }\n\n if (value !== null && typeof value === \"object\" && !(value instanceof Date)) {\n return processRecord(\n value as Record<string, unknown>,\n shouldReupload,\n maxBytes,\n );\n }\n\n return value;\n}\n\nasync function processRecord(\n obj: Record<string, unknown>,\n shouldReupload: boolean,\n maxBytes: number,\n): Promise<Record<string, unknown>> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = await processValue(value, shouldReupload, maxBytes);\n }\n return result;\n}\n\nexport async function processParamsForUpload(\n params: Record<string, unknown>,\n options?: { reupload?: boolean; maxBytes?: number },\n): Promise<Record<string, unknown>> {\n const config = getStorageConfig();\n if (!config) return params;\n\n const shouldReupload = options?.reupload || config.autoUpload || false;\n const maxBytes = options?.maxBytes ?? DEFAULT_MAX_BYTES;\n\n return processRecord(params, shouldReupload, maxBytes);\n}\n","import { createHmac, createHash } from \"node:crypto\";\n\nexport interface S3Credentials {\n accessKeyId: string;\n secretAccessKey: string;\n region?: string;\n}\n\nexport interface SignedRequest {\n url: string;\n headers: Record<string, string>;\n}\n\nfunction sha256(data: string | Buffer): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\nfunction hmacSha256(key: string | Buffer, data: string): Buffer {\n return createHmac(\"sha256\", key).update(data).digest();\n}\n\nfunction getSigningKey(\n secretKey: string,\n dateStamp: string,\n region: string,\n service: string,\n): Buffer {\n const kDate = hmacSha256(`AWS4${secretKey}`, dateStamp);\n const kRegion = hmacSha256(kDate, region);\n const kService = hmacSha256(kRegion, service);\n return hmacSha256(kService, \"aws4_request\");\n}\n\nfunction toAmzDate(date: Date): { amzDate: string; dateStamp: string } {\n const iso = date.toISOString().replace(/[-:]/g, \"\").replace(/\\.\\d{3}Z$/, \"Z\");\n return {\n amzDate: iso,\n dateStamp: iso.slice(0, 8),\n };\n}\n\nexport function signS3Request(\n method: \"PUT\" | \"DELETE\" | \"GET\",\n url: string,\n headers: Record<string, string>,\n body: Buffer | null,\n credentials: S3Credentials,\n): SignedRequest {\n const region = credentials.region ?? \"auto\";\n const service = \"s3\";\n const parsedUrl = new URL(url);\n const now = new Date();\n const { amzDate, dateStamp } = toAmzDate(now);\n\n const payloadHash = body ? sha256(body) : sha256(\"\");\n\n const allHeaders: Record<string, string> = {\n ...headers,\n host: parsedUrl.host,\n \"x-amz-date\": amzDate,\n \"x-amz-content-sha256\": payloadHash,\n };\n\n // Build lowercased header map once\n const lcHeaders: Record<string, string> = Object.fromEntries(\n Object.entries(allHeaders).map(([k, v]) => [k.toLowerCase(), v.trim()]),\n );\n const sortedKeys = Object.keys(lcHeaders).sort();\n const canonicalHeaders = sortedKeys\n .map((k) => `${k}:${lcHeaders[k]}`)\n .join(\"\\n\") + \"\\n\";\n const signedHeaders = sortedKeys.join(\";\");\n\n // Canonical request\n const canonicalRequest = [\n method,\n parsedUrl.pathname,\n parsedUrl.searchParams.toString(),\n canonicalHeaders,\n signedHeaders,\n payloadHash,\n ].join(\"\\n\");\n\n // String to sign\n const scope = `${dateStamp}/${region}/${service}/aws4_request`;\n const stringToSign = [\n \"AWS4-HMAC-SHA256\",\n amzDate,\n scope,\n sha256(canonicalRequest),\n ].join(\"\\n\");\n\n // Signing key and signature\n const signingKey = getSigningKey(credentials.secretAccessKey, dateStamp, region, service);\n const signature = createHmac(\"sha256\", signingKey)\n .update(stringToSign)\n .digest(\"hex\");\n\n const authorization = `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${scope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;\n\n return {\n url,\n headers: {\n ...lcHeaders,\n authorization,\n },\n };\n}\n\nexport interface PresignOptions {\n expiresIn?: number; // seconds, default 3600\n}\n\nexport function presignS3Url(\n url: string,\n credentials: S3Credentials,\n options?: PresignOptions,\n): string {\n const region = credentials.region ?? \"auto\";\n const service = \"s3\";\n const parsedUrl = new URL(url);\n const now = new Date();\n const { amzDate, dateStamp } = toAmzDate(now);\n const expiresIn = options?.expiresIn ?? 3600;\n\n const host = parsedUrl.host;\n const signedHeaders = \"host\";\n const scope = `${dateStamp}/${region}/${service}/aws4_request`;\n const credential = `${credentials.accessKeyId}/${scope}`;\n\n // Set query parameters for presigned URL\n const queryParams = new URLSearchParams({\n \"X-Amz-Algorithm\": \"AWS4-HMAC-SHA256\",\n \"X-Amz-Credential\": credential,\n \"X-Amz-Date\": amzDate,\n \"X-Amz-Expires\": String(expiresIn),\n \"X-Amz-SignedHeaders\": signedHeaders,\n });\n\n // Canonical request with UNSIGNED-PAYLOAD\n const canonicalRequest = [\n \"GET\",\n parsedUrl.pathname,\n queryParams.toString(),\n `host:${host}\\n`,\n signedHeaders,\n \"UNSIGNED-PAYLOAD\",\n ].join(\"\\n\");\n\n // String to sign\n const stringToSign = [\n \"AWS4-HMAC-SHA256\",\n amzDate,\n scope,\n sha256(canonicalRequest),\n ].join(\"\\n\");\n\n // Signing key and signature\n const signingKey = getSigningKey(credentials.secretAccessKey, dateStamp, region, service);\n const signature = createHmac(\"sha256\", signingKey)\n .update(stringToSign)\n .digest(\"hex\");\n\n queryParams.set(\"X-Amz-Signature\", signature);\n\n return `${parsedUrl.origin}${parsedUrl.pathname}?${queryParams.toString()}`;\n}\n","import type { ProviderAdapter, ProviderResponse, OutputItem, OutputMapping } from \"./base.js\";\nimport { AuthError, RateLimitError, ProviderError, TimeoutError } from \"../errors.js\";\n\nconst BASE_URL = \"https://queue.fal.run\";\n\n/**\n * Extract base endpoint (owner/alias) for polling URLs.\n * The fal.ai queue API uses the full path for submit but only\n * owner/alias for status and result requests.\n * e.g. \"fal-ai/nano-banana-pro/edit\" → \"fal-ai/nano-banana-pro\"\n */\nfunction getBaseEndpoint(endpoint: string): string {\n const parts = endpoint.split(\"/\");\n if (parts.length <= 2) return endpoint;\n return `${parts[0]}/${parts[1]}`;\n}\n\nasync function handleHttpErrors(\n response: Response,\n endpoint: string,\n): Promise<void> {\n if (response.ok) return;\n\n const status = response.status;\n\n if (status === 401) {\n throw new AuthError(\"fal-ai\", \"FAL_KEY\");\n }\n\n if (status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const retryMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : 60000;\n throw new RateLimitError(\"fal-ai\", retryMs);\n }\n\n let raw: unknown;\n try {\n raw = await response.json();\n } catch {\n raw = await response.text().catch(() => null);\n }\n\n throw new ProviderError(\"fal-ai\", endpoint, status, raw);\n}\n\nfunction authHeaders(auth: string): Record<string, string> {\n return {\n Authorization: `Key ${auth}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nexport const falAiAdapter: ProviderAdapter = {\n name: \"fal-ai\",\n\n async submit(\n endpoint: string,\n params: Record<string, unknown>,\n auth: string,\n ): Promise<ProviderResponse> {\n const url = `${BASE_URL}/${endpoint}`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: authHeaders(auth),\n body: JSON.stringify(params),\n });\n\n await handleHttpErrors(response, endpoint);\n\n const data = (await response.json()) as { request_id: string };\n\n return {\n id: data.request_id,\n status: \"pending\",\n };\n },\n\n async poll(\n taskId: string,\n auth: string,\n endpoint?: string,\n ): Promise<ProviderResponse> {\n if (!endpoint) {\n throw new ProviderError(\"fal-ai\", \"unknown\", 400, \"endpoint is required for polling\");\n }\n\n // Check status — use base endpoint (owner/alias) for polling\n const baseEndpoint = getBaseEndpoint(endpoint);\n const statusUrl = `${BASE_URL}/${baseEndpoint}/requests/${taskId}/status`;\n const statusResponse = await fetch(statusUrl, {\n headers: { Authorization: `Key ${auth}` },\n });\n\n await handleHttpErrors(statusResponse, endpoint);\n\n const statusData = (await statusResponse.json()) as {\n status: \"IN_QUEUE\" | \"IN_PROGRESS\" | \"COMPLETED\" | \"FAILED\";\n error?: string;\n };\n\n if (statusData.status === \"FAILED\") {\n return {\n id: taskId,\n status: \"failed\",\n error: statusData.error ?? \"Unknown error\",\n };\n }\n\n if (statusData.status !== \"COMPLETED\") {\n return {\n id: taskId,\n status: \"processing\",\n };\n }\n\n // Fetch result\n const resultUrl = `${BASE_URL}/${baseEndpoint}/requests/${taskId}`;\n const resultResponse = await fetch(resultUrl, {\n headers: { Authorization: `Key ${auth}` },\n });\n\n await handleHttpErrors(resultResponse, endpoint);\n\n const output = await resultResponse.json();\n\n return {\n id: taskId,\n status: \"completed\",\n output,\n };\n },\n\n parseOutput(raw: unknown, outputMapping: OutputMapping): OutputItem[] {\n const data = raw as Record<string, unknown>;\n const path = outputMapping.extract_path;\n\n if (path === \"images[].url\") {\n const images = data.images as Array<{\n url: string;\n content_type?: string;\n }>;\n if (!Array.isArray(images)) return [];\n return images.map((img) => ({\n type: outputMapping.type,\n url: img.url,\n content_type: img.content_type ?? outputMapping.content_type ?? \"image/jpeg\",\n }));\n }\n\n if (path === \"image.url\") {\n const image = data.image as { url: string; content_type?: string } | undefined;\n if (!image?.url) return [];\n return [\n {\n type: outputMapping.type,\n url: image.url,\n content_type: image.content_type ?? outputMapping.content_type ?? \"image/png\",\n },\n ];\n }\n\n if (path === \"video.url\") {\n const video = data.video as { url: string; content_type?: string } | undefined;\n if (!video?.url) return [];\n return [\n {\n type: outputMapping.type,\n url: video.url,\n content_type: video.content_type ?? outputMapping.content_type ?? \"video/mp4\",\n },\n ];\n }\n\n if (path === \"audio.url\") {\n const audio = data.audio as { url: string; content_type?: string } | undefined;\n if (!audio?.url) return [];\n return [\n {\n type: outputMapping.type,\n url: audio.url,\n content_type: audio.content_type ?? outputMapping.content_type ?? \"audio/mpeg\",\n },\n ];\n }\n\n if (path === \"audio_file.url\") {\n const audioFile = data.audio_file as { url: string; content_type?: string } | undefined;\n if (!audioFile?.url) return [];\n return [\n {\n type: outputMapping.type,\n url: audioFile.url,\n content_type: audioFile.content_type ?? outputMapping.content_type ?? \"audio/mpeg\",\n },\n ];\n }\n\n if (path === \"audio_url\") {\n const audioUrl = data.audio_url as { url: string; content_type?: string } | string | undefined;\n if (!audioUrl) return [];\n const url = typeof audioUrl === \"string\" ? audioUrl : audioUrl.url;\n if (!url) return [];\n return [\n {\n type: outputMapping.type,\n url,\n content_type: (typeof audioUrl === \"object\" ? audioUrl.content_type : undefined) ?? outputMapping.content_type ?? \"audio/mpeg\",\n },\n ];\n }\n\n if (path === \"video_url\") {\n const videoUrl = data.video_url as string | undefined;\n if (!videoUrl) return [];\n return [\n {\n type: outputMapping.type,\n url: videoUrl,\n content_type: outputMapping.content_type ?? \"video/mp4\",\n },\n ];\n }\n\n return [];\n },\n};\n\n/**\n * Submit a request and poll until completion or timeout.\n */\nexport async function submitAndPoll(\n endpoint: string,\n params: Record<string, unknown>,\n auth: string,\n options?: {\n timeoutMs?: number;\n intervalMs?: number;\n maxIntervalMs?: number;\n },\n): Promise<ProviderResponse> {\n const timeoutMs = options?.timeoutMs ?? 300_000;\n const startInterval = options?.intervalMs ?? 1000;\n const maxInterval = options?.maxIntervalMs ?? 5000;\n\n const submitted = await falAiAdapter.submit(endpoint, params, auth);\n const taskId = submitted.id;\n\n const start = Date.now();\n let interval = startInterval;\n\n while (Date.now() - start < timeoutMs) {\n await sleep(interval);\n\n const result = await falAiAdapter.poll(taskId, auth, endpoint);\n\n if (result.status === \"completed\" || result.status === \"failed\") {\n return result;\n }\n\n interval = Math.min(interval + 500, maxInterval);\n }\n\n throw new TimeoutError(\"fal-ai\", endpoint, timeoutMs);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import type { ProviderAdapter, ProviderResponse, OutputItem, OutputMapping } from \"./base.js\";\nimport { AuthError, RateLimitError, ProviderError } from \"../errors.js\";\n\nconst BASE_URL = \"https://api.replicate.com/v1\";\n\nasync function handleHttpErrors(\n response: Response,\n endpoint: string,\n): Promise<void> {\n if (response.ok) return;\n\n const status = response.status;\n\n if (status === 401) {\n throw new AuthError(\"replicate\", \"REPLICATE_API_TOKEN\");\n }\n\n if (status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const retryMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : 60000;\n throw new RateLimitError(\"replicate\", retryMs);\n }\n\n let raw: unknown;\n try {\n raw = await response.json();\n } catch {\n raw = await response.text().catch(() => null);\n }\n\n throw new ProviderError(\"replicate\", endpoint, status, raw);\n}\n\nfunction authHeaders(auth: string): Record<string, string> {\n return {\n Authorization: `Bearer ${auth}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nfunction inferContentType(url: string): string {\n const lower = url.toLowerCase();\n if (lower.includes(\".png\")) return \"image/png\";\n if (lower.includes(\".jpg\") || lower.includes(\".jpeg\")) return \"image/jpeg\";\n if (lower.includes(\".webp\")) return \"image/webp\";\n if (lower.includes(\".mp4\")) return \"video/mp4\";\n if (lower.includes(\".mp3\")) return \"audio/mpeg\";\n if (lower.includes(\".wav\")) return \"audio/wav\";\n return \"image/jpeg\";\n}\n\n// Cache version hashes to avoid repeated lookups and rate limits\nconst versionCache = new Map<string, string>();\n\n// Endpoints that need the legacy /predictions route (404 on /models/.../predictions)\nconst legacyEndpoints = new Set<string>();\n\nasync function fetchLatestVersion(endpoint: string, auth: string): Promise<string> {\n const cached = versionCache.get(endpoint);\n if (cached) return cached;\n\n const url = `${BASE_URL}/models/${endpoint}`;\n const response = await fetch(url, {\n headers: { Authorization: `Bearer ${auth}` },\n });\n\n await handleHttpErrors(response, endpoint);\n\n const data = (await response.json()) as {\n latest_version?: { id: string };\n };\n\n if (!data.latest_version?.id) {\n throw new ProviderError(\"replicate\", endpoint, 404, \"No version found for model\");\n }\n\n versionCache.set(endpoint, data.latest_version.id);\n return data.latest_version.id;\n}\n\nasync function submitWithVersion(\n endpoint: string,\n params: Record<string, unknown>,\n auth: string,\n): Promise<ProviderResponse> {\n const version = await fetchLatestVersion(endpoint, auth);\n const response = await fetch(`${BASE_URL}/predictions`, {\n method: \"POST\",\n headers: authHeaders(auth),\n body: JSON.stringify({ version, input: params }),\n });\n\n await handleHttpErrors(response, endpoint);\n const data = (await response.json()) as { id: string };\n return { id: data.id, status: \"pending\" };\n}\n\nexport const replicateAdapter: ProviderAdapter = {\n name: \"replicate\",\n\n async submit(\n endpoint: string,\n params: Record<string, unknown>,\n auth: string,\n ): Promise<ProviderResponse> {\n // Known legacy endpoints skip straight to version-based submission\n if (legacyEndpoints.has(endpoint)) {\n return submitWithVersion(endpoint, params, auth);\n }\n\n // Try the newer /models/{owner}/{name}/predictions endpoint first\n const modelsUrl = `${BASE_URL}/models/${endpoint}/predictions`;\n const response = await fetch(modelsUrl, {\n method: \"POST\",\n headers: authHeaders(auth),\n body: JSON.stringify({ input: params }),\n });\n\n if (response.status !== 404) {\n await handleHttpErrors(response, endpoint);\n const data = (await response.json()) as { id: string };\n return { id: data.id, status: \"pending\" };\n }\n\n // 404: remember this endpoint and fall back to version-based submission\n legacyEndpoints.add(endpoint);\n return submitWithVersion(endpoint, params, auth);\n },\n\n async poll(\n taskId: string,\n auth: string,\n ): Promise<ProviderResponse> {\n const url = `${BASE_URL}/predictions/${taskId}`;\n const response = await fetch(url, {\n headers: { Authorization: `Bearer ${auth}` },\n });\n\n await handleHttpErrors(response, taskId);\n\n const data = (await response.json()) as {\n id: string;\n status: \"starting\" | \"processing\" | \"succeeded\" | \"failed\" | \"canceled\";\n output?: unknown;\n error?: string;\n };\n\n if (data.status === \"succeeded\") {\n return {\n id: data.id,\n status: \"completed\",\n output: data.output,\n };\n }\n\n if (data.status === \"failed\" || data.status === \"canceled\") {\n return {\n id: data.id,\n status: \"failed\",\n error: data.error ?? `Prediction ${data.status}`,\n };\n }\n\n // starting or processing\n return {\n id: data.id,\n status: \"processing\",\n };\n },\n\n parseOutput(raw: unknown, outputMapping: OutputMapping): OutputItem[] {\n // Replicate output is typically string[] (URLs)\n if (!Array.isArray(raw)) return [];\n\n return (raw as string[]).map((url) => ({\n type: outputMapping.type,\n url,\n content_type: outputMapping.content_type ?? inferContentType(url),\n }));\n },\n};\n","import type { ProviderAdapter, ProviderResponse, OutputItem, OutputMapping } from \"./base.js\";\nimport { AuthError, RateLimitError, ProviderError } from \"../errors.js\";\n\nconst BASE_URL = \"https://api.wavespeed.ai/api/v3\";\n\nasync function handleHttpErrors(\n response: Response,\n endpoint: string,\n): Promise<void> {\n if (response.ok) return;\n\n const status = response.status;\n\n if (status === 401) {\n throw new AuthError(\"wavespeed\", \"WAVESPEED_API_KEY\");\n }\n\n if (status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const retryMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : 60000;\n throw new RateLimitError(\"wavespeed\", retryMs);\n }\n\n let raw: unknown;\n try {\n raw = await response.json();\n } catch {\n raw = await response.text().catch(() => null);\n }\n\n throw new ProviderError(\"wavespeed\", endpoint, status, raw);\n}\n\nfunction authHeaders(auth: string): Record<string, string> {\n return {\n Authorization: `Bearer ${auth}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nfunction inferContentType(url: string): string {\n const ext = url.split(\".\").pop()?.toLowerCase()?.split(\"?\")[0];\n switch (ext) {\n case \"png\":\n return \"image/png\";\n case \"jpg\":\n case \"jpeg\":\n return \"image/jpeg\";\n case \"webp\":\n return \"image/webp\";\n case \"gif\":\n return \"image/gif\";\n case \"mp4\":\n return \"video/mp4\";\n case \"mp3\":\n return \"audio/mpeg\";\n case \"wav\":\n return \"audio/wav\";\n default:\n return \"application/octet-stream\";\n }\n}\n\nexport const wavespeedAdapter: ProviderAdapter = {\n name: \"wavespeed\",\n\n async submit(\n endpoint: string,\n params: Record<string, unknown>,\n auth: string,\n ): Promise<ProviderResponse> {\n const url = `${BASE_URL}/${endpoint}`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: authHeaders(auth),\n body: JSON.stringify(params),\n });\n\n await handleHttpErrors(response, endpoint);\n\n const json = (await response.json()) as {\n data: { id: string; status: string };\n };\n\n return {\n id: json.data.id,\n status: \"pending\",\n };\n },\n\n async poll(\n taskId: string,\n auth: string,\n ): Promise<ProviderResponse> {\n const url = `${BASE_URL}/predictions/${taskId}/result`;\n const response = await fetch(url, {\n headers: { Authorization: `Bearer ${auth}` },\n });\n\n await handleHttpErrors(response, `predictions/${taskId}/result`);\n\n const json = (await response.json()) as {\n data: {\n id: string;\n status: string;\n outputs?: string[];\n error?: string;\n };\n };\n\n const { data } = json;\n\n if (data.status === \"failed\") {\n return {\n id: taskId,\n status: \"failed\",\n error: data.error ?? \"Unknown error\",\n };\n }\n\n if (data.status === \"completed\") {\n return {\n id: taskId,\n status: \"completed\",\n output: data,\n };\n }\n\n // created or processing\n return {\n id: taskId,\n status: \"processing\",\n };\n },\n\n parseOutput(raw: unknown, outputMapping: OutputMapping): OutputItem[] {\n const data = raw as Record<string, unknown>;\n const outputs = data.outputs as string[] | undefined;\n\n if (!Array.isArray(outputs)) return [];\n\n return outputs.map((url) => ({\n type: outputMapping.type,\n url,\n content_type: outputMapping.content_type ?? inferContentType(url),\n }));\n },\n};\n","import type { ProviderAdapter, ProviderResponse, OutputItem, OutputMapping } from \"./base.js\";\nimport { AuthError, RateLimitError, ProviderError } from \"../errors.js\";\n\nconst BASE_URL = \"https://openrouter.ai/api/v1\";\n\nasync function handleHttpErrors(\n response: Response,\n endpoint: string,\n): Promise<void> {\n if (response.ok) return;\n\n const status = response.status;\n\n if (status === 401) {\n throw new AuthError(\"openrouter\", \"OPENROUTER_API_KEY\");\n }\n\n if (status === 429) {\n const retryAfter = response.headers.get(\"retry-after\");\n const retryMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : 60000;\n throw new RateLimitError(\"openrouter\", retryMs);\n }\n\n let raw: unknown;\n try {\n raw = await response.json();\n } catch {\n raw = await response.text().catch(() => null);\n }\n\n throw new ProviderError(\"openrouter\", endpoint, status, raw);\n}\n\nfunction authHeaders(auth: string): Record<string, string> {\n return {\n Authorization: `Bearer ${auth}`,\n \"Content-Type\": \"application/json\",\n \"X-Title\": \"getaiapi\",\n };\n}\n\nexport const openRouterAdapter: ProviderAdapter = {\n name: \"openrouter\",\n\n async submit(\n endpoint: string,\n params: Record<string, unknown>,\n auth: string,\n ): Promise<ProviderResponse> {\n const { prompt, system, temperature, max_tokens, top_p, ...rest } = params;\n\n const messages: Array<{ role: string; content: string }> = [];\n\n if (system && typeof system === \"string\") {\n messages.push({ role: \"system\", content: system });\n }\n\n messages.push({ role: \"user\", content: (prompt as string) ?? \"\" });\n\n const body: Record<string, unknown> = {\n model: endpoint,\n messages,\n ...rest,\n };\n\n if (temperature !== undefined) body.temperature = temperature;\n if (max_tokens !== undefined) body.max_tokens = max_tokens;\n if (top_p !== undefined) body.top_p = top_p;\n\n const url = `${BASE_URL}/chat/completions`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: authHeaders(auth),\n body: JSON.stringify(body),\n });\n\n await handleHttpErrors(response, endpoint);\n\n const data = await response.json() as {\n id: string;\n choices: Array<{ message: { content: string } }>;\n usage?: {\n total_tokens?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n };\n\n return {\n id: data.id,\n status: \"completed\",\n output: data,\n };\n },\n\n async poll(\n taskId: string,\n ): Promise<ProviderResponse> {\n // OpenRouter is synchronous — submit() returns the completed result.\n // poll() should never be called, but return completed as a no-op.\n return {\n id: taskId,\n status: \"completed\",\n };\n },\n\n parseOutput(raw: unknown, outputMapping: OutputMapping): OutputItem[] {\n const data = raw as Record<string, unknown>;\n const choices = data.choices as Array<{ message: { content: string } }> | undefined;\n\n if (!Array.isArray(choices) || choices.length === 0) return [];\n\n const content = choices[0].message?.content;\n if (typeof content !== \"string\") return [];\n\n return [\n {\n type: outputMapping.type,\n content,\n content_type: outputMapping.content_type ?? \"text/plain\",\n },\n ];\n },\n};\n","import {\n AuthError,\n ValidationError,\n ModelNotFoundError,\n ProviderError,\n RateLimitError,\n TimeoutError,\n} from './errors.js'\n\nexport interface RetryOptions {\n maxRetries: number\n initialDelayMs: number\n maxDelayMs: number\n timeoutMs: number\n}\n\nconst DEFAULT_OPTIONS: RetryOptions = {\n maxRetries: 3,\n initialDelayMs: 1000,\n maxDelayMs: 10000,\n timeoutMs: 300_000,\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction isRetryable(error: unknown): boolean {\n // Never retry auth, validation, or model-not-found errors\n if (\n error instanceof AuthError ||\n error instanceof ValidationError ||\n error instanceof ModelNotFoundError\n ) {\n return false\n }\n\n // Retry rate limit errors (429)\n if (error instanceof RateLimitError) {\n return true\n }\n\n // ProviderError: only retry 5xx, not 4xx\n if (error instanceof ProviderError) {\n return error.statusCode >= 500\n }\n\n // Network errors (TypeError from fetch, etc.) are retryable\n if (error instanceof TypeError) {\n return true\n }\n\n return false\n}\n\nfunction getDelayMs(\n error: unknown,\n attempt: number,\n options: RetryOptions,\n): number {\n // RateLimitError has its own retry-after\n if (error instanceof RateLimitError) {\n return error.retryAfterMs\n }\n\n // Exponential backoff with jitter\n const jitter = Math.random() * options.initialDelayMs * 0.5\n const delay = options.initialDelayMs * Math.pow(2, attempt) + jitter\n return Math.min(delay, options.maxDelayMs)\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options?: Partial<RetryOptions>,\n): Promise<T> {\n const opts: RetryOptions = { ...DEFAULT_OPTIONS, ...options }\n const startTime = Date.now()\n let lastError: unknown\n\n for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {\n // Check total timeout before attempting\n if (attempt > 0) {\n const elapsed = Date.now() - startTime\n if (elapsed >= opts.timeoutMs) {\n throw new TimeoutError('unknown', 'unknown', opts.timeoutMs)\n }\n }\n\n try {\n return await fn()\n } catch (error) {\n lastError = error\n\n // If not retryable, throw immediately\n if (!isRetryable(error)) {\n throw error\n }\n\n // If we've exhausted retries, throw\n if (attempt >= opts.maxRetries) {\n throw error\n }\n\n const delay = getDelayMs(error, attempt, opts)\n\n // Check if waiting would exceed timeout\n const elapsed = Date.now() - startTime\n if (elapsed + delay >= opts.timeoutMs) {\n throw new TimeoutError('unknown', 'unknown', opts.timeoutMs)\n }\n\n await sleep(delay)\n }\n }\n\n /* v8 ignore next 3 */\n // Unreachable: the for loop always returns or throws\n throw lastError as Error\n}\n"],"mappings":"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","names":["BASE_URL","handleHttpErrors","authHeaders","BASE_URL","handleHttpErrors","authHeaders","inferContentType","BASE_URL","handleHttpErrors","authHeaders"]}
@@ -1,125 +0,0 @@
1
- type OutputType = 'image' | 'video' | 'audio' | 'text' | '3d' | 'segmentation';
2
- type InputType = 'text' | 'image' | 'audio' | 'video';
3
- type ProviderName = 'fal-ai' | 'replicate' | 'wavespeed' | 'openrouter';
4
- interface ModelEntryV2 {
5
- canonical_name: string;
6
- aliases: string[];
7
- modality: {
8
- inputs: InputType[];
9
- outputs: OutputType[];
10
- };
11
- providers: ProviderBindingV2[];
12
- }
13
- interface ProviderBindingV2 {
14
- provider: ProviderName;
15
- skill_id: string;
16
- endpoint: string;
17
- auth_env: string;
18
- param_map: Record<string, string | string[]>;
19
- output_map: OutputMapping;
20
- }
21
- interface OutputMapping {
22
- type: OutputType;
23
- extract_path: string;
24
- content_type?: string;
25
- }
26
- interface GenerateRequestV2 {
27
- model: string;
28
- provider?: ProviderName;
29
- prompt?: string;
30
- image?: string | File;
31
- images?: (string | File)[];
32
- audio?: string | File;
33
- video?: string | File;
34
- negative_prompt?: string;
35
- count?: number;
36
- size?: string | {
37
- width: number;
38
- height: number;
39
- };
40
- seed?: number;
41
- guidance?: number;
42
- steps?: number;
43
- strength?: number;
44
- format?: 'png' | 'jpeg' | 'webp' | 'mp4' | 'mp3' | 'wav' | 'obj' | 'glb';
45
- quality?: number;
46
- safety?: boolean;
47
- options?: Record<string, unknown>;
48
- }
49
- interface GenerateResponseV2 {
50
- id: string;
51
- model: string;
52
- provider: string;
53
- status: 'completed' | 'failed';
54
- outputs: OutputItemV2[];
55
- metadata: {
56
- seed?: number;
57
- inference_time_ms?: number;
58
- cost?: number;
59
- safety_flagged?: boolean;
60
- tokens?: number;
61
- prompt_tokens?: number;
62
- completion_tokens?: number;
63
- };
64
- }
65
- interface OutputItemV2 {
66
- type: OutputType;
67
- url?: string;
68
- content?: string;
69
- content_type: string;
70
- size_bytes?: number;
71
- }
72
- interface ListModelsFiltersV2 {
73
- input?: InputType;
74
- output?: OutputType;
75
- provider?: ProviderName;
76
- query?: string;
77
- }
78
-
79
- declare function generate(request: GenerateRequestV2): Promise<GenerateResponseV2>;
80
-
81
- /**
82
- * Lists models filtered by modality, provider, or text query.
83
- * Category is derived, not stored — filter by input/output modality instead.
84
- */
85
- declare function listModels(filters?: ListModelsFiltersV2): ModelEntryV2[];
86
- /**
87
- * Derives a display category label from modality.
88
- * e.g., inputs=["text"], outputs=["image"] → "text-to-image"
89
- * e.g., inputs=["image","text"], outputs=["video"] → "image,text-to-video"
90
- */
91
- declare function deriveCategory(model: ModelEntryV2): string;
92
-
93
- /**
94
- * Reads and parses registry/v2/registry.json.
95
- * Caches the result so the file is only loaded once.
96
- */
97
- declare function loadRegistry(): ModelEntryV2[];
98
- /**
99
- * Resolves a user's model name query to a matching ModelEntryV2.
100
- *
101
- * Resolution order:
102
- * 1. Exact canonical match
103
- * 2. Exact alias match
104
- * 3. Normalized canonical match
105
- * 4. Normalized alias match
106
- * 5. No match -> throw with suggestions
107
- */
108
- declare function resolveModel(query: string, availableProviders?: ProviderName[]): ModelEntryV2;
109
- /**
110
- * Clears the registry cache. Useful for testing.
111
- */
112
- declare function clearRegistryCache(): void;
113
-
114
- /**
115
- * Maps a universal GenerateRequestV2 to provider-specific params
116
- * using the binding's own param_map. No template lookup needed.
117
- */
118
- declare function mapInput(request: GenerateRequestV2, binding: ProviderBindingV2): Record<string, unknown>;
119
- /**
120
- * Maps raw provider response to OutputItemV2[] using the output mapping.
121
- * Same logic as v1 — output_map was already per-model.
122
- */
123
- declare function mapOutput(raw: unknown, outputMapping: OutputMapping): OutputItemV2[];
124
-
125
- export { type GenerateRequestV2, type GenerateResponseV2, type InputType, type ListModelsFiltersV2, type ModelEntryV2, type OutputItemV2, type OutputMapping, type OutputType, type ProviderBindingV2, type ProviderName, clearRegistryCache, deriveCategory, generate, listModels, loadRegistry, mapInput, mapOutput, resolveModel };
package/dist/v2/index.js DELETED
@@ -1,368 +0,0 @@
1
- import {
2
- AuthManager,
3
- ProviderError,
4
- ValidationError,
5
- falAiAdapter,
6
- openRouterAdapter,
7
- processParamsForUpload,
8
- replicateAdapter,
9
- wavespeedAdapter,
10
- withRetry
11
- } from "../chunk-P7XV6JOH.js";
12
-
13
- // src/v2/gateway.ts
14
- import { randomUUID } from "crypto";
15
-
16
- // src/v2/registry.ts
17
- import { readFileSync } from "fs";
18
- import { resolve, dirname } from "path";
19
- import { fileURLToPath } from "url";
20
- var __filename = fileURLToPath(import.meta.url);
21
- var __dirname = dirname(__filename);
22
- var registryCache = null;
23
- function loadRegistry() {
24
- if (registryCache) return registryCache;
25
- let dir = __dirname;
26
- for (let i = 0; i < 5; i++) {
27
- const candidate = resolve(dir, "registry", "v2", "registry.json");
28
- try {
29
- const raw = readFileSync(candidate, "utf-8");
30
- registryCache = JSON.parse(raw);
31
- return registryCache;
32
- } catch {
33
- dir = dirname(dir);
34
- }
35
- }
36
- throw new Error(
37
- "Could not find registry/v2/registry.json. Searched upward from: " + __dirname
38
- );
39
- }
40
- function normalizeModelName(input) {
41
- return input.toLowerCase().replace(/[^a-z0-9]/g, "").replace(/(?<=\d)v(?=\d)/g, "").replace(/v(?=\d)/g, "");
42
- }
43
- function resolveModel(query, availableProviders) {
44
- if (!query || typeof query !== "string" || query.trim() === "") {
45
- throw new Error("Model name is required");
46
- }
47
- const trimmedQuery = query.trim();
48
- const registry = loadRegistry();
49
- let matched;
50
- matched = registry.find((e) => e.canonical_name === trimmedQuery);
51
- if (!matched) {
52
- matched = registry.find((e) => e.aliases.some((a) => a === trimmedQuery));
53
- }
54
- if (!matched) {
55
- const normalizedQuery = normalizeModelName(trimmedQuery);
56
- matched = registry.find(
57
- (e) => normalizeModelName(e.canonical_name) === normalizedQuery
58
- );
59
- if (!matched) {
60
- matched = registry.find(
61
- (e) => e.aliases.some((a) => normalizeModelName(a) === normalizedQuery)
62
- );
63
- }
64
- }
65
- if (!matched) {
66
- const suggestions = findSuggestions(trimmedQuery, registry);
67
- throw new Error(
68
- `Model "${trimmedQuery}" not found.${suggestions.length > 0 ? ` Did you mean: ${suggestions.join(", ")}?` : ""}`
69
- );
70
- }
71
- if (availableProviders && availableProviders.length > 0) {
72
- const filteredProviders = matched.providers.filter(
73
- (p) => availableProviders.includes(p.provider)
74
- );
75
- if (filteredProviders.length === 0) {
76
- throw new Error(
77
- `No available provider for "${matched.canonical_name}". Model supports: ${matched.providers.map((p) => p.provider).join(", ")}`
78
- );
79
- }
80
- return { ...matched, providers: filteredProviders };
81
- }
82
- return matched;
83
- }
84
- function findSuggestions(query, registry) {
85
- const normalizedQuery = normalizeModelName(query);
86
- if (normalizedQuery === "") return [];
87
- const matches = registry.filter((e) => {
88
- const normalizedCanonical = normalizeModelName(e.canonical_name);
89
- if (normalizedCanonical.startsWith(normalizedQuery) || normalizedCanonical.includes(normalizedQuery) || normalizedQuery.startsWith(normalizedCanonical)) {
90
- return true;
91
- }
92
- const minLen = Math.min(normalizedQuery.length, normalizedCanonical.length);
93
- let shared = 0;
94
- for (let i = 0; i < minLen; i++) {
95
- if (normalizedQuery[i] === normalizedCanonical[i]) shared++;
96
- else break;
97
- }
98
- return shared >= 3 && shared >= normalizedQuery.length * 0.3;
99
- });
100
- return matches.sort((a, b) => a.canonical_name.length - b.canonical_name.length).slice(0, 5).map((e) => e.canonical_name);
101
- }
102
- function clearRegistryCache() {
103
- registryCache = null;
104
- }
105
-
106
- // src/v2/mapper.ts
107
- function mapInput(request, binding) {
108
- const result = {};
109
- const provider = binding.provider;
110
- for (const [universal, providerKey] of Object.entries(binding.param_map)) {
111
- const value = request[universal];
112
- if (value === void 0 || value === null) continue;
113
- const transformed = applyTransform(universal, value, provider);
114
- if (Array.isArray(providerKey)) {
115
- if (typeof transformed === "object" && transformed !== null && !Array.isArray(transformed)) {
116
- const obj = transformed;
117
- for (const key of providerKey) {
118
- if (obj[key] !== void 0) {
119
- result[key] = obj[key];
120
- }
121
- }
122
- }
123
- } else {
124
- result[providerKey] = transformed;
125
- }
126
- }
127
- if (request.options) {
128
- for (const [key, val] of Object.entries(request.options)) {
129
- result[key] = val;
130
- }
131
- }
132
- return result;
133
- }
134
- function applyTransform(universal, value, provider) {
135
- if (universal === "safety") {
136
- if (provider === "replicate") return !value;
137
- return value;
138
- }
139
- if (universal === "size") {
140
- return parseSizeForProvider(value, provider);
141
- }
142
- return value;
143
- }
144
- function parseSizeForProvider(value, provider) {
145
- if (provider === "fal-ai" || provider === "replicate") {
146
- if (typeof value === "string") {
147
- const [w, h] = value.split("x").map(Number);
148
- return { width: w, height: h };
149
- }
150
- return value;
151
- }
152
- return value;
153
- }
154
- function mapOutput(raw, outputMapping) {
155
- const { type, extract_path, content_type } = outputMapping;
156
- const defaultContentType = content_type || "image/jpeg";
157
- const data = raw;
158
- if (extract_path === "images[].url") {
159
- const images = data?.images ?? [];
160
- return images.map((img) => ({
161
- type,
162
- url: img.url,
163
- content_type: img.content_type || defaultContentType
164
- }));
165
- }
166
- if (extract_path === "output[]") {
167
- const arr = Array.isArray(data) ? data : data?.output ?? [];
168
- return arr.map((url) => ({
169
- type,
170
- url,
171
- content_type: defaultContentType
172
- }));
173
- }
174
- if (extract_path === "data.outputs[]") {
175
- const outputs = data?.data?.outputs ?? [];
176
- return outputs.map((url) => ({
177
- type,
178
- url,
179
- content_type: defaultContentType
180
- }));
181
- }
182
- if (extract_path === "video.url") {
183
- return [{
184
- type: "video",
185
- url: data?.video?.url,
186
- content_type: "video/mp4"
187
- }];
188
- }
189
- if (extract_path === "audio.url") {
190
- return [{
191
- type: "audio",
192
- url: data?.audio?.url,
193
- content_type: "audio/mpeg"
194
- }];
195
- }
196
- return genericExtract(data, extract_path, type, defaultContentType);
197
- }
198
- function genericExtract(data, path, type, contentType) {
199
- const segments = path.split(".");
200
- let current = data;
201
- for (const seg of segments) {
202
- if (current === null || current === void 0) return [];
203
- const indexMatch = seg.match(/^(.+)\[(\d+)\]$/);
204
- if (indexMatch) {
205
- const key = indexMatch[1];
206
- const index = parseInt(indexMatch[2], 10);
207
- const arr = current[key];
208
- if (!Array.isArray(arr) || index >= arr.length) return [];
209
- current = arr[index];
210
- continue;
211
- }
212
- const arrayMatch = seg.match(/^(.+)\[\]$/);
213
- if (arrayMatch) {
214
- const key = arrayMatch[1];
215
- current = current[key];
216
- if (Array.isArray(current)) {
217
- const remaining = segments.slice(segments.indexOf(seg) + 1).join(".");
218
- if (remaining) {
219
- return current.map((item) => ({
220
- type,
221
- url: getNestedValue(item, remaining),
222
- content_type: contentType
223
- }));
224
- }
225
- return current.map((item) => ({
226
- type,
227
- url: typeof item === "string" ? item : item?.url,
228
- content_type: contentType
229
- }));
230
- }
231
- return [];
232
- }
233
- current = current[seg];
234
- }
235
- if (typeof current === "string") {
236
- if (type === "text") {
237
- return [{ type, content: current, content_type: contentType }];
238
- }
239
- return [{ type, url: current, content_type: contentType }];
240
- }
241
- return [];
242
- }
243
- function getNestedValue(obj, path) {
244
- let current = obj;
245
- for (const key of path.split(".")) {
246
- if (current === null || current === void 0) return void 0;
247
- current = current[key];
248
- }
249
- return current;
250
- }
251
-
252
- // src/v2/gateway.ts
253
- var adapters = {
254
- "fal-ai": falAiAdapter,
255
- "replicate": replicateAdapter,
256
- "wavespeed": wavespeedAdapter,
257
- "openrouter": openRouterAdapter
258
- };
259
- var DEFAULT_TIMEOUT_MS = 12e4;
260
- async function generate(request) {
261
- const startTime = Date.now();
262
- if (!request.model) throw new ValidationError("model", "model is required");
263
- const auth = new AuthManager();
264
- const model = resolveModel(request.model, auth.availableProviders());
265
- let availableBindings = model.providers.filter(
266
- (p) => auth.availableProviders().includes(p.provider) && adapters[p.provider]
267
- );
268
- if (request.provider) {
269
- availableBindings = availableBindings.filter((p) => p.provider === request.provider);
270
- if (availableBindings.length === 0) {
271
- throw new ValidationError(
272
- "provider",
273
- `Provider "${request.provider}" is not available for model "${model.canonical_name}". Available: ${model.providers.map((p) => p.provider).join(", ")}`
274
- );
275
- }
276
- }
277
- if (availableBindings.length === 0) {
278
- throw new ValidationError(
279
- "model",
280
- `No adapter available for model "${model.canonical_name}". Available providers: ${model.providers.map((p) => p.provider).join(", ")}`
281
- );
282
- }
283
- const binding = availableBindings[0];
284
- const providerParams = mapInput(request, binding);
285
- const finalParams = await processParamsForUpload(providerParams, {
286
- reupload: request.options?.reupload
287
- });
288
- const adapter = adapters[binding.provider];
289
- const apiKey = auth.getKey(binding.provider);
290
- const timeoutMs = request.options?.timeout ?? DEFAULT_TIMEOUT_MS;
291
- const submitted = await withRetry(
292
- () => adapter.submit(binding.endpoint, finalParams, apiKey),
293
- { timeoutMs }
294
- );
295
- let result = submitted;
296
- while (result.status === "processing" || result.status === "pending") {
297
- await new Promise((resolve2) => setTimeout(resolve2, 1e3));
298
- result = await adapter.poll(submitted.id, apiKey, binding.endpoint);
299
- }
300
- if (result.status === "failed") {
301
- throw new ProviderError(
302
- binding.provider,
303
- model.canonical_name,
304
- 0,
305
- result.error || "Generation failed"
306
- );
307
- }
308
- const outputs = mapOutput(result.output, binding.output_map);
309
- const rawOutput = typeof result.output === "object" && result.output !== null ? result.output : void 0;
310
- const metadata = {
311
- inference_time_ms: Date.now() - startTime,
312
- seed: rawOutput?.seed,
313
- safety_flagged: rawOutput ? Array.isArray(rawOutput.has_nsfw_concepts) ? rawOutput.has_nsfw_concepts.some((v) => v) : void 0 : void 0
314
- };
315
- if (rawOutput?.usage) {
316
- const usage = rawOutput.usage;
317
- metadata.tokens = usage.total_tokens;
318
- metadata.prompt_tokens = usage.prompt_tokens;
319
- metadata.completion_tokens = usage.completion_tokens;
320
- }
321
- return {
322
- id: randomUUID(),
323
- model: model.canonical_name,
324
- provider: binding.provider,
325
- status: "completed",
326
- outputs,
327
- metadata
328
- };
329
- }
330
-
331
- // src/v2/discovery.ts
332
- function listModels(filters) {
333
- let models = loadRegistry();
334
- if (filters?.input) {
335
- models = models.filter((m) => m.modality.inputs.includes(filters.input));
336
- }
337
- if (filters?.output) {
338
- models = models.filter((m) => m.modality.outputs.includes(filters.output));
339
- }
340
- if (filters?.provider) {
341
- models = models.filter(
342
- (m) => m.providers.some((p) => p.provider === filters.provider)
343
- );
344
- }
345
- if (filters?.query) {
346
- const q = filters.query.toLowerCase();
347
- models = models.filter(
348
- (m) => m.canonical_name.includes(q) || m.aliases.some((a) => a.includes(q))
349
- );
350
- }
351
- return models;
352
- }
353
- function deriveCategory(model) {
354
- const inputs = model.modality.inputs.join(",");
355
- const outputs = model.modality.outputs.join(",");
356
- return `${inputs}-to-${outputs}`;
357
- }
358
- export {
359
- clearRegistryCache,
360
- deriveCategory,
361
- generate,
362
- listModels,
363
- loadRegistry,
364
- mapInput,
365
- mapOutput,
366
- resolveModel
367
- };
368
- //# sourceMappingURL=index.js.map