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 的影片模型可透過任務 API、官方 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 的影片介面仍在實驗階段。影片請使用任務 API 或 JavaScript SDK。

怎麼查看一次呼叫花了多少錢?

讀取 providerMetadata.popnow:每個任務都會回報它的 taskId、costUsd,以及費用是否已 settled。API 控制台會依金鑰顯示用量。

本頁內容