Skip to content

Add Kling provider support#3742

Open
wydream wants to merge 1 commit intohigress-group:mainfrom
wydream:feat/kling-provider-support
Open

Add Kling provider support#3742
wydream wants to merge 1 commit intohigress-group:mainfrom
wydream:feat/kling-provider-support

Conversation

@wydream
Copy link
Copy Markdown
Collaborator

@wydream wydream commented Apr 21, 2026

Ⅰ. Describe what this PR did

本 PR 新增 KlingAI provider,支持 KlingAI 官方 AK/SK JWT 鉴权、第三方网关静态 Bearer token,并同时覆盖 OpenAI 兼容协议与 Kling 原始协议。

背景

KlingAI 视频生成接口按任务类型拆分为:

  • 文生视频:/v1/videos/text2video
  • 图生视频:/v1/videos/image2video
  • 文生任务查询:/v1/videos/text2video/{video_id}
  • 图生任务查询:/v1/videos/image2video/{video_id}

同时社区存在 302.ai、New API 等网关服务,通常需要自定义 host、base path 和静态 Bearer token。因此 Kling provider 需要同时支持:

  • 官方直连:klingAccessKey + klingSecretKey 生成 HS256 JWT
  • 网关模式:复用 apiTokens 作为 Bearer token
  • providerDomain / providerBasePath 覆盖网关域名和路径前缀
  • OpenAI 兼容 /v1/videos 与 Kling 原始路径透传

主要变更

  1. 新增 Kling provider 注册与配置

    • 新增 providerTypeKling = "kling"
    • 新增 provider initializer:klingProviderInitializer
    • 新增配置项:
      • klingAccessKey
      • klingSecretKey
      • klingTokenRefreshAhead,默认 60
    • 支持两类认证:
      • 官方模式:AK/SK 生成并缓存 JWT,设置 Authorization: Bearer <jwt>
      • 网关模式:复用 apiTokens,设置 Authorization: Bearer <apiToken>
    • 当 AK/SK 和 apiTokens 同时配置时,优先官方 JWT
  2. 新增 Kling capability

    • openai/v1/videos -> /v1/videos/text2video
    • kling/v1/image2video -> /v1/videos/image2video
    • openai/v1/retrievevideo -> /v1/videos/text2video/{video_id}
    • kling/v1/retrieveimagevideo -> /v1/videos/image2video/{video_id}
    • ProviderConfig.setDefaultCapabilities 改为保留用户显式配置,不再覆盖自定义 capability
  3. OpenAI 兼容协议支持

    • POST /v1/videos 先按 text-to-video capability 做 header 阶段路径映射
    • body 阶段检测图像字段后切换到明确的 kling/v1/image2video capability
    • model 转换为 Kling 原生 model_name
    • model_name 输入也支持按 modelMapping 原地映射
    • 创建响应中的 task_id 自动加前缀:
      • 文生:kling-t2v-
      • 图生:kling-i2v-
    • 后续 GET /v1/videos/{task_id} 可通过前缀路由到正确的 text/image retrieve endpoint
  4. 任务查询路由与 query 处理

    • OpenAI retrieve 支持三种路由方式:
      • kling-i2v-<id> 前缀 -> image retrieve endpoint
      • kling-t2v-<id> 前缀 -> text retrieve endpoint
      • 原始 task id + kling_task_type=image2video|text2video hint -> 指定 retrieve endpoint
    • 内部 hint kling_task_type 在转发上游前剥离
    • 未知/非法 kling_task_type fallback 到默认 retrieve capability,同时也会剥离内部 hint
    • capability query 与客户端原始 query 会合并,并避免重复转发相同 query 片段
    • image-create body 阶段使用客户端原始 query,不继承 header 阶段临时 text capability query
  5. 原始协议支持

    • protocol: original 返回基础 klingProvider,不暴露 RequestBodyHandler
    • 原始协议只处理 host、base path、鉴权,不做 body/response 转换
    • 原始协议保留 Content-Length
    • 支持 Kling 原生 create/retrieve path 的 GetApiName 识别:
      • /v1/videos/text2video
      • /v1/videos/image2video
      • /v1/videos/text2video/{task_id}
      • /v1/videos/image2video/{task_id}
  6. 通用链路调整

    • main.go 只在 provider 实现 RequestBodyHandler 时才拦截 request body
    • 避免 original Kling 这类无 body handler provider 被无意义地 HeaderStopIteration
    • util.MapRequestPathByCapability 修复嵌套 provider path 中 {video_id} 占位符替换问题

修复前后对比

场景 变更前 变更后
Kling 官方直连 ❌ 不支持 ✅ AK/SK 生成 JWT Bearer
Kling 网关服务 ❌ 不支持 apiTokens 静态 Bearer
providerDomain / providerBasePath ❌ 无 Kling provider ✅ 支持 302.ai/New API 等网关
OpenAI /v1/videos 文生 ❌ 不支持 ✅ 转发 /v1/videos/text2video
OpenAI /v1/videos 图生 ❌ 不支持 ✅ body 阶段切换 /v1/videos/image2video
图生任务查询 ❌ 容易误路由到 text retrieve ✅ task id 前缀 / hint 路由到 image retrieve
query 参数 ⚠️ body 阶段可能丢失或混入错误 query ✅ capability query 与原始 query 正确合并
原始协议 body ⚠️ 会暴露 body handler / 拦截 body ✅ 不暴露 body handler,直接透传
原始协议 Content-Length ⚠️ 可能被删除 ✅ 保留

Ⅱ. Does this pull request fix one issue?

本 PR 是 KlingAI provider 能力新增,同时修复接入过程中发现的几个路由与协议边界问题:

  1. OpenAI-style image-to-video retrieve 需要路由到 image retrieve endpoint
  2. create/retrieve query 参数需要正确保留、合并并剥离内部 hint
  3. original Kling provider 不应暴露 request body handler
  4. original 协议不应删除 Content-Length

Ⅲ. Why don't you add test cases (unit test/integration test)?

已补充 provider 单测和插件链路测试,覆盖主要分支和边界:

  • ✅ 配置解析:klingAccessKeyklingSecretKeyklingTokenRefreshAhead、Kling 自定义 capability
  • ✅ 配置校验:官方 AK/SK、网关 token、部分 AK/SK 缺失、无认证配置
  • ✅ provider 创建:OpenAI wrapper 暴露 body/response handler,original provider 不暴露
  • ✅ JWT:HS256 header/payload/signature,token cache 与 refresh ahead
  • ✅ header 转换:
    • 官方 JWT Bearer
    • 网关静态 Bearer
    • 默认 host
    • providerDomain 不被默认 host 覆盖
    • OpenAI 模式删除 Content-Length
    • original 模式保留 Content-Length
  • ✅ body 转换:
    • model -> model_name
    • model_name 原地映射
    • 文生 / 图生 path 切换
    • image-create 使用明确 kling/v1/image2video capability
    • image-create 不继承 header 阶段 text capability query
  • ✅ retrieve 路由:
    • text/image task id 前缀
    • kling_task_type hint
    • prefixed task id 剥离内部 hint
    • 未知 hint fallback 且不转发内部 hint
    • 自定义 image retrieve capability
    • capability query 与请求 query 合并
  • ✅ response 转换:
    • 文生/图生创建响应 task id 前缀
    • retrieve response 透传
  • ✅ original 协议:
    • 原始 create path 只应用 providerBasePath
    • 原始 retrieve path 识别
    • 不触发 request body handler
    • 保留 Content-Length
  • ✅ 插件链路:
    • 官方模式 header/path/auth
    • 网关模式 providerDomain / providerBasePath
    • OpenAI 文生/图生创建
    • image-create 自定义 capability + query merge
    • retrieve text/image routing
    • prefixed/raw task id 的 hint 剥离

Ⅳ. Describe how to verify it

定向验证 Kling provider 单测

cd plugins/wasm-go/extensions/ai-proxy
go test ./provider -run Kling -count=1 -gcflags='all=-N -l'

定向验证 Kling 插件链路测试

cd plugins/wasm-go/extensions/ai-proxy
go test . -run TestKling -count=1 -gcflags='all=-N -l'

全量验证

cd plugins/wasm-go/extensions/ai-proxy
go test ./...

本地验证结果:

  1. go test ./provider -run Kling -count=1 -gcflags='all=-N -l' 通过
  2. go test . -run TestKling -count=1 -gcflags='all=-N -l' 通过
  3. go test ./... 通过

