Vercel AI SDK プロバイダー
Vercel AI SDK 7 から PopNow のモデルを使います。generateImage で画像生成と画像編集、generateSpeech・transcribe・チャットモデルも使えます。API キー 1 つで、米ドルの API 残高から課金されます。
@popnow/ai-sdk-provider は、PopNow のモデルを Vercel AI SDK から使えるようにします。API キー 1 つで、画像生成と画像編集のモデルは 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 aiAPI キーを作成する
API コンソールでキーを作成します。キーは sk-popnow- で始まります。API 残高は $0 から始まるので、最初の有料呼び出しの前に API の課金でチャージしてください。
環境変数にキーを設定する
既定の 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 に含めます。
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 で渡された画像は、JPEG・PNG・WebP・GIF で 1 MiB 以下であればインラインで送られます。それ以外は PopNow にアップロードされます。
設定が PopNow にどう対応するか
PopNow の各モデルは、自身の JSON Schema に照らして input を検証し、未知の項目を拒否します。プロバイダーはモデルの Schema(GET /api/v1/models/{model}、10 分間キャッシュ)を読み、モデルに対応する項目がある場合にのみ設定を送ります。
| 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 でチャットモデルを提供しています。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);チャットモデルはトークン単位で料金が決まり、リクエストごとの最低料金はありません。チャットモデルのページに、すべてのモデルと対応するパラメータが載っています。
モデル 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 枚ごと、秒ごと、または 1,000 文字ごとに決まります。モデルと各モデルのページに掲載されています。AI 価格指数にも一覧があります。各タスクは受け付けられた時点で、API 残高から最大料金を保留し、完了すると実際の料金で精算されます。失敗したタスクや期限切れのタスクは課金されません。詳しくは課金と見積もりを参照してください。
providerMetadata.popnow.images の各画像のエントリには、taskId、costUsd(米ドルの十進数の文字列)、そして料金が settled(精算済み)かどうかが入ります。音声の読み上げと文字起こしの結果も、同じ項目を providerMetadata.popnow に持ちます。
タスク、ポーリング、再試行
PopNow の生成は非同期です。呼び出しごとにタスクが作成され、作成リクエストは最大 60 秒待ちます。その後、タスクが最終状態になるまでポーリングします。ポーリングの間隔は最初は 2 秒で、最終的には 15 秒まで延びます。出力ファイルは署名付きリンクからダウンロードします。API キーがこれらのリンクに送られることはありません。
次のオプションは providerOptions.popnow に指定します。モデルには送られません。
| オプション | 既定値 | 意味 |
|---|---|---|
pollIntervalMs | 2000 | 最初のポーリングまでの待ち時間 |
pollTimeoutMs | タスクの期限に 2 分を足した時間 | この時間を過ぎたら待機をやめます。タスク自体は実行を続けます |
waitSeconds | 60 | 作成リクエストを開いたままにする時間(0〜60) |
idempotencyKey | 呼び出しごとに生成 | 1 回の論理的な生成に対応する固定のキー |
metadata | なし | 任意のラベル。タスクと一緒に保存されます |
作成リクエストには、すべて Idempotency-Key が付きます。接続エラー、429、再試行可能な 5xx の応答は、同じキーで 2 回まで再試行されます。そのため、再試行で 2 つ目のタスクが作られることはありません。独自の 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 残高を使えてしまいます。Next.js の route handler や server action のようなサーバー側のルートから AI SDK を呼び出し、結果をブラウザに送ってください。
動画モデルに対応していますか?
まだ対応していません。AI SDK の動画インターフェースが実験的段階にあるためです。動画は タスク API か JavaScript SDK を使ってください。
呼び出しにいくらかかったか、どう確認しますか?
providerMetadata.popnow を読んでください。各タスクには taskId、costUsd、そして料金が精算済みかどうかが報告されます。API コンソールでは、キーごとの利用状況を確認できます。

