AI网关新增xAI格式TTS端点与过滤弃用模型开关
- POST /ai/v1/tts:xAI 官方 TTS 格式转换层(text/voice_id→input/voice),复用 Speech 编排,model 缺省 xai.grok-tts;实测 output_format/speed 透传生效 - 「过滤弃用模型」开关(GET/PUT /api/v1/ai-settings,settings 表持久化):开启后已宣布弃用(未退役)模型从列表与路由排除;同步入库与退役提醒不受影响 - AI 网关文档更名 docs/AI网关.md,补 tts 矩阵段与开关说明;README 引用同步 - CHANGELOG 0.5.0(0.4.0 已发版冻结);DASH_VERSION v0.5.0
This commit is contained in:
@@ -12,6 +12,7 @@ AI 网关使用面板创建的独立密钥鉴权,支持 `Authorization: Bearer
|
||||
| `POST /ai/v1/messages` | Anthropic Messages 转换层 | SSE |
|
||||
| `POST /ai/v1/embeddings` | OpenAI Embeddings | 否 |
|
||||
| `POST /ai/v1/audio/speech` | OpenAI Audio Speech,文本转语音(xAI Voice) | 否 |
|
||||
| `POST /ai/v1/tts` | xAI 官方格式文本转语音(同一上游,网关转换) | 否 |
|
||||
| `POST /ai/v1/rerank` | 文档重排(Cohere Rerank,Jina 风格协议) | 否 |
|
||||
| `POST /ai/v1/moderations` | 内容审核(OCI Guardrails:内容审核 / PII / 提示注入) | 否 |
|
||||
| `GET /ai/v1/models` | 当前密钥可见的模型列表 | 否 |
|
||||
@@ -25,6 +26,7 @@ AI 网关使用面板创建的独立密钥鉴权,支持 `Authorization: Bearer
|
||||
- Chat Completions 只承担协议转换与兼容修复;新能力优先在 Responses 和 Messages 提供
|
||||
- 单次请求最多尝试三个渠道;可重试错误会切换渠道,流式响应建立后不会换渠道重试
|
||||
- Audio Speech 直通 OCI 兼容面(模型 `xai.grok-tts`,voice 取 xAI Grok Voice 列表:`ara`/`eve`/`leo`/`rex`/`sal`);上游把 `language` 当必填,缺省时网关自动注入 `"auto"`,xAI 专属参数(`output_format` 等)可平铺在请求体透传;仅单请求返回音频,不提供 WebSocket 流式
|
||||
- `/ai/v1/tts` 为 xAI 官方 TTS 格式(`text`/`language` 必填、`voice_id`、`output_format` 对象)的转换端点:网关转换为 OpenAI 兼容形态后走同一上游与渠道调度,`model` 为网关扩展字段(缺省 `xai.grok-tts`);实测 `output_format`(codec/sample_rate/bit_rate)与 `speed` 透传生效
|
||||
- Rerank 走 OCI typed 面(`cohere.rerank-v4.0-pro` / `-fast`),请求 `{model, query, documents[], top_n?, return_documents?}`,响应 `results[].index` 指向入参下标;无 token 用量口径,调用日志只记时延
|
||||
- Moderations 是 OpenAI moderations 外壳映射 OCI Guardrails:`input` 为字符串或字符串数组(至多 8 条),categories 用 OCI 原生维度 `overall` / `blocklist` / `prompt_injection`(阈值 0.5 判定 `flagged`),PII 命中放扩展字段 `results[].pii`(不参与 flagged);`model` 字段接受但忽略,无模型白名单维度;实测中文人名/手机号识别较弱,英文 PII 识别正常
|
||||
- Responses 的 `input_file` 内容块(file_url / file_data)实测被上游拒绝:`File content is currently unsupported for ZDR customers`——网关强制 `store:false` 属 ZDR 形态,该能力在上游侧不可用
|
||||
@@ -217,6 +219,32 @@ Audio Speech 与 Responses 同为“原始 JSON 直通 + 本地门禁”:除
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>POST /ai/v1/tts</code> 对比 xAI TTS</summary>
|
||||
|
||||
`/ai/v1/tts` 接受 [xAI 官方 TTS 格式](https://docs.x.ai/developers/model-capabilities/audio/text-to-speech)(OCI 无 HTTP 版 xAI 面,网关转换为 OpenAI 兼容形态后与 `/ai/v1/audio/speech` 走同一上游与调度)。
|
||||
|
||||
| 标准字段 | 状态 | 网关行为 |
|
||||
| --- | :---: | --- |
|
||||
| `text` | 🔄 | 必填非空,转换为上游 `input` |
|
||||
| `language` | ◐ | 必填(对齐 xAI 官方;接受 BCP-47 或 `auto`),原样透传 |
|
||||
| `voice_id` | 🔄 | 转换为上游 `voice`;缺省交上游默认(`eve`) |
|
||||
| `output_format` | ➡️ | `{codec, sample_rate, bit_rate}` 对象原样透传,实测生效(44.1kHz/192kbps 验证) |
|
||||
| `speed` | ➡️ | 原样透传,实测接受 |
|
||||
| `model`(网关扩展) | ◐ | xAI 官方无此字段;缺省注入 `xai.grok-tts`,可显式覆盖,受密钥白名单限制 |
|
||||
| `optimize_streaming_latency`、`text_normalization`、`with_timestamps` 及其他未知字段 | ➡️ | 原样透传,是否生效由上游决定 |
|
||||
|
||||
不支持:流式音频输出(xAI 官方 `optimize_streaming_latency` 面向流式场景,本端点响应恒为一次性完整音频);WebSocket 流式(OCI 另有 `wss://…/xai/v1/tts` 私有协议面,网关未代理)。
|
||||
|
||||
响应边界:
|
||||
|
||||
- 成功响应为音频字节,`Content-Type` 透传上游(缺省 `audio/mpeg`)
|
||||
- 无 token 用量口径,调用日志只记时延与渠道(端点名 `tts`)
|
||||
|
||||
实现依据:[`service/aigateway_extras.go`](../internal/service/aigateway_extras.go) · [`api/aigateway_extras.go`](../internal/api/aigateway_extras.go)
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>POST /ai/v1/rerank</code> 对比 Cohere Rerank</summary>
|
||||
|
||||
@@ -263,4 +291,4 @@ Moderations 是 OpenAI moderations 外壳映射 OCI Guardrails(内容审核 /
|
||||
|
||||
</details>
|
||||
|
||||
`GET /ai/v1/models` 使用 OpenAI Models 列表外壳(`object`、`data[].id/object/created/owned_by`),但只返回当前渠道目录中通过分组、全局黑名单和密钥白名单筛选后的模型;网关不提供标准的单模型检索端点。
|
||||
`GET /ai/v1/models` 使用 OpenAI Models 列表外壳(`object`、`data[].id/object/created/owned_by`),但只返回当前渠道目录中通过分组、全局黑名单和密钥白名单筛选后的模型;网关不提供标准的单模型检索端点。面板「过滤弃用模型」开关开启时,OCI 已宣布弃用(即使未到退役日)的模型同时从模型列表与路由中排除,关闭后恢复。
|
||||
+123
@@ -220,6 +220,33 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ai/v1/tts": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"AI 网关"
|
||||
],
|
||||
"summary": "xAI 官方格式文本转语音端点",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "xAI TTS 请求体(text/language 必填,voice_id 缺省 eve;model 为网关扩展,缺省 xai.grok-tts;未列字段原样透传)",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/oci-portal_internal_aiwire.TtsRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "音频字节(Content-Type 透传上游,默认 audio/mpeg)",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/about": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -705,6 +732,57 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/ai-settings": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AI 管理"
|
||||
],
|
||||
"summary": "AI 网关全局设置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/internal_api.aiSettingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AI 管理"
|
||||
],
|
||||
"summary": "更新 AI 网关全局设置",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "开启后已宣布弃用(即使未退役)的模型从列表与路由中排除",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/internal_api.aiSettingsResponse"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/internal_api.aiSettingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/auth/credentials": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -5893,6 +5971,14 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"internal_api.aiSettingsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"filterDeprecated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"internal_api.attachBootVolumeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -7689,6 +7775,43 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"oci-portal_internal_aiwire.TtsOutputFormat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bit_rate": {
|
||||
"type": "integer"
|
||||
},
|
||||
"codec": {
|
||||
"type": "string"
|
||||
},
|
||||
"sample_rate": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"oci-portal_internal_aiwire.TtsRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"output_format": {
|
||||
"$ref": "#/definitions/oci-portal_internal_aiwire.TtsOutputFormat"
|
||||
},
|
||||
"speed": {
|
||||
"type": "number"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"voice_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"oci-portal_internal_aiwire.Usage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -213,6 +213,33 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ai/v1/tts": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"AI 网关"
|
||||
],
|
||||
"summary": "xAI 官方格式文本转语音端点",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "xAI TTS 请求体(text/language 必填,voice_id 缺省 eve;model 为网关扩展,缺省 xai.grok-tts;未列字段原样透传)",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/oci-portal_internal_aiwire.TtsRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "音频字节(Content-Type 透传上游,默认 audio/mpeg)",
|
||||
"schema": {
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/about": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -698,6 +725,57 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/ai-settings": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AI 管理"
|
||||
],
|
||||
"summary": "AI 网关全局设置",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/internal_api.aiSettingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"AI 管理"
|
||||
],
|
||||
"summary": "更新 AI 网关全局设置",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "开启后已宣布弃用(即使未退役)的模型从列表与路由中排除",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/internal_api.aiSettingsResponse"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/internal_api.aiSettingsResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/auth/credentials": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -5886,6 +5964,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"internal_api.aiSettingsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"filterDeprecated": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"internal_api.attachBootVolumeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -7682,6 +7768,43 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"oci-portal_internal_aiwire.TtsOutputFormat": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bit_rate": {
|
||||
"type": "integer"
|
||||
},
|
||||
"codec": {
|
||||
"type": "string"
|
||||
},
|
||||
"sample_rate": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"oci-portal_internal_aiwire.TtsRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"output_format": {
|
||||
"$ref": "#/definitions/oci-portal_internal_aiwire.TtsOutputFormat"
|
||||
},
|
||||
"speed": {
|
||||
"type": "number"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"voice_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"oci-portal_internal_aiwire.Usage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -46,6 +46,11 @@ definitions:
|
||||
key:
|
||||
type: string
|
||||
type: object
|
||||
internal_api.aiSettingsResponse:
|
||||
properties:
|
||||
filterDeprecated:
|
||||
type: boolean
|
||||
type: object
|
||||
internal_api.attachBootVolumeRequest:
|
||||
properties:
|
||||
bootVolumeId:
|
||||
@@ -1219,6 +1224,30 @@ definitions:
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
oci-portal_internal_aiwire.TtsOutputFormat:
|
||||
properties:
|
||||
bit_rate:
|
||||
type: integer
|
||||
codec:
|
||||
type: string
|
||||
sample_rate:
|
||||
type: integer
|
||||
type: object
|
||||
oci-portal_internal_aiwire.TtsRequest:
|
||||
properties:
|
||||
language:
|
||||
type: string
|
||||
model:
|
||||
type: string
|
||||
output_format:
|
||||
$ref: '#/definitions/oci-portal_internal_aiwire.TtsOutputFormat'
|
||||
speed:
|
||||
type: number
|
||||
text:
|
||||
type: string
|
||||
voice_id:
|
||||
type: string
|
||||
type: object
|
||||
oci-portal_internal_aiwire.Usage:
|
||||
properties:
|
||||
completion_tokens:
|
||||
@@ -2752,6 +2781,23 @@ paths:
|
||||
summary: OpenAI Responses 兼容端点
|
||||
tags:
|
||||
- AI 网关
|
||||
/ai/v1/tts:
|
||||
post:
|
||||
parameters:
|
||||
- description: xAI TTS 请求体(text/language 必填,voice_id 缺省 eve;model 为网关扩展,缺省 xai.grok-tts;未列字段原样透传)
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/oci-portal_internal_aiwire.TtsRequest'
|
||||
responses:
|
||||
"200":
|
||||
description: 音频字节(Content-Type 透传上游,默认 audio/mpeg)
|
||||
schema:
|
||||
type: file
|
||||
summary: xAI 官方格式文本转语音端点
|
||||
tags:
|
||||
- AI 网关
|
||||
/api/v1/about:
|
||||
get:
|
||||
responses:
|
||||
@@ -3040,6 +3086,36 @@ paths:
|
||||
summary: '---- 聚合模型与调用日志 ----'
|
||||
tags:
|
||||
- AI 管理
|
||||
/api/v1/ai-settings:
|
||||
get:
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/internal_api.aiSettingsResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: AI 网关全局设置
|
||||
tags:
|
||||
- AI 管理
|
||||
put:
|
||||
parameters:
|
||||
- description: 开启后已宣布弃用(即使未退役)的模型从列表与路由中排除
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/internal_api.aiSettingsResponse'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/internal_api.aiSettingsResponse'
|
||||
security:
|
||||
- BearerAuth: []
|
||||
summary: 更新 AI 网关全局设置
|
||||
tags:
|
||||
- AI 管理
|
||||
/api/v1/auth/credentials:
|
||||
get:
|
||||
responses:
|
||||
|
||||
Reference in New Issue
Block a user