Ⅴ. Special notes for reviews

  1. 官方鉴权优先级:只要配置了完整 klingAccessKey + klingSecretKey,就优先使用官方 JWT;apiTokens 仅作为网关模式 Bearer。
  2. image-create capability 是 Kling 私有能力openai/v1/videos 仍作为 OpenAI 客户端入口;kling/v1/image2video 用于 body 阶段根据图像字段切换上游 endpoint。
  3. retrieve image capability 独立存在:Kling 原生查询接口按 text/image 拆分,不能只依赖 openai/v1/retrievevideo
  4. kling_task_type 是内部 hint:只用于 raw task id 的 OpenAI-style retrieve 路由,转发上游前必须剥离。
  5. query merge 使用客户端原始 query:body 阶段不使用 header 阶段已映射 path 的 query,避免 text capability query 污染 image-create。
  6. original 协议没有 body handler:这是为了保持 Kling 原始协议透传,只处理 host/base path/auth。
  7. setDefaultCapabilities 行为调整:改为不覆盖用户自定义 capability,避免 provider 初始化覆盖配置中的 Kling gateway path。

Ⅵ. AI Coding Tool Usage Checklist (if applicable)

Please check all applicable items:

  • For regular updates/changes (not new plugins):
    • I have included the AI Coding summary below

AI Coding Summary

关键决策:

  1. Kling provider 同时支持官方 AK/SK JWT 与网关静态 Bearer,官方凭证优先。
  2. OpenAI /v1/videos 保持单一客户端入口,body 阶段根据 image 字段切换 text/image upstream capability。
  3. 通过 task id 前缀和 kling_task_type hint 解决 Kling retrieve endpoint 按任务类型拆分的问题。
  4. original provider 不暴露 request body handler,避免原始协议被 OpenAI 兼容转换链路处理。
  5. query 合并以客户端原始 query 为准,内部 hint 不转发给上游。

主要改动范围:

  1. provider/kling.go
    • 新增 Kling provider、JWT 鉴权、OpenAI 兼容转换、original 协议透传
    • 新增 text/image create 与 retrieve capability 映射
    • 新增 task id prefix、retrieve hint、query merge 逻辑
  2. provider/provider.go
    • 注册 kling provider
    • 新增 Kling 配置项与 Kling 私有 capability
    • setDefaultCapabilities 保留用户自定义 capability
  3. main.go
    • 仅当 provider 实现 RequestBodyHandler 时才拦截 request body
  4. util/http.go
    • 修复 capability path 中 {video_id} 等占位符替换
  5. provider/kling_test.go
    • 新增 Kling provider 单测
  6. test/kling.go
    • 新增 Kling 插件链路测试
  7. main_test.goprovider/provider_test.gotest/util.go
    • 接入 Kling 测试入口及通用回归测试

验证结果:

  1. go test ./provider -run Kling -count=1 -gcflags='all=-N -l' 通过
  2. go test . -run TestKling -count=1 -gcflags='all=-N -l' 通过
  3. go test ./... 通过

Ⅰ. Describe what this PR did

This PR adds a new KlingAI provider, supports KlingAI official AK/SK JWT authentication, third-party gateway static Bearer token, and covers both OpenAI compatible protocols and Kling original protocols.

Background

KlingAI video generation interface is split according to task type:

  • Vincent Video: /v1/videos/text2video
  • Tusheng Video: /v1/videos/image2video
  • Vincent task query: /v1/videos/text2video/{video_id}
  • Tusheng task query: /v1/videos/image2video/{video_id}

At the same time, there are gateway services such as 302.ai and New API in the community, which usually require customized host, base path and static Bearer token. Therefore, Kling provider needs to support both:

  • Official direct connection: klingAccessKey + klingSecretKey generate HS256 JWT
  • Gateway mode: reuse apiTokens as Bearer tokens
  • providerDomain / providerBasePath overrides the gateway domain name and path prefix
  • OpenAI is compatible with /v1/videos and Kling original path transparent transmission

Major changes

  1. Added Kling provider registration and configuration

    • Added providerTypeKling = "kling"
    • Added provider initializer: klingProviderInitializer
    • New configuration items:
      • klingAccessKey
      • klingSecretKey
      • klingTokenRefreshAhead, default 60
    • Supports two types of authentication:
      • Official mode: AK/SK generates and caches JWT, set Authorization: Bearer <jwt>
      • Gateway mode: reuse apiTokens, set Authorization: Bearer <apiToken>
    • When AK/SK and apiTokens are configured at the same time, the official JWT takes precedence
  2. New Kling capability

    • openai/v1/videos -> /v1/videos/text2video
    • kling/v1/image2video -> /v1/videos/image2video
    • openai/v1/retrievevideo -> /v1/videos/text2video/{video_id}
    • kling/v1/retrieveimagevideo -> /v1/videos/image2video/{video_id}
    • ProviderConfig.setDefaultCapabilities is changed to retain the user's explicit configuration and no longer overrides the custom capability
  3. OpenAI compatible protocol support

    • POST /v1/videos first press text-to-video capability to do header stage path mapping
    • Switch to the explicit kling/v1/image2video capability after detecting the image field in the body stage
    • model converted to Kling native model_name
    • model_name input also supports in-place mapping by modelMapping
    • Automatically prefix task_id in creation response:
      • Vincent: kling-t2v-
      • Tusheng: kling-i2v-
    • Subsequent GET /v1/videos/{task_id} can be routed to the correct text/image retrieve endpoint via the prefix
  4. Task query routing and query processing

    • OpenAI retrieve supports three routing methods:
      • kling-i2v-<id> prefix -> image retrieve endpoint
      • kling-t2v-<id> prefix -> text retrieve endpoint
      • Original task id + kling_task_type=image2video|text2video hint -> specify retrieve endpoint
    • Internal hint kling_task_type stripped before forwarding upstream
    • Unknown/illegal kling_task_type fallback to default retrieve capability, also stripping internal hints
    • capability query will be merged with the client’s original query and avoid forwarding the same query fragment repeatedly
    • The image-create body phase uses the client's original query and does not inherit the temporary text capability query of the header phase.
  5. Original protocol support

    • protocol: original returns the base klingProvider and does not expose RequestBodyHandler
    • The original protocol only handles host, base path, and authentication, and does not perform body/response conversion.
    • Original protocol retains Content-Length
    • Support GetApiName recognition of Kling’s native create/retrieve path:
      • /v1/videos/text2video
      • /v1/videos/image2video
      • /v1/videos/text2video/{task_id}
      • /v1/videos/image2video/{task_id}
  6. Universal Link Adjustment

    • main.go only intercepts the request body if the provider implements RequestBodyHandler
    • Prevent body handler providers such as original Kling from being meaninglessly HeaderStopIteration
    • util.MapRequestPathByCapability fixes {video_id} placeholder replacement problem in nested provider path

Comparison before and after repair

Scenario Before the change After the change
Kling official direct connection ❌ Not supported ✅ AK/SK generated JWT Bearer
Kling Gateway Service ❌ Not supported apiTokens static Bearer
providerDomain / providerBasePath ❌ No Kling provider ✅ Support gateways such as 302.ai/New API
OpenAI /v1/videos Vincent ❌ Not supported ✅ Forward /v1/videos/text2video
OpenAI /v1/videos Tusheng ❌ Not supported ✅ body stage switching /v1/videos/image2video
Tusheng task query ❌ Easily routed to text retrieve by mistake ✅ task id prefix/hint routed to image retrieve
query parameters ⚠️ The body stage may be missing or mixed with wrong query ✅ capability query is correctly merged with the original query
Original protocol body ⚠️ Will expose body handler / intercept body ✅ Does not expose body handler, direct transparent transmission
Original Agreement Content-Length ⚠️ May be deleted ✅ Reserved

Ⅱ. Does this pull request fix one issue?

This PR is a new addition to KlingAI provider capabilities, and also fixes several routing and protocol boundary issues discovered during the access process:

  1. OpenAI-style image-to-video retrieve needs to be routed to image retrieve endpoint
  2. Create/retrieve query parameters need to be correctly retained, merged and stripped of internal hints
  3. original Kling provider should not expose request body handler
  4. The original protocol should not delete Content-Length

Ⅲ. Why don't you add test cases (unit test/integration test)?

Provider single test and plug-in link test have been added to cover main branches and boundaries:

  • ✅ Configuration analysis: klingAccessKey, klingSecretKey, klingTokenRefreshAhead, Kling custom capability
  • ✅ Configuration verification: official AK/SK, gateway token, some AK/SK missing, no authentication configuration
  • ✅ Provider creation: OpenAI wrapper exposes body/response handler, original provider is not exposed
  • ✅ JWT: HS256 header/payload/signature, token cache and refresh ahead
  • ✅ header conversion:
    • Official JWT Bearer
    • Gateway static Bearer
      -Default host
    • providerDomain is not overridden by default host
    • OpenAI mode removed Content-Length
    • original mode retains Content-Length
  • ✅ body conversion:
    • model -> model_name
    • model_name in-place mapping
    • Vincent / Tusheng path switching
    • image-create uses explicit kling/v1/image2video capability
    • image-create does not inherit the header stage text capability query
  • ✅ retrieve route:
    • text/image task id prefix
    • kling_task_type hint
    • prefixed task id strips internal hints
    • Unknown hint fallback and does not forward internal hints
    • Custom image retrieval capability
    • capability query merged with request query
  • ✅ response conversion:
    • Vincent/Tusheng creates response task id prefix
    • retrieve response transparent transmission
  • ✅ original agreement:
    • Original create path only applies providerBasePath
    • Original retrieve path identification
    • Do not trigger request body handler
    • Keep Content-Length
  • ✅ Plug-in link:
    • Official mode header/path/auth
    • Gateway mode providerDomain / providerBasePath
    • OpenAI Wensheng/Tusheng creation
    • image-create custom capability + query merge
    • retrieve text/image routing
    • Hint stripping of prefixed/raw task id

