You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

15 KiB

模型生成接口整理(按当前代码)

整理依据为当前源码,不沿用旧文档结论。主要代码入口:

  • src/app/api/generate/route.ts
  • src/app/api/generate/providers/*.ts
  • src/app/api/generate/poll/route.ts
  • src/app/api/llm/route.ts
  • src/store/execution/*Executor.ts

1. 项目内部接口

内部接口 方法 当前调用方 作用
/api/generate POST nanoBananaExecutorgenerateVideoExecutorgenerateAudioExecutorgenerate3DExecutor 图片、视频、音频、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 会把 aspectRatioresolution 合并进 parameters,再交给 provider 文件处理。其他 provider 基本保留 imagespromptparametersdynamicInputs,只过滤空值。

3. 同步返回类接口

这里的“同步”指前端只调用一次项目内部接口。即使服务端内部轮询,也不会让前端调用 /api/generate/poll

3.1 Gemini 图片

代码:src/app/api/generate/providers/gemini.ts

上游调用 方法 当前用途
ai.models.generateContent(...) SDK Gemini 图片生成。模型映射在 MODEL_MAPnano-banananano-banana-pronano-banana-2

请求要点:

  • contents 包含 prompt 和 inline image。
  • config.responseModalities = ["IMAGE", "TEXT"]
  • aspectRatio 写入 config.imageConfig.aspectRatio
  • nano-banana-pronano-banana-2resolution 写入 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/generationsgenerateWithNewApiWG(...) 的分流顺序如下:

分流条件 实际上游接口 方法 说明
模型名匹配 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-imagegpt-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[]

当前参数规则:

  • sizeresolveNewApiWGImageSize(parameters) 计算。
  • 如果 parameters.imageSizeparameters.resolution5121K2K4K,会结合 aspectRatio/aspect_ratio 计算成类似 1024x1024 的尺寸。
  • response_format 固定为 b64_json
  • 透传参数会先删除这些字段:sizeimage_sizeoutput_sizedimensionsaspectRatioaspect_ratioresolutionimageSize
  • 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 归一化结果
imageimagesimage_urlimage_urlsfirst_frame_urllast_frame_urltail_image_urlreference_image_url(s) mediaInputs.images
videovideosvideo_urlvideo_urlsreference_video_url(s) mediaInputs.videos
audioaudiosaudio_urlaudio_urlsreference_audio_url(s) mediaInputs.audios

视频返回处理:

  • 如果响应里直接有 URL,立即返回 videoUrl
  • 如果响应里只有 task_idid,服务端调用 {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_urlhttps://queue.fal.run/{modelId}/requests/{requestId}/status GET 服务端内部轮询状态。
response_urlhttps://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.gethttps://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-KeyX-NewApiWG-Base-URL NEWAPIWG_API_KEYNEWAPIWG_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-KeyX-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-KeyX-NewApiWG-Base-URL NEWAPIWG_API_KEYNEWAPIWG_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 文本 无。