feat(gateway): 补齐桌面端高级媒体直连接口
ci / verify (pull_request) Successful in 15m34s

新增图片矢量化、视频超分、每日用量、计价与任务隔离能力,并通过环境变量解析平台凭据。

已通过 Go 全量门禁、迁移检查、镜像构建以及 Vectorizer 五格式和 Topaz 3 秒视频真实 DEV 验收。
This commit is contained in:
2026-07-22 14:02:53 +08:00
parent cbebfd7baa
commit 3056cf8fca
37 changed files with 3336 additions and 29 deletions
+467 -4
View File
@@ -4710,6 +4710,15 @@
"volces-compatible"
],
"summary": "查询 server-main 兼容视频结果",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "taskID",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
@@ -5568,6 +5577,15 @@
"volces-compatible"
],
"summary": "查询火山内容生成任务",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "taskID",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
@@ -5592,6 +5610,15 @@
"volces-compatible"
],
"summary": "取消火山内容生成任务",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "taskID",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
@@ -6094,6 +6121,87 @@
}
}
},
"/api/v1/images/vectorize": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "将 URL 位图转换为 SVG、EPS、PDF、DXF 或 PNG;设置 X-Async=true 时返回统一异步任务结构。可使用同一所有者历史任务的 vectorizerTaskId 复用上游 image token。",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"images"
],
"summary": "图片矢量化",
"parameters": [
{
"type": "boolean",
"description": "true 时异步创建任务并返回 202",
"name": "X-Async",
"in": "header"
},
{
"description": "图片矢量化请求",
"name": "input",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/httpapi.ImageVectorizeRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httpapi.CompatibleResponse"
}
},
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/httpapi.TaskAcceptedResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"502": {
"description": "Bad Gateway",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/v1/kling/v1/videos/omni-video": {
"get": {
"security": [
@@ -8167,6 +8275,87 @@
}
}
},
"/api/v1/videos/upscales": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "原生执行 Topaz 视频增强流程;设置 X-Async=true 时返回统一异步任务结构,结果在任务完成前持久化到 Gateway 文件存储。",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"videos"
],
"summary": "视频超分",
"parameters": [
{
"type": "boolean",
"description": "true 时异步创建任务并返回 202",
"name": "X-Async",
"in": "header"
},
{
"description": "视频超分请求",
"name": "input",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/httpapi.VideoUpscaleRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httpapi.CompatibleResponse"
}
},
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/httpapi.TaskAcceptedResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"502": {
"description": "Bad Gateway",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/v1/voice_clone": {
"post": {
"security": [
@@ -8709,6 +8898,72 @@
}
}
},
"/api/workspace/token-usage/daily": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "按 IANA 时区返回连续自然日用量;API Key 仅统计当前 KeyJWT 统计当前用户。",
"produces": [
"application/json"
],
"tags": [
"workspace"
],
"summary": "查询每日 Token 与资源点用量",
"parameters": [
{
"type": "string",
"description": "开始日期 YYYY-MM-DD",
"name": "from",
"in": "query",
"required": true
},
{
"type": "string",
"description": "结束日期 YYYY-MM-DD",
"name": "to",
"in": "query",
"required": true
},
{
"type": "string",
"default": "UTC",
"description": "IANA 时区",
"name": "timezone",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httpapi.DailyTokenUsageResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/workspace/user-groups": {
"get": {
"security": [
@@ -9498,6 +9753,32 @@
}
}
},
"httpapi.DailyTokenUsageResponse": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/store.DailyTokenUsage"
}
},
"range": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"summary": {
"$ref": "#/definitions/httpapi.dailyTokenUsageSummary"
},
"tokenDays": {
"type": "array",
"items": {
"$ref": "#/definitions/store.DailyTokenUsage"
}
}
}
},
"httpapi.ErrorEnvelope": {
"type": "object",
"properties": {
@@ -9589,6 +9870,63 @@
}
}
},
"httpapi.ImageVectorizeRequest": {
"type": "object",
"properties": {
"cleanupLevel": {
"type": "string",
"enum": [
"low",
"standard",
"strong"
],
"example": "standard"
},
"format": {
"type": "string",
"enum": [
"svg",
"eps",
"pdf",
"dxf",
"png"
],
"example": "svg"
},
"maxColors": {
"type": "integer",
"enum": [
0,
2,
4,
8,
16,
32
],
"example": 16
},
"model": {
"type": "string",
"example": "easy-image-vectorizer-1"
},
"source": {
"$ref": "#/definitions/httpapi.ImageVectorizeSource"
}
}
},
"httpapi.ImageVectorizeSource": {
"type": "object",
"properties": {
"url": {
"type": "string",
"example": "https://example.com/source.png"
},
"vectorizerTaskId": {
"type": "string",
"example": "9f4d8f3d-5f5f-4bb7-a4be-344a9f930e25"
}
}
},
"httpapi.KelingCompatibleEnvelope": {
"type": "object",
"properties": {
@@ -10528,10 +10866,24 @@
"type": "number",
"example": 0.65
},
"audio_url": {
"type": "string",
"example": "https://example.com/source-voice.mp3"
},
"customMode": {
"type": "boolean",
"example": false
},
"display_name": {
"type": "string",
"example": "EasyAI DEV acceptance"
},
"documents": {
"type": "array",
"items": {
"type": "string"
}
},
"duration": {
"type": "integer",
"example": 5
@@ -10576,10 +10928,26 @@
"type": "number",
"example": 0
},
"preview_model": {
"type": "string",
"example": "speech-2.8-hd"
},
"prompt": {
"type": "string",
"example": "A watercolor robot reading a book"
},
"prompt_audio_url": {
"type": "string",
"example": "https://example.com/prompt-voice.mp3"
},
"prompt_text": {
"type": "string",
"example": "EasyAI voice clone prompt."
},
"query": {
"type": "string",
"example": "Which document mentions EasyAI Gateway?"
},
"reasoning_effort": {
"description": "ReasoningEffort 推理强度,OpenAI-compatible 请求字段;支持 none、minimal、low、medium、high、xhigh、max。供应商自定义取值由网关按平台适配。",
"type": "string",
@@ -10693,6 +11061,62 @@
}
}
},
"httpapi.VideoUpscaleRequest": {
"type": "object",
"properties": {
"duration": {
"type": "number",
"example": 3
},
"model": {
"type": "string",
"example": "easy-proteus-standard-4"
},
"operation": {
"type": "string",
"enum": [
"upscale"
],
"example": "upscale"
},
"output_height": {
"type": "integer",
"example": 1080
},
"output_width": {
"type": "integer",
"example": 1920
},
"preserve_audio": {
"type": "boolean",
"example": true
},
"slow_motion_rate": {
"type": "number",
"example": 1
},
"source_frame_rate": {
"type": "number",
"example": 24
},
"source_resolution": {
"type": "string",
"example": "480p"
},
"target_frame_rate": {
"type": "number",
"example": 24
},
"target_resolution": {
"type": "string",
"example": "1080p"
},
"video_url": {
"type": "string",
"example": "https://example.com/source.mp4"
}
}
},
"httpapi.WalletAdjustmentResponse": {
"type": "object",
"properties": {
@@ -10733,6 +11157,23 @@
}
}
},
"httpapi.dailyTokenUsageSummary": {
"type": "object",
"properties": {
"cumulativeTokens": {
"type": "integer"
},
"currentStreakDays": {
"type": "integer"
},
"longestStreakDays": {
"type": "integer"
},
"peakDailyTokens": {
"type": "integer"
}
}
},
"httpapi.desktopBillingConfigResponse": {
"type": "object",
"properties": {
@@ -11997,6 +12438,32 @@
}
}
},
"store.DailyTokenUsage": {
"type": "object",
"properties": {
"cachedInputTokens": {
"type": "integer"
},
"date": {
"type": "string"
},
"inputTokens": {
"type": "integer"
},
"outputTokens": {
"type": "integer"
},
"resourcePoints": {
"type": "number"
},
"taskCount": {
"type": "integer"
},
"totalTokens": {
"type": "integer"
}
}
},
"store.FileStorageChannel": {
"type": "object",
"properties": {
@@ -12224,10 +12691,6 @@
"remoteTaskId": {
"type": "string"
},
"remoteTaskPayload": {
"type": "object",
"additionalProperties": {}
},
"request": {
"type": "object",
"additionalProperties": {}
+318 -3
View File
@@ -329,6 +329,23 @@ definitions:
additionalProperties: true
type: object
type: object
httpapi.DailyTokenUsageResponse:
properties:
items:
items:
$ref: '#/definitions/store.DailyTokenUsage'
type: array
range:
additionalProperties:
type: string
type: object
summary:
$ref: '#/definitions/httpapi.dailyTokenUsageSummary'
tokenDays:
items:
$ref: '#/definitions/store.DailyTokenUsage'
type: array
type: object
httpapi.ErrorEnvelope:
properties:
error:
@@ -393,6 +410,49 @@ definitions:
example: easyai-ai-gateway
type: string
type: object
httpapi.ImageVectorizeRequest:
properties:
cleanupLevel:
enum:
- low
- standard
- strong
example: standard
type: string
format:
enum:
- svg
- eps
- pdf
- dxf
- png
example: svg
type: string
maxColors:
enum:
- 0
- 2
- 4
- 8
- 16
- 32
example: 16
type: integer
model:
example: easy-image-vectorizer-1
type: string
source:
$ref: '#/definitions/httpapi.ImageVectorizeSource'
type: object
httpapi.ImageVectorizeSource:
properties:
url:
example: https://example.com/source.png
type: string
vectorizerTaskId:
example: 9f4d8f3d-5f5f-4bb7-a4be-344a9f930e25
type: string
type: object
httpapi.KelingCompatibleEnvelope:
properties:
code:
@@ -1034,12 +1094,22 @@ definitions:
audio:
example: false
type: boolean
audio_url:
example: https://example.com/source-voice.mp3
type: string
audioWeight:
example: 0.65
type: number
customMode:
example: false
type: boolean
display_name:
example: EasyAI DEV acceptance
type: string
documents:
items:
type: string
type: array
duration:
example: 5
type: integer
@@ -1073,9 +1143,21 @@ definitions:
pitch:
example: 0
type: number
preview_model:
example: speech-2.8-hd
type: string
prompt:
example: A watercolor robot reading a book
type: string
prompt_audio_url:
example: https://example.com/prompt-voice.mp3
type: string
prompt_text:
example: EasyAI voice clone prompt.
type: string
query:
example: Which document mentions EasyAI Gateway?
type: string
reasoning_effort:
description: ReasoningEffort 推理强度,OpenAI-compatible 请求字段;支持 none、minimal、low、medium、high、xhigh、max。供应商自定义取值由网关按平台适配。
enum:
@@ -1158,6 +1240,47 @@ definitions:
$ref: '#/definitions/store.GatewayUser'
type: array
type: object
httpapi.VideoUpscaleRequest:
properties:
duration:
example: 3
type: number
model:
example: easy-proteus-standard-4
type: string
operation:
enum:
- upscale
example: upscale
type: string
output_height:
example: 1080
type: integer
output_width:
example: 1920
type: integer
preserve_audio:
example: true
type: boolean
slow_motion_rate:
example: 1
type: number
source_frame_rate:
example: 24
type: number
source_resolution:
example: 480p
type: string
target_frame_rate:
example: 24
type: number
target_resolution:
example: 1080p
type: string
video_url:
example: https://example.com/source.mp4
type: string
type: object
httpapi.WalletAdjustmentResponse:
properties:
account:
@@ -1185,6 +1308,17 @@ definitions:
example: 42
type: integer
type: object
httpapi.dailyTokenUsageSummary:
properties:
cumulativeTokens:
type: integer
currentStreakDays:
type: integer
longestStreakDays:
type: integer
peakDailyTokens:
type: integer
type: object
httpapi.desktopBillingConfigResponse:
properties:
gatewayBaseUrl:
@@ -2044,6 +2178,23 @@ definitions:
secret:
type: string
type: object
store.DailyTokenUsage:
properties:
cachedInputTokens:
type: integer
date:
type: string
inputTokens:
type: integer
outputTokens:
type: integer
resourcePoints:
type: number
taskCount:
type: integer
totalTokens:
type: integer
type: object
store.FileStorageChannel:
properties:
channelKey:
@@ -2197,9 +2348,6 @@ definitions:
type: object
remoteTaskId:
type: string
remoteTaskPayload:
additionalProperties: {}
type: object
request:
additionalProperties: {}
type: object
@@ -6344,6 +6492,12 @@ paths:
- playground
/api/v1/ai/result/{taskID}:
get:
parameters:
- description: 任务 ID
in: path
name: taskID
required: true
type: string
produces:
- application/json
responses:
@@ -6897,6 +7051,12 @@ paths:
/api/v1/contents/generations/tasks/{taskID}:
delete:
description: 取消网关任务;对于已提交且保存了上游任务标识的 Volces 视频任务,同时调用火山 DELETE 接口并持久化取消状态。
parameters:
- description: 任务 ID
in: path
name: taskID
required: true
type: string
produces:
- application/json
responses:
@@ -6911,6 +7071,12 @@ paths:
tags:
- volces-compatible
get:
parameters:
- description: 任务 ID
in: path
name: taskID
required: true
type: string
produces:
- application/json
responses:
@@ -7241,6 +7407,59 @@ paths:
summary: 创建或执行 AI 任务
tags:
- tasks
/api/v1/images/vectorize:
post:
consumes:
- application/json
description: 将 URL 位图转换为 SVG、EPS、PDF、DXF 或 PNG;设置 X-Async=true 时返回统一异步任务结构。可使用同一所有者历史任务的
vectorizerTaskId 复用上游 image token。
parameters:
- description: true 时异步创建任务并返回 202
in: header
name: X-Async
type: boolean
- description: 图片矢量化请求
in: body
name: input
required: true
schema:
$ref: '#/definitions/httpapi.ImageVectorizeRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/httpapi.CompatibleResponse'
"202":
description: Accepted
schema:
$ref: '#/definitions/httpapi.TaskAcceptedResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"404":
description: Not Found
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"502":
description: Bad Gateway
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 图片矢量化
tags:
- images
/api/v1/kling/v1/videos/omni-video:
get:
parameters:
@@ -8578,6 +8797,59 @@ paths:
summary: 查询 Kling Omni 视频任务
tags:
- kling-compatible
/api/v1/videos/upscales:
post:
consumes:
- application/json
description: 原生执行 Topaz 视频增强流程;设置 X-Async=true 时返回统一异步任务结构,结果在任务完成前持久化到 Gateway
文件存储。
parameters:
- description: true 时异步创建任务并返回 202
in: header
name: X-Async
type: boolean
- description: 视频超分请求
in: body
name: input
required: true
schema:
$ref: '#/definitions/httpapi.VideoUpscaleRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/httpapi.CompatibleResponse'
"202":
description: Accepted
schema:
$ref: '#/definitions/httpapi.TaskAcceptedResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"404":
description: Not Found
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"502":
description: Bad Gateway
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 视频超分
tags:
- videos
/api/v1/voice_clone:
post:
consumes:
@@ -8925,6 +9197,49 @@ paths:
summary: 获取任务参数预处理日志
tags:
- tasks
/api/workspace/token-usage/daily:
get:
description: 按 IANA 时区返回连续自然日用量;API Key 仅统计当前 Key,JWT 统计当前用户。
parameters:
- description: 开始日期 YYYY-MM-DD
in: query
name: from
required: true
type: string
- description: 结束日期 YYYY-MM-DD
in: query
name: to
required: true
type: string
- default: UTC
description: IANA 时区
in: query
name: timezone
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/httpapi.DailyTokenUsageResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 查询每日 Token 与资源点用量
tags:
- workspace
/api/workspace/user-groups:
get:
description: 返回当前用户关联的用户组及策略摘要,供个人中心使用。