Ⅳ. Describe how to verify it

Directed verification Kling provider single test

cd plugins/wasm-go/extensions/ai-proxy
go test ./provider -run Kling -count=1 -gcflags='all=-N -l'

Directed verification Kling plug-in link test

cd plugins/wasm-go/extensions/ai-proxy
go test . -run TestKling -count=1 -gcflags='all=-N -l'

Full verification

cd plugins/wasm-go/extensions/ai-proxy
go test ./...

Local verification results:

  1. go test ./provider -run Kling -count=1 -gcflags='all=-N -l' passed
  2. go test . -run TestKling -count=1 -gcflags='all=-N -l' passed
  3. go test ./... passed

Ⅴ. Special notes for reviews

  1. Official authentication priority: As long as the complete klingAccessKey + klingSecretKey is configured, the official JWT will be used first; apiTokens is only used as a gateway mode Bearer.
  2. image-create capability is Kling’s private capability: openai/v1/videos is still used as the OpenAI client entry; kling/v1/image2video is used in the body stage to switch upstream endpoints based on the image field.
  3. retrieve image capability exists independently: Kling’s native query interface is split by text/image and cannot only rely on openai/v1/retrievevideo.
  4. kling_task_type is an internal hint: only used for OpenAI-style retrieve routing of raw task id, which must be stripped before forwarding to the upstream.
  5. query merge uses the client's original query: the body stage does not use the query with path mapped in the header stage to avoid text capability query contaminating image-create.
  6. Original protocol does not have a body handler: This is to maintain the transparent transmission of Kling’s original protocol and only handle host/base path/auth.
  7. setDefaultCapabilities behavior adjustment: Changed to not overwriting user-defined capabilities to prevent provider initialization from overwriting the Kling gateway path in the configuration.

Ⅵ. AI Coding Tool Usage Checklist (if applicable)

Please check all applicable items:

  • For regular updates/changes (not new plugins):
    • I have included the AI Coding summary below

AI Coding Summary

Key Decisions:

  1. Kling provider supports both official AK/SK JWT and gateway static Bearer, with official credentials taking priority.
  2. OpenAI /v1/videos maintains a single client entry, and switches the text/image upstream capability according to the image field in the body stage.
  3. Solve the problem of Kling retrieve endpoint splitting by task type through task id prefix and kling_task_type hint.
  4. The original provider does not expose the request body handler to prevent the original protocol from being processed by the OpenAI compatible conversion link.
  5. Query merging is based on the client’s original query, and internal hints are not forwarded to the upstream.

Main scope of changes:

  1. provider/kling.go
    • Added Kling provider, JWT authentication, OpenAI compatible conversion, original protocol transparent transmission
    • Added text/image create and retrieve capability mappings
    • Added task id prefix, retrieve hint, query merge logic
  2. provider/provider.go
    • Register kling provider
    • Added Kling configuration items and Kling private capabilities
    • setDefaultCapabilities retains user-defined capabilities
  3. main.go
    • Intercept request body only if provider implements RequestBodyHandler
  4. util/http.go
    • Fixed replacement of placeholders such as {video_id} in capability path
  5. provider/kling_test.go
    • Added Kling provider single test
  6. test/kling.go
    • Added Kling plug-in link test
  7. main_test.go, provider/provider_test.go, test/util.go
    • Access Kling test portal and general regression testing

Verification result:

  1. go test ./provider -run Kling -count=1 -gcflags='all=-N -l' passed
  2. go test . -run TestKling -count=1 -gcflags='all=-N -l' passed
  3. go test ./... passed

Change-Id: I2f5c5a595681d9d2bbcefaecd2b81972341decda
Co-developed-by: Codex <noreply@openai.com>
@wydream wydream requested review from johnlanni and rinfx as code owners April 21, 2026 10:39
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 21, 2026

Codecov Report

❌ Patch coverage is 97.22222% with 18 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...gins/wasm-go/extensions/ai-proxy/provider/kling.go 93.93% 9 Missing and 9 partials ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants