15 KiB
模型生成接口整理(按当前代码)
整理依据为当前源码,不沿用旧文档结论。主要代码入口:
src/app/api/generate/route.tssrc/app/api/generate/providers/*.tssrc/app/api/generate/poll/route.tssrc/app/api/llm/route.tssrc/store/execution/*Executor.ts
1. 项目内部接口
| 内部接口 | 方法 | 当前调用方 | 作用 |
|---|---|---|---|
/api/generate |
POST | nanoBananaExecutor、generateVideoExecutor、generateAudioExecutor、generate3DExecutor |
图片、视频、音频、3D 统一入口。按 selectedModel.provider 分发。 |
/api/generate/poll |
POST | pollTaskCompletion.ts |
只用于 Kie.ai。/api/generate 返回 polling: true 后前端继续轮询。 |
/api/llm |
POST | llmGenerateExecutor.ts |
LLM Generate 节点文本生成,不走 /api/generate。 |
/api/models |
GET | 模型选择/搜索 UI | 获取模型列表。 |
/api/models/[modelId]?provider=... |
GET | 模型参数面板/动态输入 | 获取模型参数和输入 schema。 |
2. /api/generate 当前分发逻辑
src/app/api/generate/route.ts 当前按 selectedModel.provider 分发:
| Provider | 调用函数 | 文件 |
|---|---|---|
newapiwg |
generateWithNewApiWG(...) |
providers/newapiwg.ts |
replicate |
generateWithReplicate(...) |
providers/replicate.ts |
fal |
generateWithFalQueue(...) |
providers/fal.ts |
kie |
submitKieTask(...),立即返回轮询信息 |
providers/kie.ts |
wavespeed |
generateWithWaveSpeed(...) |
providers/wavespeed.ts |
默认/gemini |
generateWithGemini(...) 或 generateWithGeminiVideo(...) |
providers/gemini.ts |
newapiwg 会把 aspectRatio、resolution 合并进 parameters,再交给 provider 文件处理。其他 provider 基本保留 images、prompt、parameters、dynamicInputs,只过滤空值。
3. 同步返回类接口
这里的“同步”指前端只调用一次项目内部接口。即使服务端内部轮询,也不会让前端调用 /api/generate/poll。
3.1 Gemini 图片
代码:src/app/api/generate/providers/gemini.ts
| 上游调用 | 方法 | 当前用途 |
|---|---|---|
ai.models.generateContent(...) |
SDK | Gemini 图片生成。模型映射在 MODEL_MAP:nano-banana、nano-banana-pro、nano-banana-2。 |
请求要点:
contents包含 prompt 和 inline image。config.responseModalities = ["IMAGE", "TEXT"]。aspectRatio写入config.imageConfig.aspectRatio。nano-banana-pro、nano-banana-2的resolution写入config.imageConfig.imageSize。nano-banana-pro可用googleSearch。nano-banana-2可用googleSearch.searchTypes.webSearch/imageSearch。
返回:直接返回 image data URL。
3.2 Gemini Veo 视频
代码:src/app/api/generate/providers/gemini.ts
| 上游调用 | 方法 | 当前用途 |
|---|---|---|
ai.models.generateVideos(...) |
SDK | 提交 Veo 视频生成。 |
ai.operations.getVideosOperation({ operation }) |
SDK | 服务端内部轮询。 |
<generatedVideos[0].video.uri>&key=<apiKey> |
GET | 下载生成视频。 |
当前模型映射:
| 项目模型 ID | Gemini API 模型 |
|---|---|
veo-3.1/text-to-video |
veo-3.1-generate-preview |
veo-3.1/image-to-video |
veo-3.1-generate-preview |
veo-3.1-fast/text-to-video |
veo-3.1-fast-generate-preview |
veo-3.1-fast/image-to-video |
veo-3.1-fast-generate-preview |
服务端每 10 秒轮询一次,最多 5 分钟。前端不调用 /api/generate/poll。
3.3 NewApiWG
代码:src/app/api/generate/providers/newapiwg.ts
当前 NewApiWG 不是所有图片都走 images/generations。generateWithNewApiWG(...) 的分流顺序如下:
| 分流条件 | 实际上游接口 | 方法 | 说明 |
|---|---|---|---|
| 模型名匹配 Doubao chat-only | 无 | 无 | 直接返回错误:这是文本/聊天模型,不是生成模型。 |
isAudio = !isVideo && capabilities.includes("text-to-audio") |
{baseUrl}/audio/speech |
POST | 文本转音频。 |
非视频、非音频,且 isGeminiNativeImageModel(modelId) |
{baseUrl}/models/{modelName}:generateContent |
POST | Gemini native 图片路径。/v1 base URL 会转成 /v1beta。 |
非视频、非音频,且 isOpenAIChatImageModel(modelId) |
{baseUrl}/chat/completions |
POST | chat 风格图片模型,例如 sora-image、gpt-image-2-all。 |
isVideo |
{baseUrl}/video/generations |
POST | 标准视频生成。 |
| 以上都不满足 | {baseUrl}/images/generations |
POST | 普通图片生成兜底路径。 |
NewApiWG images/generations 当前请求体
只有“非视频、非音频、非 Gemini native、非 chat 图片模型”的普通图片会走:
POST {baseUrl}/images/generations
当前 body 结构:
{
"model": "input.model.id",
"prompt": "dynamicInputs.prompt 或 input.prompt",
"n": 1,
"...dynamicInputsWithoutPrompt": "...",
"...mediaInputs": "...",
"size": "resolveNewApiWGImageSize(parameters)",
"response_format": "b64_json",
"...imageParameters": "normalized parameters"
}
当前图片输入规则:
| 来源 | 传给上游的字段 |
|---|---|
input.images 为空 |
不加图片字段。 |
input.images 只有 1 张 |
image: string |
input.images 多张 |
image: string[] |
当前参数规则:
size由resolveNewApiWGImageSize(parameters)计算。- 如果
parameters.imageSize或parameters.resolution是512、1K、2K、4K,会结合aspectRatio/aspect_ratio计算成类似1024x1024的尺寸。 response_format固定为b64_json。- 透传参数会先删除这些字段:
size、image_size、output_size、dimensions、aspectRatio、aspect_ratio、resolution、imageSize。 dynamicInputs.prompt不透传,因为 prompt 已经放到顶层prompt。
NewApiWG video/generations 当前请求体
视频模型走:
POST {baseUrl}/video/generations
当前 body 结构:
{
"model": "input.model.id",
"prompt": "dynamicInputs.prompt 或 input.prompt",
"n": 1,
"...normalizedDynamicInputs": "...",
"...mediaInputs": "...",
"...parameters": "input.parameters"
}
视频动态媒体输入会被归一化:
| dynamic input key | 归一化结果 |
|---|---|
image、images、image_url、image_urls、first_frame_url、last_frame_url、tail_image_url、reference_image_url(s) 等 |
mediaInputs.images |
video、videos、video_url、video_urls、reference_video_url(s) 等 |
mediaInputs.videos |
audio、audios、audio_url、audio_urls、reference_audio_url(s) 等 |
mediaInputs.audios |
视频返回处理:
- 如果响应里直接有 URL,立即返回
videoUrl。 - 如果响应里只有
task_id或id,服务端调用{baseUrl}/video/generations/{taskId}内部轮询,最多 9 分钟。 - 前端不调用
/api/generate/poll。
3.4 Replicate
代码:src/app/api/generate/providers/replicate.ts
| 上游接口 | 方法 | 当前用途 |
|---|---|---|
https://api.replicate.com/v1/models/{owner}/{name} |
GET | 获取 latest version 和 OpenAPI schema。 |
https://api.replicate.com/v1/predictions |
POST | 创建 prediction。 |
https://api.replicate.com/v1/predictions/{predictionId} |
GET | 服务端内部轮询。 |
<outputUrl> |
GET | 下载结果媒体。 |
请求体创建规则:
selectedModel.modelId必须是owner/name。prediction.input会根据 Replicate schema 做字段映射和类型转换。- 有
dynamicInputs时,dynamicInputs直接使用 schema 字段名,并根据 schema 决定数组/单值。 - 没有
dynamicInputs时,用 schema 推断 prompt/image/参数字段名。
服务端轮询:1 秒一次;图片最多 5 分钟,视频最多 10 分钟。前端不调用 /api/generate/poll。
3.5 fal.ai
代码:src/app/api/generate/providers/fal.ts
| 上游接口 | 方法 | 当前用途 |
|---|---|---|
https://api.fal.ai/v1/models?endpoint_id={modelId}&expand=openapi-3.0 |
GET | 获取并缓存 schema 映射,缓存 30 分钟。 |
https://rest.alpha.fal.ai/storage/upload/initiate?storage_type=fal-cdn-v3 |
POST | base64 媒体上传前初始化。 |
<upload_url> |
PUT | 上传到 fal CDN。 |
https://queue.fal.run/{modelId} |
POST | 提交 fal 队列任务。 |
status_url 或 https://queue.fal.run/{modelId}/requests/{requestId}/status |
GET | 服务端内部轮询状态。 |
response_url 或 https://queue.fal.run/{modelId}/requests/{requestId} |
GET | 获取任务结果。 |
<mediaUrl> |
GET | 下载结果媒体。 |
当前逻辑:
- base64 图片/媒体会先上传到 fal CDN。
- 队列状态每 1 秒查一次,最多 10 分钟。
- 3D 直接返回 URL。
- 大视频超过 20MB 时返回 URL,不转 base64。
- 前端不调用
/api/generate/poll。
3.6 WaveSpeed
代码:src/app/api/generate/providers/wavespeed.ts
| 上游接口 | 方法 | 当前用途 |
|---|---|---|
https://api.wavespeed.ai/api/v3/{modelId} |
POST | 提交任务。 |
data.urls.get 或 https://api.wavespeed.ai/api/v3/predictions/{taskId}/result |
GET | 服务端内部轮询结果。 |
<outputUrl> |
GET | 下载结果媒体。 |
当前逻辑:
modelId直接拼进 URL path,但会拒绝非法字符和..。- payload 先展开
parameters,再设置顶层prompt。 - 有
dynamicInputs时直接按 schema 字段名传;images会包装成数组。 - 没有
dynamicInputs且有图片时,第一张图放入image。 - 轮询 1 秒一次,最多 5 分钟;
404视为结果未就绪继续等。 - 3D 直接返回 URL;大视频超过 20MB 返回 URL。
- 前端不调用
/api/generate/poll。
4. 异步任务接口
这里的“异步”指前端会继续调用项目内部 /api/generate/poll。
4.1 Kie.ai
提交代码:src/app/api/generate/providers/kie.ts
轮询代码:src/app/api/generate/poll/route.ts
提交阶段由 /api/generate 调用 submitKieTask(...),不会等待最终媒体。
| 上游接口 | 方法 | 当前用途 |
|---|---|---|
https://kieai.redpandaai.co/api/file-base64-upload |
POST | base64 图片、视频、音频上传为 URL。 |
https://api.kie.ai/api/v1/jobs/createTask |
POST | 标准 Kie 模型提交任务。 |
https://api.kie.ai/api/v1/veo/generate |
POST | Kie Veo 模型提交任务。 |
/api/generate 对 Kie 当前返回:
{
"success": true,
"polling": true,
"taskId": "...",
"pollProvider": "kie",
"pollModelId": "...",
"pollModelName": "...",
"pollMediaType": "image | video | audio | 3d"
}
前端 pollGenerateTask(...) 继续调用:
POST /api/generate/poll
body:
{
"taskId": "...",
"provider": "kie",
"modelId": "...",
"modelName": "...",
"mediaType": "..."
}
/api/generate/poll 当前只支持 provider === "kie"。
| 查询类型 | 上游接口 | 方法 |
|---|---|---|
| 标准 Kie 任务 | https://api.kie.ai/api/v1/jobs/recordInfo?taskId={taskId} |
GET |
| Kie Veo 任务 | https://api.kie.ai/api/v1/veo/record-info?taskId={taskId} |
GET |
| 结果媒体 | <mediaUrl> |
GET |
前端轮询策略:
- 初始间隔 3 秒。
- 每次增加 0.5 秒。
- 最高 8 秒。
- 最长 10 分钟。
- 连续 10 次临时错误后失败。
5. LLM 文本生成接口
LLM Generate 节点不走 /api/generate,当前走 POST /api/llm。
代码:src/app/api/llm/route.ts
| Provider | 上游接口/调用 | 方法 |
|---|---|---|
google |
ai.models.generateContent(...) |
SDK |
openai |
https://api.openai.com/v1/chat/completions |
POST |
anthropic |
https://api.anthropic.com/v1/messages |
POST |
newapiwg |
{baseUrl}/chat/completions |
POST |
当前没有 LLM 轮询接口,一次请求直接返回 text。
6. 模型列表和 Schema
6.1 /api/models
代码:src/app/api/models/route.ts
| Provider | 当前上游调用 |
|---|---|
| Gemini | 无上游调用,本地静态列表。 |
| Kie.ai | 无上游调用,本地静态列表。 |
| NewApiWG | {baseUrl}/models |
| Replicate | https://api.replicate.com/v1/models |
| fal.ai | https://api.fal.ai/v1/models?status=active,可带搜索参数。 |
| WaveSpeed | https://api.wavespeed.ai/api/v3/models |
6.2 /api/models/[modelId]?provider=...
代码:src/app/api/models/[modelId]/route.ts
| Provider | 当前上游调用 |
|---|---|
| Gemini | 无上游调用,本地静态 schema。 |
| Kie.ai | 无上游调用,本地静态 schema。 |
| NewApiWG | 无上游调用,根据模型 ID 推断 schema。 |
| Replicate | https://api.replicate.com/v1/models/{owner}/{name} |
| fal.ai | https://api.fal.ai/v1/models?endpoint_id={modelId}&expand=openapi-3.0 |
| WaveSpeed | 优先用缓存;缺失时调用 https://api.wavespeed.ai/api/v3/models。 |
7. Header
7.1 /api/generate 使用的 provider header
| Provider | Header | 环境变量兜底 |
|---|---|---|
| NewApiWG | X-NewApiWG-Key、X-NewApiWG-Base-URL |
NEWAPIWG_API_KEY、NEWAPIWG_BASE_URL |
| Gemini | X-Gemini-API-Key |
GEMINI_API_KEY |
| Replicate | X-Replicate-API-Key |
REPLICATE_API_KEY |
| fal.ai | X-Fal-API-Key |
FAL_API_KEY |
| Kie.ai | X-Kie-Key |
KIE_API_KEY |
| WaveSpeed | X-WaveSpeed-Key |
WAVESPEED_API_KEY |
7.2 /api/models 和 /api/models/[modelId] 使用的 header
注意:模型列表/schema 接口里 Replicate、fal 的 header 名和 /api/generate 不完全一样。
| Provider | Header |
|---|---|
| NewApiWG | X-NewApiWG-Key、X-NewApiWG-Base-URL |
| Replicate | X-Replicate-Key |
| fal.ai | X-Fal-Key |
| Kie.ai | X-Kie-Key |
| WaveSpeed | X-WaveSpeed-Key |
7.3 /api/llm 使用的 header
| Provider | Header | 环境变量兜底 |
|---|---|---|
| Google/Gemini | X-Gemini-API-Key |
GEMINI_API_KEY |
| OpenAI | X-OpenAI-API-Key |
OPENAI_API_KEY |
| Anthropic | X-Anthropic-API-Key |
ANTHROPIC_API_KEY |
| NewApiWG | X-NewApiWG-Key、X-NewApiWG-Base-URL |
NEWAPIWG_API_KEY、NEWAPIWG_BASE_URL |
8. 同步/异步总览
| 类型 | 前端是否调用 /api/generate/poll |
轮询位置 |
|---|---|---|
| Gemini 图片 | 否 | 无。 |
| Gemini Veo 视频 | 否 | 服务端内部 Gemini operation 轮询。 |
NewApiWG 普通图片 images/generations |
否 | 无。 |
| NewApiWG Gemini native 图片 | 否 | 无。 |
| NewApiWG chat 图片 | 否 | 无。 |
| NewApiWG 音频 | 否 | 无。 |
| NewApiWG 视频 | 否 | 可能服务端内部轮询 {baseUrl}/video/generations/{taskId}。 |
| Replicate | 否 | 服务端内部轮询 prediction。 |
| fal.ai | 否 | 服务端内部轮询 queue。 |
| WaveSpeed | 否 | 服务端内部轮询 prediction result。 |
| Kie.ai | 是 | 前端轮询 /api/generate/poll,服务端每次单次查询 Kie。 |
| LLM 文本 | 否 | 无。 |