PopNowAPI 文档
集成
正文

Vercel AI SDK 提供方

在 Vercel AI SDK 7 中使用 PopNow 模型。generateImage 用于文生图和图片编辑,另有 generateSpeech、transcribe 和对话模型,一把 API 密钥,按美元从 API 余额扣费。

@popnow/ai-sdk-provider 把 PopNow 模型接入 Vercel AI SDK。使用一把 API 密钥,你可以通过 generateImage 调用图片生成和图片编辑模型,通过 generateSpeech 调用文本转语音,通过 transcribe 调用语音转文字,并通过 generateText 和 streamText 调用对话模型。所有费用都按美元从你单独的 API 余额扣除。

这个包以 MIT 许可证开源(GitHub)。它需要 AI SDK 7(ai@^7)和 Node.js 22 或更高版本。

概览

AI SDK 函数PopNow 模型工厂函数
generateImage文生图与图片编辑:Nano Banana、GPT Image、Seedream、FLUX、Qwen Image 等popnow.image(id)
generateSpeech文本转语音popnow.speech(id)
transcribe语音转文字popnow.transcription(id)
generateText、streamText通过 OpenAI 兼容端点调用的对话模型popnow(id)、popnow.chat(id)

设置

安装包

npm install @popnow/ai-sdk-provider ai

创建 API 密钥

在 API 控制台创建一个密钥。密钥以 sk-popnow- 开头。API 余额初始为 $0,请在首次调用付费模型前,于 API 账单中充值。

把密钥放进环境变量

默认的 popnow 实例从 POPNOW_API_KEY 读取密钥:

export POPNOW_API_KEY="sk-popnow-..."

请把密钥保存在你的服务器上。任何能读取它的人都可以花掉你的 API 余额。

生成一张图片

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateImage } from 'ai';
import fs from 'node:fs';

const { image } = await generateImage({
  model: popnow.image('google/nano-banana-2.1/text-to-image'),
  prompt: 'A cozy reading nook beside a rain-streaked window, warm lamp light',
  aspectRatio: '16:9',
  providerOptions: {
    popnow: { resolution: '2k' },
  },
});

await fs.promises.writeFile('nook.png', image.uint8Array);

提供方设置

如需其他设置,请用 createPopNow 创建你自己的实例:

TypeScript
import { createPopNow } from '@popnow/ai-sdk-provider';

const popnow = createPopNow({
  apiKey: process.env.POPNOW_API_KEY, // default: POPNOW_API_KEY
  baseURL: 'https://api.popnow.ai', // default: POPNOW_BASE_URL or https://api.popnow.ai
  headers: { 'X-PopNow-Tags': 'my-app' }, // optional, sent with every request
});

createPopNow 还可以接收自定义的 fetch 函数。

编辑图片

编辑模型的 ID 以 /edit 结尾。把源图片传入 prompt;如果模型需要蒙版,也在 prompt 中一并传入:

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateImage } from 'ai';

const { image } = await generateImage({
  model: popnow.image('google/nano-banana-2.1/edit'),
  prompt: {
    text: 'Change the jacket to deep forest green; keep the face and background',
    images: ['https://example.com/portrait.jpg'],
  },
});

URL 会原样传递。以字节或 base64 提供的图片,如果是不超过 1 MiB 的 JPEG、PNG、WebP 或 GIF,会直接内联发送;其余的图片会先上传到 PopNow。

设置如何映射到 PopNow

每个 PopNow 模型都会用它自己的 JSON Schema 校验 input,并拒绝未知字段。提供方会读取模型的 Schema(GET /api/v1/models/{model},缓存十分钟),只有当模型存在对应字段时才发送该设置:

AI SDK 设置PopNow 输入字段
promptprompt
aspectRatioaspect_ratio
sizewidth 和 height;模型不支持时简化为 aspect_ratio,并给出 compatibility 警告
seedseed
nnum_outputs 或 num_images;两者都没有的模型,每张图片是一个单独的任务,由 AI SDK 发起多次调用
prompt 中的 imagesimage_urls,单图模型则为 image_url
prompt 中的 maskmask_url

模型不支持的设置会被省略,并在 warnings 中以 unsupported 报告。其他模型字段放在 providerOptions.popnow 中,拼写必须与模型 Schema 完全一致(snake_case),例如 resolution、output_format 或 quality。这些值会覆盖映射得到的值。

文本转语音

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateSpeech } from 'ai';
import fs from 'node:fs';

const { audio } = await generateSpeech({
  model: popnow.speech('openai/tts-1/text-to-speech'),
  text: 'Hello from PopNow.',
  voice: 'nova',
  speed: 1.1,
});

await fs.promises.writeFile('hello.mp3', audio.uint8Array);

voice 映射到 voice_id,outputFormat 映射到 output_format;instructions、speed 和 language 在模型支持时,映射到同名字段。每个模型的 Schema 都列出了它接受的音色。

语音转文字

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { transcribe } from 'ai';
import fs from 'node:fs';

const result = await transcribe({
  model: popnow.transcription('openai/whisper-1/speech-to-text'),
  audio: await fs.promises.readFile('meeting.mp3'),
  providerOptions: { popnow: { language: 'en' } },
});

console.log(result.text, result.words);

音频字节会先上传到 PopNow(支持 MP3 和 WAV,最大 90 MiB)。公开的 https:// URL(audio: new URL('https://...'))会直接交给 PopNow,不经下载。

对话模型

PopNow 通过 OpenAI 兼容的 API 提供对话模型,地址为 https://api.popnow.ai/v1。提供方使用 @ai-sdk/openai-compatible 调用它们,使用同一把 API 密钥和同一份余额:

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateText } from 'ai';

const { text } = await generateText({
  model: popnow('anthropic/claude-haiku-5.5/chat'),
  prompt: 'Suggest three names for a kite shop by the sea.',
});

streamText 可以用同一个模型:

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { streamText } from 'ai';

const result = streamText({
  model: popnow('anthropic/claude-haiku-5.5/chat'),
  prompt: 'Write a short welcome message for a kite shop.',
});

for await (const delta of result.textStream) process.stdout.write(delta);

对话模型按 token 计价,没有单次请求的最低收费。对话模型列出了所有模型及其支持的参数。

模型 ID

模型 ID 的格式为 <maker>/<model>/<task>,例如 google/nano-banana-2.1/text-to-image、openai/tts-1/text-to-speech 或 openai/whisper-1/speech-to-text。TypeScript 类型只提示其中几个;你的密钥能调用的任意 ID 都可以使用。模型列出了所有模型的参数和价格。如需在代码中连同输入 Schema 一起列出它们:

curl "https://api.popnow.ai/api/v1/models?modality=image&includeSchema=1" \
  -H "Authorization: Bearer $POPNOW_API_KEY"

modality 可取 image、video 或 audio。对话模型通过 GET https://api.popnow.ai/v1/models 列出。

价格

价格以美元计,依模型而定,单位是每张图片、每秒或每 1,000 个字符,并显示在模型页及每个模型的页面上。AI 价格指数也列出了这些价格。每个任务被接受时,会从你的 API 余额中冻结其最高价格,完成时按实际费用结算。失败或过期的任务不收费。详情见计费与报价。

每个图片条目在 providerMetadata.popnow.images 中都带有 taskId、costUsd(美元十进制字符串)以及费用是否已 settled(已结算)。语音和转写结果在 providerMetadata.popnow 中带有相同的字段。

任务、轮询与重试

PopNow 的生成是异步的。每次调用会创建一个任务,在创建请求上最多等待 60 秒,然后轮询任务(起初每 2 秒一次,逐步延长到每 15 秒一次),直到任务进入最终状态,再从签名链接下载输出文件。API 密钥从不会发送到这些链接。

以下选项放在 providerOptions.popnow 中,不会发送给模型:

选项默认值含义
pollIntervalMs2000第一次轮询前的等待时间
pollTimeoutMs任务截止时间加两分钟等待超过此时长即停止;任务会继续运行
waitSeconds60创建请求保持打开的时长(0 到 60)
idempotencyKey每次调用时生成一次逻辑生成对应的稳定密钥
metadata无你自己的标签,随任务一起保存

每个创建请求都会携带 Idempotency-Key。连接错误、429 以及可重试的 5xx 响应会用同一个密钥重试两次,因此重试不会启动第二个任务。如果你传入了自己的 idempotencyKey,AI SDK 自身的重试(maxRetries)也会复用它。参见幂等性。

abortSignal 会立即停止等待。已经被接受的任务会继续在 PopNow 上运行。

错误

  • APICallError(来自 @ai-sdk/provider)表示 API 错误。错误信息中包含 PopNow 的业务码,例如 40201(API 余额不足)或 40301(该密钥不能调用此模型)。参见错误。
  • PopNowTaskError 表示任务以 failed 或 expired 结束。它包含 taskId、state、errorCode(例如 content_rejected)、errorMessage 和 costUsd。这些任务不收费。
  • PopNowTaskTimeoutError 表示 pollTimeoutMs 已耗尽。它包含 taskId;任务会继续运行。
TypeScript
import { popnow, PopNowTaskError } from '@popnow/ai-sdk-provider';
import { generateImage } from 'ai';

try {
  await generateImage({
    model: popnow.image('google/nano-banana-2.1/text-to-image'),
    prompt: 'A lighthouse at dawn, watercolor',
  });
} catch (error) {
  if (PopNowTaskError.isInstance(error)) console.log(error.taskId, error.errorCode);
}

不包含的功能

  • 视频。 AI SDK 的视频模型接口仍处于实验阶段(experimental_generateVideo),因此这个包暂未实现它。PopNow 的视频模型可通过任务接口、官方 SDK 以及 OpenAI Videos 兼容端点使用。
  • Embeddings。 embeddingModel 会抛出 NoSuchModelError。

需要哪个版本的 AI SDK?

AI SDK 7(ai@^7),运行环境为 Node.js 22 或更高版本。用 npm install @popnow/ai-sdk-provider ai 可以一次装好两者。

可以在浏览器中调用吗?

不能把你的 API 密钥放在页面里使用:任何能读取密钥的人都可以花掉你的 API 余额。请在服务端路由中调用 AI SDK,例如 Next.js 的 route handler 或 server action,再把结果发送到浏览器。

支持视频模型吗?

暂不支持,因为 AI SDK 的视频接口仍处于实验阶段。视频请使用任务接口或 JavaScript SDK。

如何查看一次调用花了多少钱?

读取 providerMetadata.popnow:每个任务都会报告它的 taskId、costUsd 以及费用是否已 settled。API 控制台会按密钥显示用量。

本页内容