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把金鑰放進環境變數
預設的 popnow 實例會讀取 POPNOW_API_KEY:
export POPNOW_API_KEY="sk-popnow-..."請把金鑰保存在你的伺服器上。任何能讀取它的人都能花掉你的 API 餘額。
生成一張圖片
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 建立你自己的實例:
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 中一併傳入:
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 輸入欄位 |
|---|---|
prompt | prompt |
aspectRatio | aspect_ratio |
size | width 與 height;模型不支援時簡化為 aspect_ratio,並給出 compatibility 警告 |
seed | seed |
n | num_outputs 或 num_images;兩者都沒有的模型,每張圖片是一個獨立的任務,由 AI SDK 發起多次呼叫 |
prompt 中的 images | image_urls,單圖模型則為 image_url |
prompt 中的 mask | mask_url |
模型不支援的設定會被省略,並在 warnings 中以 unsupported 回報。其他模型欄位放在 providerOptions.popnow 中,拼寫必須與模型 Schema 完全一致(snake_case),例如 resolution、output_format 或 quality。這些值會覆寫對應得到的值。
文字轉語音
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 都列出了它接受的音色。
語音轉文字
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 金鑰與同一份餘額:
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 可以搭配同一個模型使用:
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 中,不會送給模型:
| 選項 | 預設值 | 意義 |
|---|---|---|
pollIntervalMs | 2000 | 第一次輪詢前的等待時間 |
pollTimeoutMs | 任務截止時間加兩分鐘 | 超過此時間便停止等待;任務會繼續執行 |
waitSeconds | 60 | 建立請求保持開啟的時間(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;任務會繼續執行。
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 控制台會依金鑰顯示用量。

