AI网关新增xAI格式TTS端点与过滤弃用模型开关
CI / test (push) Successful in 32s
Release / release (push) Successful in 54s

- 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:
2026-07-14 09:49:28 +08:00
parent 0a86b5a291
commit b4ef98a25e
17 changed files with 626 additions and 7 deletions
+29 -1
View File
@@ -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 RerankJina 风格协议) | 否 |
| `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
View File
@@ -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": {
+123
View File
@@ -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": {
+76
View File
@@ -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: