From 0a86b5a291f4b5840593e40267b545e4011c0678 Mon Sep 17 00:00:00 2001
From: Wang Defa <1+wangdefa@noreply.gitea.bcde.io>
Date: Mon, 13 Jul 2026 20:17:06 +0800
Subject: [PATCH] =?UTF-8?q?AI=E7=BD=91=E5=85=B3=E6=96=B0=E5=A2=9ETTS/?=
=?UTF-8?q?=E9=87=8D=E6=8E=92/=E5=AE=A1=E6=A0=B8=E7=AB=AF=E7=82=B9,xAI?=
=?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=89=A9=E5=B1=95,swagger=E4=BF=AE=E7=BC=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新端点 /ai/v1/audio/speech(xai.grok-tts)、/rerank(cohere.rerank-v4)、/moderations(OCI Guardrails)
- Responses 放行 code_interpreter 与远程 mcp 工具,web_search/x_search 解除仅非流式限制
- 模型能力映射扩展:TEXT_RERANK→RERANK、TEXT_TO_AUDIO→TTS
- AI 网关文档独立 docs/ai-gateway.md,字段兼容矩阵只列支持项;README 精简引用
- swagger 修缺:135 处响应注解具体化,RawMessage/联合类型统一渲染 AnyJSON,overrides 迁至 docs/.swaggo
- CHANGELOG 0.4.0,版本段不再记日期;DASH_VERSION v0.4.0
---
.trellis/spec/backend/index.md | 4 +-
CHANGELOG.md | 27 +-
DASH_VERSION | 2 +-
README.md | 202 +-
docs/.swaggo | 6 +
docs/ai-gateway.md | 266 ++
docs/docs.go | 3773 +++++++++++++++++++--
docs/swagger.json | 3773 +++++++++++++++++++--
docs/swagger.yaml | 2639 ++++++++++++--
internal/aiwire/anyjson.go | 5 +
internal/aiwire/moderations.go | 45 +
internal/aiwire/rerank.go | 28 +
internal/aiwire/responses.go | 13 +
internal/api/about.go | 2 +-
internal/api/aiadmin.go | 27 +-
internal/api/aigateway.go | 18 +-
internal/api/aigateway_extras.go | 119 +
internal/api/aigateway_test.go | 8 +
internal/api/attachment.go | 22 +-
internal/api/auth.go | 6 +-
internal/api/authx.go | 24 +-
internal/api/console.go | 6 +-
internal/api/federation.go | 12 +-
internal/api/instance.go | 18 +-
internal/api/logevent.go | 12 +-
internal/api/network.go | 32 +-
internal/api/ociconfig.go | 18 +-
internal/api/overview.go | 4 +-
internal/api/proxy.go | 12 +-
internal/api/region.go | 10 +-
internal/api/routes_ai.go | 3 +
internal/api/settings.go | 22 +-
internal/api/subscription.go | 8 +-
internal/api/swagger_resp.go | 176 +
internal/api/systemlog.go | 3 +-
internal/api/task.go | 15 +-
internal/api/tenant.go | 36 +-
internal/api/webconsole.go | 2 +-
internal/api/webhook.go | 2 +-
internal/model/models.go | 2 +-
internal/oci/client.go | 6 +
internal/oci/genai.go | 5 +
internal/oci/genai_guard.go | 127 +
internal/oci/genai_responses.go | 6 +-
internal/oci/genai_speech.go | 44 +
internal/service/aigateway_extras.go | 248 ++
internal/service/aigateway_extras_test.go | 164 +
internal/service/aigateway_test.go | 20 +
internal/service/airesponses.go | 21 +-
internal/service/airesponses_test.go | 27 +-
50 files changed, 10699 insertions(+), 1371 deletions(-)
create mode 100644 docs/.swaggo
create mode 100644 docs/ai-gateway.md
create mode 100644 internal/aiwire/anyjson.go
create mode 100644 internal/aiwire/moderations.go
create mode 100644 internal/aiwire/rerank.go
create mode 100644 internal/api/aigateway_extras.go
create mode 100644 internal/api/swagger_resp.go
create mode 100644 internal/oci/genai_guard.go
create mode 100644 internal/oci/genai_speech.go
create mode 100644 internal/service/aigateway_extras.go
create mode 100644 internal/service/aigateway_extras_test.go
diff --git a/.trellis/spec/backend/index.md b/.trellis/spec/backend/index.md
index 9126d81..ec00321 100644
--- a/.trellis/spec/backend/index.md
+++ b/.trellis/spec/backend/index.md
@@ -1,6 +1,6 @@
# Backend Development Guidelines(oci-portal 后端规范)
-> Go 后端(`oci-portal/`)编码规范入口。规范提炼自 Google / Uber Go Style Guide、Effective Go 与 Go 官方模块布局指南,按本项目裁剪;条目与项目约定冲突时,以本 spec 为准。迁自 docs/开发指南.md 与根目录 AGENTS.md(2026-07)。
+> Go 后端(`oci-portal/`)编码规范入口。规范提炼自 Google / Uber Go Style Guide、Effective Go 与 Go 官方模块布局指南,按本项目裁剪;条目与项目约定冲突时,以本 spec 为准。
---
@@ -51,7 +51,7 @@ go mod tidy # 依赖有变更时
全部 HTTP 接口带 swaggo 注释(@Summary 中文/@Tags 按域/@Param/@Success/@Router;JWT 组接口标 @Security BearerAuth)。**新增或修改接口必须同步注释**,并重新生成 spec:
```bash
-go tool swag init -g cmd/server/main.go -o docs --parseInternal --parseDependency
+go tool swag init -g cmd/server/main.go -o docs --parseInternal --parseDependency --overridesFile docs/.swaggo
```
生成的 `docs/` 一并提交;UI 由 `SWAGGER=1` 开启(/swagger/index.html)。同名 handler 方法(list/create/get/update/remove)分布在多个 struct 上,写注释时确认 @Router 路径与该 receiver 的真实注册一致(routes_*.go)。
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 09e67fd..4bfba0a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,23 @@
# Changelog
-格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循语义化版本。
+格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)(版本段不记日期),版本号遵循语义化版本。
-## [0.3.1] - 2026-07-13
+## [0.4.0]
+
+### Added
+
+- 文本转语音端点 `POST /ai/v1/audio/speech`:OpenAI Audio Speech 兼容,直通 OCI 兼容面(模型 `xai.grok-tts`,voice 取 xAI Grok Voice 列表 `ara`/`eve`/`leo`/`rex`/`sal`);上游必填的 `language` 缺省时自动注入 `"auto"`,xAI 专属参数平铺透传;响应为一次性完整音频(Content-Type 透传上游,缺省 audio/mpeg),不提供流式
+- 文档重排端点 `POST /ai/v1/rerank`:Jina / Cohere 通行协议,走 OCI typed 面(`cohere.rerank-v4.0-pro` / `-fast`),支持 `top_n` 与 `return_documents`,`results[].index` 指向入参 `documents` 下标
+- 内容审核端点 `POST /ai/v1/moderations`:OpenAI moderations 外壳映射 OCI Guardrails(内容审核 / PII / 提示注入),`input` 为字符串或字符串数组(单次至多 8 条),categories 用 OCI 原生维度 `overall` / `blocklist` / `prompt_injection`(任一得分 ≥0.5 判 `flagged`),PII 命中放扩展字段 `results[].pii`(不参与 flagged;实测中文人名 / 手机号识别较弱,英文正常)
+- Responses 服务端工具扩展:放行 Oracle 文档化的 xAI `code_interpreter` 与远程 `mcp` 工具,并解除 `web_search` / `x_search` 仅非流式的限制——四类服务端工具非流式与流式均实测可用;`code_interpreter` 的命名容器管理与 File Search 不提供
+- 模型能力映射扩展:`TEXT_RERANK` → RERANK、`TEXT_TO_AUDIO` → TTS,渠道探测 / 同步自动发现重排与语音模型入池
+
+### Changed
+
+- AI 网关文档独立成篇 `docs/ai-gateway.md`(端点定位、兼容边界、已知上游限制、字段兼容矩阵——矩阵只列支持项,不支持 / 忽略项以文字简述),README 精简为概览并引用;实测披露:Responses `input_file` 内容块被上游以 ZDR 形态拒绝,能力不可用
+- swagger 全面修缺:135 处响应注解从泛型 map 改为具体类型(补文档用途响应结构与泛型列表外壳),AI 网关端点请求 / 响应 schema 完整可见;`json.RawMessage` 与联合类型统一渲染为任意 JSON 值(AnyJSON),不再误显示为 byte 数组;swag overrides 配置移至 `docs/.swaggo`,生成命令加 `--overridesFile docs/.swaggo`;顺带修正网页控制台会话创建响应码(200→201)与 SAML 元数据下载(改文件响应)两处注解失真
+
+## [0.3.1]
### Added
@@ -16,7 +31,7 @@
- AI 网关流式假成功:上游 error / `response.failed` 事件此前被吞掉,流提前 EOF 也被伪装成正常结束,调用日志呈现 200 · 0/0 且无错误信息;现 Messages 将上游失败转为 Anthropic `error` 事件,三个流式端点日志均记录上游错误消息或「上游流提前终止,未返回终态事件」
-## [0.3.0] - 2026-07-13
+## [0.3.0]
### Added
@@ -33,7 +48,7 @@
- **移除自定义审计告警规则**及其阈值、窗口和冷却匹配能力;`/api/v1/log-events/alert-rules` 与 `/api/v1/log-events/alert-rules/{ruleId}` 管理接口、`audit_alert` 通知模板不再提供,已有规则升级后不再执行
-## [0.2.0] - 2026-07-12
+## [0.2.0]
### Added
@@ -60,7 +75,7 @@
- 渠道「同步模型成功但探测报错不可用」:法兰克福等区域的微调基座模型占满探测候选导致的误报(探测状态与真实可用性不符的根因)
- 租户删除:告警命中清理改子查询,日志事件数万条时不再超出 SQL 绑定变量上限导致删除失败;无法解析的任务 payload 记警告跳过并保留原任务,不再永久阻断租户删除
-## [0.1.0] - 2026-07-10
+## [0.1.0]
### Added
@@ -88,7 +103,7 @@
- HTTP 入口加固:显式读写超时与优雅关闭、请求体上限(面板 1MB / AI 网关 10MB)、登录字段长度上限、登录守卫条目数有界
- 出错响应脱敏:内部错误只返回固定文案 + requestId,完整原因写服务端日志;GORM SQL 日志参数化输出,不再记录实参
-## [0.0.1] - 2026-07-09
+## [0.0.1]
首个版本:自托管 OCI 多租户管理面板后端。
diff --git a/DASH_VERSION b/DASH_VERSION
index 268b033..fb7a04c 100644
--- a/DASH_VERSION
+++ b/DASH_VERSION
@@ -1 +1 @@
-v0.3.0
+v0.4.0
diff --git a/README.md b/README.md
index 39e1149..cb3c81a 100644
--- a/README.md
+++ b/README.md
@@ -197,206 +197,20 @@ server {
## AI 网关
-AI 网关使用面板创建的独立密钥鉴权,支持 `Authorization: Bearer sk-...` 和 `x-api-key: sk-...`。密钥可绑定渠道分组和模型白名单;全局模型黑名单会从模型列表、路由和探测候选中同时排除目标模型。
+面板内置 OpenAI / Anthropic 兼容的 GenAI 网关:独立密钥鉴权(`Authorization: Bearer sk-...` 或 `x-api-key`),支持渠道分组、加权路由、熔断探测、模型黑白名单、内容日志与调用日志。
| 端点 | 定位 | 流式 |
| --- | --- | --- |
-| `POST /ai/v1/responses` | OpenAI Responses,无状态主接口 | SSE;服务端工具除外 |
-| `POST /ai/v1/chat/completions` | OpenAI Chat Completions,存量客户端兼容层 | SSE |
+| `POST /ai/v1/responses` | OpenAI Responses,无状态主接口(xAI 服务端工具 / MCP) | SSE |
+| `POST /ai/v1/chat/completions` | OpenAI Chat Completions 兼容层 | SSE |
| `POST /ai/v1/messages` | Anthropic Messages 转换层 | SSE |
| `POST /ai/v1/embeddings` | OpenAI Embeddings | 否 |
+| `POST /ai/v1/audio/speech` | 文本转语音(xAI Voice) | 否 |
+| `POST /ai/v1/rerank` | 文档重排(Cohere Rerank) | 否 |
+| `POST /ai/v1/moderations` | 内容审核(OCI Guardrails) | 否 |
| `GET /ai/v1/models` | 当前密钥可见的模型列表 | 否 |
-兼容边界:
-
-- 对话请求统一转发 OCI OpenAI 兼容面,当前供给以 `xai.`、`meta.`、`openai.` 前缀模型为主;Cohere Embeddings 不受该对话模型范围影响
-- 网关不保存会话历史,客户端需要携带完整上下文;Responses 拒绝非空 `previous_response_id`、非 `null` `conversation` 和 `background:true`
-- Responses 支持 xAI Grok `web_search` / `x_search` 服务端工具,但仅限非流式请求
-- Responses 的 `reasoning.effort`、Messages 的 `output_config.effort` 和 Chat Completions 的 `reasoning_effort` 会传给上游,实际档位和效果由模型决定
-- Chat Completions 只承担协议转换与兼容修复;新能力优先在 Responses 和 Messages 提供
-- 单次请求最多尝试三个渠道;可重试错误会切换渠道,流式响应建立后不会换渠道重试
-
-### 已知上游限制:大 system 区流式断流
-
-实测(2026-07-13)OCI 兼容面对 `instructions` 与 `tools` 合计超约 64.5KB 的**流式**请求会在发出少量事件后静默断开连接(无任何错误事件;同请求非流式正常),与模型、字符集、消息正文大小均无关——消息正文(`input`)不计入该限制。Chat Completions 与 Messages 的 system/developer 提示会转换为 `instructions`,因此 Claude Code 等自带大体量系统提示与工具定义的客户端极易触发。
-
-网关侧应对:
-
-- Messages 与 Chat Completions 的流式请求在客户端尚未收到任何输出时遭遇上游断流,会自动降级为非流式重做,并按标准事件/chunk 序列一次推送;调用日志记 `retries=1` 与降级标记
-- Responses 直通因初始事件已转发、协议上无法透明降级,调用日志记「上游流提前终止」,客户端需自行回退非流式
-- 应急规避:将超长 system 内容移入首条 user 消息正文可绕过该限制(正文不计入),但语义有别,根治有待上游修复
-
-这里提供的是兼容接口而非 OpenAI / Anthropic 协议的完整实现。OCI OpenAI 兼容面的部分行为来自实测,未见 Oracle 文档承诺,可能随上游调整。路由与鉴权定义以 [Swagger YAML](docs/swagger.yaml) 或运行时 Swagger UI 为准;无法由 OpenAPI 完整表达的兼容边界列于上方。
-
-### 字段兼容矩阵
-
-以下矩阵以 2026-07-13 的 [OpenAI Responses](https://developers.openai.com/api/reference/resources/responses/methods/create)、[Chat Completions](https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create)、[Embeddings](https://developers.openai.com/api/reference/resources/embeddings/methods/create) 和 [Anthropic Messages](https://platform.claude.com/docs/en/api/messages/create) 为标准基线,并与当前实现逐项核对。
-
-这是一份兼容性快照,不替代 Swagger。标准接口和 OCI 上游都可能变化,最终行为以当前版本代码与实测为准。
-
-| 标记 | 含义 |
-| :---: | --- |
-| ✅ | 网关直接支持 |
-| ➡️ | 网关原样透传;是否生效由 OCI 上游决定 |
-| 🔄 | 网关进行字段或协议转换后支持 |
-| ◐ | 部分支持、存在前置条件或语义降级 |
-| ⚠️ | 请求可被接受,但字段会被忽略 |
-| ❌ | 网关在请求到达上游前拒绝 |
-
-
-POST /ai/v1/responses 对比 OpenAI Responses
-
-Responses 是“原始 JSON 直通 + 本地门禁”。除 `store` 外,网关不会重建请求体;未知顶层字段也会保留并送往 OCI。
-
-| 标准字段 | 状态 | 网关行为 |
-| --- | :---: | --- |
-| `model` | ◐ | 必须非空,还要通过密钥模型白名单并匹配可用渠道;随后原样透传 |
-| `input` | ➡️ | 支持标准的字符串或 item 数组,原始内容透传;网关不逐项保证 OCI 能处理所有 item 类型 |
-| `instructions`、`max_output_tokens` | ➡️ | 类型可解析后原样透传,不做范围或模型能力校验 |
-| `temperature`、`top_p`、`parallel_tool_calls` | ➡️ | 原样透传,不做取值范围校验 |
-| `text` / `text.format` / `text.verbosity` | ➡️ | 整个原始对象透传;结构化输出是否可用由 OCI 模型决定 |
-| `reasoning` | ➡️ | 整个原始对象透传;`effort` 不校验档位,`summary` 等字段不会被网关删除 |
-| `tool_choice` | ➡️ | 任意 JSON 原样透传,本地不校验枚举或结构 |
-| `context_management`、`include`、`max_tool_calls`、`metadata`、`moderation`、`prompt` | ➡️ | 网关未建模但会保留在原始请求中,由 OCI 决定是否接受 |
-| `prompt_cache_key`、`prompt_cache_retention`、`safety_identifier`、`service_tier` | ➡️ | 原样透传,不代表 OCI 一定实现 OpenAI 的对应语义 |
-| `stream_options`、`top_logprobs`、`truncation`、`user` | ➡️ | 原样透传,不做本地语义校验 |
-| `store` | 🔄 | 无论客户端传什么,上游请求都强制改写为 `false` |
-| `previous_response_id` | ❌ | 非空即返回 400;网关不保存历史响应 |
-| `conversation` | ◐ | 省略或 `null` 可通过;任何非 `null` 值返回 400 |
-| `background` | ◐ | `true` 返回 400;`false`、`null` 或省略时继续透传 |
-| `stream` | ◐ | 普通请求和 `function` 工具支持 SSE;含 `web_search` / `x_search` 时拒绝流式 |
-| `tools[].type=function` | ➡️ | 非流式和流式均可,工具对象原样透传 |
-| `tools[].type=web_search` / `x_search` | ◐ | 使用 xAI 服务端工具语义且仅支持非流式;`x_search` 不是 OpenAI 标准工具 |
-| 其他标准工具类型 | ❌ | `web_search_preview`、`file_search`、`computer`、`code_interpreter`、`image_generation`、`mcp`、`shell`、`custom` 等返回 400 |
-| 其他未知顶层字段 | ➡️ | 只要整个请求是合法 JSON,字段名、结构和数值都会保留 |
-
-响应边界:
-
-- 非流式成功响应不做转换,OCI JSON 原样返回;usage 解析只用于面板调用日志
-- SSE 事件逐行原样转发,不补 `data: [DONE]`,推理增量也不会被网关过滤
-- 流建立前最多切换三个渠道;流建立后中断不重试,客户端可能只收到部分事件
-- 未知模型返回 404、无渠道返回 503;上游错误会套入 OpenAI 风格错误体,不保证与标准 OpenAI 错误字段完全相同
-
-实现依据:[`airesponses.go`](internal/service/airesponses.go) · [`responses.go`](internal/aiwire/responses.go) · [`aigateway.go`](internal/api/aigateway.go)
-
-
-
-
-POST /ai/v1/chat/completions 对比 OpenAI Chat Completions
-
-Chat Completions 会先转换为 Responses 请求,再把 OCI Responses 响应桥接回 Chat Completions 形态。
-
-| 标准字段 | 状态 | 网关行为 |
-| --- | :---: | --- |
-| `model` | ◐ | 必填,受密钥白名单和可用渠道限制;模型名保留到上游请求 |
-| `messages` | 🔄 | 必填并转换为 Responses `input` / `instructions` |
-| `system` / `developer` 消息 | ◐ | 文本按出现顺序合并为 `instructions`;块数组中的非文本内容被忽略 |
-| `user` / `assistant` 文本内容 | 🔄 | 字符串及 `text` 块分别转为 `input_text` / `output_text` |
-| `image_url` 内容块 | ◐ | URL 或 data URI 转为 `input_image`;`image_url.detail` 被忽略 |
-| `input_audio`、`file`、`refusal` 等内容块 | ❌ | 当前消息转换器不支持,返回 400 |
-| assistant `tool_calls` / `role=tool` | 🔄 | 转为 `function_call` / `function_call_output`,保留调用 ID、函数名和参数 |
-| 消息 `name`、`refusal`、`audio`、旧式 `function_call` | ⚠️ | 当前消息结构未建模,静默忽略 |
-| `max_completion_tokens` | 🔄 | 转为 `max_output_tokens`,优先于 `max_tokens` |
-| `max_tokens` | 🔄 | 未提供 `max_completion_tokens` 时转为 `max_output_tokens` |
-| `temperature`、`top_p`、`parallel_tool_calls` | ◐ | 原值写入 Responses 请求,但不校验范围或模型能力 |
-| `stream` | 🔄 | OCI Responses SSE 桥接为 `chat.completion.chunk`,末尾补 `data: [DONE]`;上游断流且尚无输出时自动降级非流式重做,结果按 chunk 序列一次推送 |
-| `stream_options.include_usage` | 🔄 | 控制网关在终块后追加 `choices: []` 的 usage 块 |
-| `stream_options.include_obfuscation` | ⚠️ | 未建模,静默忽略 |
-| `tools[].type=function` | ◐ | `name`、`description`、`parameters` 支持;`function.strict` 被忽略 |
-| `tools[].type=custom` 及其他工具 | ❌ | 只接受 `function`,其他类型返回 400 |
-| `tool_choice` | ◐ | 支持 `auto` / `none` / `required` 和具名 function;非法或未知值被静默忽略 |
-| `response_format` | ◐ | `json_object`、`json_schema` 转为 Responses `text.format`;未知类型交给 OCI 处理 |
-| `reasoning_effort` | ◐ | 转小写后映射为 `reasoning.effort`,不校验模型或档位 |
-| `store` | ⚠️ / 🔄 | 客户端字段被忽略,转换后的上游请求始终使用 `store:false` |
-| `stop`、`seed`、`n`、`frequency_penalty`、`presence_penalty` | ⚠️ | 静默忽略;`n` 因此恒为单个 choice |
-| `logprobs`、`top_logprobs`、`logit_bias`、`user` | ⚠️ | 静默忽略 |
-| `audio`、`modalities`、`prediction`、`metadata`、`moderation` | ⚠️ | 静默忽略 |
-| `prompt_cache_key`、`safety_identifier`、`service_tier`、`verbosity`、`web_search_options` | ⚠️ | 静默忽略 |
-| 其他未知字段 | ⚠️ | JSON 解码器不会拒绝未知字段,但转换后的上游请求不包含它们 |
-
-响应边界:
-
-- 非流式固定生成一个 `choices[0]`;文本会合并,函数调用转为 `tool_calls`
-- `finish_reason` 只生成 `stop`、`tool_calls`、`length`;其他上游终止原因不保留
-- reasoning 输出、logprobs、refusal、annotations、audio、service tier 和 system fingerprint 不返回
-- usage 保留 `prompt_tokens`、`completion_tokens`、`total_tokens` 和 `prompt_tokens_details.cached_tokens`
-- 已建立的流中断或上游 `response.failed` 不会转换成标准 SSE 错误事件
-
-实现依据:[`chatresponses.go`](internal/service/chatresponses.go) · [`openai.go`](internal/aiwire/openai.go) · [`aigateway.go`](internal/api/aigateway.go)
-
-
-
-
-POST /ai/v1/embeddings 对比 OpenAI Embeddings
-
-| 标准字段 | 状态 | 网关行为 |
-| --- | :---: | --- |
-| `model` | ◐ | 必填,受密钥白名单限制,并且必须存在具有 `EMBEDDING` 能力的渠道 |
-| `input` 为字符串 | ✅ | 包装为单个输入后调用 OCI |
-| `input` 为字符串数组 | ✅ | 按原顺序调用 OCI |
-| `input` 为 token ID 数组或二维 token ID 数组 | ❌ | 只能解码字符串或字符串数组,绑定阶段返回 400 |
-| 空数组 / `null` | ❌ | 本地返回 400;空字符串不在本地拒绝,由 OCI 决定 |
-| `dimensions` | ◐ | 映射为 OCI 输出维度,不做范围或模型能力校验 |
-| `encoding_format=float` | ✅ | 返回 float 数组;省略时行为相同 |
-| `encoding_format=base64` | ❌ | 本地返回 400,不提供 base64 响应 |
-| `user` | ⚠️ | 能解析但不会传给 OCI |
-| 其他未知字段 | ⚠️ | 静默忽略 |
-
-响应使用标准的 `object:"list"`、`data[].object:"embedding"`、`index`、`model` 和可选 `usage` 外壳;向量为 `float32` 数组,不支持流式。
-
-实现依据:[`embeddings.go`](internal/aiwire/embeddings.go) · [`aigateway_chat.go`](internal/service/aigateway_chat.go) · [`aigateway.go`](internal/api/aigateway.go)
-
-
-
-
-POST /ai/v1/messages 对比 Anthropic Messages
-
-网关接受 `Authorization: Bearer` 或 `x-api-key`,但不会校验或使用标准 Anthropic `anthropic-version`、`anthropic-beta` 请求头。
-
-| 标准字段 | 状态 | 网关行为 |
-| --- | :---: | --- |
-| `model` | ◐ | 用于模型与渠道选择,但空字符串不会在 handler 中按参数错误拒绝,通常最终返回模型不存在 |
-| `max_tokens` | 🔄 | 可缺省(缺省或 ≤0 时按默认值 8192),转换为 `max_output_tokens` |
-| `messages` | ◐ | 必须非空;角色、交替顺序和空内容不做完整校验 |
-| `system` | ◐ | 支持字符串或 text 块数组;多个文本块直接拼接,`cache_control` 等附加字段被忽略 |
-| `temperature`、`top_p` | ◐ | 写入 Responses 请求,不做取值范围或模型能力校验 |
-| `top_k` | ⚠️ | 能解析但不会传给上游 |
-| `stop_sequences` | ⚠️ | 能解析但不会传给上游;响应 `stop_sequence` 恒为 `null` |
-| `stream` | 🔄 | Responses SSE 桥接为 Anthropic 事件序列;上游断流且尚无输出时自动降级非流式重做,结果按事件序列一次推送 |
-| `tools` | ◐ | 每个工具都转换成 Responses `function`;自定义客户端工具可用,Anthropic 服务端工具类型不保留原语义 |
-| `tool_choice` | ◐ | 支持 `auto`、`any`、`none`、具名 `tool`;`disable_parallel_tool_use` 等附加字段被忽略 |
-| `metadata` | ⚠️ | 能解析但不会传给上游 |
-| `thinking` | ⚠️ | 顶层 thinking 配置不会控制上游思考预算 |
-| `output_config.effort` | 🔄 | 转小写后映射为 Responses `reasoning.effort` |
-| `output_config` 其他子字段 | ⚠️ | 未建模,静默忽略 |
-| `cache_control`、`container`、`inference_geo`、`service_tier` | ⚠️ | 标准 SDK 中存在,但当前请求结构未建模,静默忽略 |
-| 其他未知顶层字段 | ⚠️ | JSON 解码器接受,但转换后的上游请求不包含它们 |
-
-`messages[].content`:
-
-| 标准内容块 | 状态 | 网关行为 |
-| --- | :---: | --- |
-| 字符串 / `text` | 🔄 | user 转 `input_text`,assistant 历史转 `output_text` |
-| `image` | ◐ | 仅支持 `base64` 和 `url` source;缺字段或其他 source 类型返回 400 |
-| `tool_use` | 🔄 | 转为 `function_call`,保留 ID、名称和输入 |
-| `tool_result` | ◐ | 转为 `function_call_output`;块数组只拼接 text,`is_error` 和非文本结果丢失 |
-| `thinking` / `redacted_thinking` | ⚠️ | 历史思考块被删除,不进入上游上下文 |
-| `document`、服务端工具结果及其他未知块 | ❌ | 返回 400 |
-| `null` / 空块数组 | ◐ | 该消息可能从上游 input 中消失,不返回参数错误 |
-
-响应边界:
-
-- 非流式只把 Responses `output_text` 转成 `text`、`function_call` 转成 `tool_use`
-- `stop_reason` 只生成 `end_turn`、`tool_use`、`max_tokens`;`stop_sequence` 恒为 `null`
-- reasoning 不会生成 Anthropic `thinking` / `redacted_thinking` 块,也没有 signature
-- usage 只保留 `input_tokens`、`output_tokens` 和 `cache_read_input_tokens`,不提供 `cache_creation_input_tokens`
-- 流式输出标准事件骨架,但不生成 `thinking_delta` 和 `signature_delta`;上游错误事件与无终态断流会转成 Anthropic `error` 事件
-
-实现依据:[`anthresponses.go`](internal/service/anthresponses.go) · [`anthropic.go`](internal/aiwire/anthropic.go) · [`aigateway.go`](internal/api/aigateway.go)
-
-
-
-`GET /ai/v1/models` 使用 OpenAI Models 列表外壳(`object`、`data[].id/object/created/owned_by`),但只返回当前渠道目录中通过分组、全局黑名单和密钥白名单筛选后的模型;网关不提供标准的单模型检索端点。
+协议兼容边界、已知上游限制与逐字段兼容矩阵见 **[AI 网关文档](docs/ai-gateway.md)**。
## API 与配置
@@ -446,7 +260,7 @@ go vet ./...
go test ./...
# Handler 注释变更后重新生成唯一的对外 API 文档。
-go tool swag init -g cmd/server/main.go -o docs --parseInternal --parseDependency
+go tool swag init -g cmd/server/main.go -o docs --parseInternal --parseDependency --overridesFile docs/.swaggo
```
- Go 后端规范与目录约定:[`AGENTS.md`](AGENTS.md) · [`.trellis/spec/backend/`](.trellis/spec/backend/)
diff --git a/docs/.swaggo b/docs/.swaggo
new file mode 100644
index 0000000..acabe31
--- /dev/null
+++ b/docs/.swaggo
@@ -0,0 +1,6 @@
+// swag 全局类型替换:原始 JSON 与联合类型统一渲染为 AnyJSON(任意 JSON 值),
+// 避免 json.RawMessage 被误渲染成 byte 数组、联合类型暴露内部字段。
+replace encoding/json.RawMessage oci-portal/internal/aiwire.AnyJSON
+replace oci-portal/internal/aiwire.RespInput oci-portal/internal/aiwire.AnyJSON
+replace oci-portal/internal/aiwire.Content oci-portal/internal/aiwire.AnyJSON
+replace oci-portal/internal/aiwire.StringList oci-portal/internal/aiwire.AnyJSON
diff --git a/docs/ai-gateway.md b/docs/ai-gateway.md
new file mode 100644
index 0000000..4456357
--- /dev/null
+++ b/docs/ai-gateway.md
@@ -0,0 +1,266 @@
+# AI 网关
+
+> 本文是 OCI Portal AI 网关的完整使用与兼容性文档:端点定位、协议兼容边界、已知上游限制与字段兼容矩阵。
+> 路由与鉴权的机器可读定义以 [Swagger YAML](swagger.yaml) 或运行时 Swagger UI 为准;无法由 OpenAPI 表达的兼容边界以本文为准。
+
+AI 网关使用面板创建的独立密钥鉴权,支持 `Authorization: Bearer sk-...` 和 `x-api-key: sk-...`。密钥可绑定渠道分组和模型白名单;全局模型黑名单会从模型列表、路由和探测候选中同时排除目标模型。
+
+| 端点 | 定位 | 流式 |
+| --- | --- | --- |
+| `POST /ai/v1/responses` | OpenAI Responses,无状态主接口 | SSE |
+| `POST /ai/v1/chat/completions` | OpenAI Chat Completions,存量客户端兼容层 | SSE |
+| `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/rerank` | 文档重排(Cohere Rerank,Jina 风格协议) | 否 |
+| `POST /ai/v1/moderations` | 内容审核(OCI Guardrails:内容审核 / PII / 提示注入) | 否 |
+| `GET /ai/v1/models` | 当前密钥可见的模型列表 | 否 |
+
+兼容边界:
+
+- 对话请求统一转发 OCI OpenAI 兼容面,当前供给以 `xai.`、`meta.`、`openai.` 前缀模型为主;Cohere Embeddings 不受该对话模型范围影响
+- 网关不保存会话历史,客户端需要携带完整上下文;Responses 拒绝非空 `previous_response_id`、非 `null` `conversation` 和 `background:true`
+- Responses 支持 Oracle 文档化的 xAI 服务端工具 `web_search` / `x_search` / `code_interpreter` 与远程 `mcp` 工具(非流式与流式均可),工具参数与限制遵循 [xAI 规格](https://docs.oracle.com/en-us/iaas/Content/generative-ai/get-started-agents.htm#xai-compatible-tools);`code_interpreter` 的命名容器管理(containers API)与 File Search 不提供
+- Responses 的 `reasoning.effort`、Messages 的 `output_config.effort` 和 Chat Completions 的 `reasoning_effort` 会传给上游,实际档位和效果由模型决定
+- 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 流式
+- 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 形态,该能力在上游侧不可用
+
+### 已知上游限制:大 system 区流式断流
+
+实测(2026-07-13)OCI 兼容面对 `instructions` 与 `tools` 合计超约 64.5KB 的**流式**请求会在发出少量事件后静默断开连接(无任何错误事件;同请求非流式正常),与模型、字符集、消息正文大小均无关——消息正文(`input`)不计入该限制。Chat Completions 与 Messages 的 system/developer 提示会转换为 `instructions`,因此 Claude Code 等自带大体量系统提示与工具定义的客户端极易触发。
+
+网关侧应对:
+
+- Messages 与 Chat Completions 的流式请求在客户端尚未收到任何输出时遭遇上游断流,会自动降级为非流式重做,并按标准事件/chunk 序列一次推送;调用日志记 `retries=1` 与降级标记
+- Responses 直通因初始事件已转发、协议上无法透明降级,调用日志记「上游流提前终止」,客户端需自行回退非流式
+- 应急规避:将超长 system 内容移入首条 user 消息正文可绕过该限制(正文不计入),但语义有别,根治有待上游修复
+
+这里提供的是兼容接口而非 OpenAI / Anthropic 协议的完整实现。OCI OpenAI 兼容面的部分行为来自实测,未见 Oracle 文档承诺,可能随上游调整。路由与鉴权定义以 [Swagger YAML](swagger.yaml) 或运行时 Swagger UI 为准;无法由 OpenAPI 完整表达的兼容边界列于上方。
+
+### 字段兼容矩阵
+
+以下矩阵以 2026-07-13 的 [OpenAI Responses](https://developers.openai.com/api/reference/resources/responses/methods/create)、[Chat Completions](https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create)、[Embeddings](https://developers.openai.com/api/reference/resources/embeddings/methods/create)、[Audio Speech](https://developers.openai.com/api/reference/resources/audio/methods/speech)、[Moderations](https://developers.openai.com/api/reference/resources/moderations/methods/create) 和 [Anthropic Messages](https://platform.claude.com/docs/en/api/messages/create) 为标准基线,并与当前实现逐项核对;Rerank 无 OpenAI 对应端点,基线取 [Cohere Rerank](https://docs.cohere.com/reference/rerank) 协议。
+
+这是一份兼容性快照,不替代 Swagger。标准接口和 OCI 上游都可能变化,最终行为以当前版本代码与实测为准。
+
+矩阵只列网关支持的字段;不支持(本地拒绝)与被忽略的字段不入表,在各端点段落末尾以文字简述。
+
+| 标记 | 含义 |
+| :---: | --- |
+| ✅ | 网关直接支持 |
+| ➡️ | 网关原样透传;是否生效由 OCI 上游决定 |
+| 🔄 | 网关进行字段或协议转换后支持 |
+| ◐ | 部分支持、存在前置条件或语义降级 |
+
+
+POST /ai/v1/responses 对比 OpenAI Responses
+
+Responses 是“原始 JSON 直通 + 本地门禁”。除 `store` 外,网关不会重建请求体;未知顶层字段也会保留并送往 OCI。
+
+| 标准字段 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| `model` | ◐ | 必须非空,还要通过密钥模型白名单并匹配可用渠道;随后原样透传 |
+| `input` | ➡️ | 支持标准的字符串或 item 数组,原始内容透传;网关不逐项保证 OCI 能处理所有 item 类型 |
+| `instructions`、`max_output_tokens` | ➡️ | 类型可解析后原样透传,不做范围或模型能力校验 |
+| `temperature`、`top_p`、`parallel_tool_calls` | ➡️ | 原样透传,不做取值范围校验 |
+| `text` / `text.format` / `text.verbosity` | ➡️ | 整个原始对象透传;结构化输出是否可用由 OCI 模型决定 |
+| `reasoning` | ➡️ | 整个原始对象透传;`effort` 不校验档位,`summary` 等字段不会被网关删除 |
+| `tool_choice` | ➡️ | 任意 JSON 原样透传,本地不校验枚举或结构 |
+| `store` | 🔄 | 无论客户端传什么,上游请求都强制改写为 `false` |
+| `stream` | ✅ | 普通请求、`function` 与服务端工具均支持 SSE |
+| `tools[].type=function` | ➡️ | 非流式和流式均可,工具对象原样透传 |
+| `tools[].type=web_search` / `x_search` / `code_interpreter` | ◐ | Oracle 文档化的 xAI 服务端工具,参数与限制遵循 xAI 规格(如 `allowed_domains` 上限 10、`container` 支持 `{"type":"auto"}`),非流式与流式均实测可用;`x_search` 不是 OpenAI 标准工具 |
+| `tools[].type=mcp` | ➡️ | 远程 MCP 服务由上游直连调用(`server_url` / `require_approval` / `authorization` 等原样透传),非流式与流式均实测可用 |
+| 其余标准与未知顶层字段 | ➡️ | `context_management`、`include`、`metadata`、`prompt`、`prompt_cache_key`、`service_tier`、`truncation`、`user` 等未建模字段一律保留在原始请求中,由 OCI 决定是否接受 |
+
+不支持(请求到达上游前返回 400):非空 `previous_response_id`、非 `null` 的 `conversation`、`background:true`——网关无状态,不保存历史响应;以及 `function` / xAI 服务端工具 / `mcp` 之外的工具类型(`web_search_preview`、`file_search`、`computer`、`image_generation`、`shell`、`custom` 等)。
+
+响应边界:
+
+- 非流式成功响应不做转换,OCI JSON 原样返回;usage 解析只用于面板调用日志
+- SSE 事件逐行原样转发,不补 `data: [DONE]`,推理增量也不会被网关过滤
+- 流建立前最多切换三个渠道;流建立后中断不重试,客户端可能只收到部分事件
+- 未知模型返回 404、无渠道返回 503;上游错误会套入 OpenAI 风格错误体,不保证与标准 OpenAI 错误字段完全相同
+
+实现依据:[`airesponses.go`](../internal/service/airesponses.go) · [`responses.go`](../internal/aiwire/responses.go) · [`aigateway.go`](../internal/api/aigateway.go)
+
+
+
+
+POST /ai/v1/chat/completions 对比 OpenAI Chat Completions
+
+Chat Completions 会先转换为 Responses 请求,再把 OCI Responses 响应桥接回 Chat Completions 形态。转换器只搬运下表字段,其余字段不进入上游请求。
+
+| 标准字段 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| `model` | ◐ | 必填,受密钥白名单和可用渠道限制;模型名保留到上游请求 |
+| `messages` | 🔄 | 必填并转换为 Responses `input` / `instructions` |
+| `system` / `developer` 消息 | ◐ | 文本按出现顺序合并为 `instructions`;块数组中的非文本内容被忽略 |
+| `user` / `assistant` 文本内容 | 🔄 | 字符串及 `text` 块分别转为 `input_text` / `output_text` |
+| `image_url` 内容块 | ◐ | URL 或 data URI 转为 `input_image`;`image_url.detail` 被忽略 |
+| assistant `tool_calls` / `role=tool` | 🔄 | 转为 `function_call` / `function_call_output`,保留调用 ID、函数名和参数 |
+| `max_completion_tokens` | 🔄 | 转为 `max_output_tokens`,优先于 `max_tokens` |
+| `max_tokens` | 🔄 | 未提供 `max_completion_tokens` 时转为 `max_output_tokens` |
+| `temperature`、`top_p`、`parallel_tool_calls` | ◐ | 原值写入 Responses 请求,但不校验范围或模型能力 |
+| `stream` | 🔄 | OCI Responses SSE 桥接为 `chat.completion.chunk`,末尾补 `data: [DONE]`;上游断流且尚无输出时自动降级非流式重做,结果按 chunk 序列一次推送 |
+| `stream_options.include_usage` | 🔄 | 控制网关在终块后追加 `choices: []` 的 usage 块 |
+| `tools[].type=function` | ◐ | `name`、`description`、`parameters` 支持;`function.strict` 被忽略 |
+| `tool_choice` | ◐ | 支持 `auto` / `none` / `required` 和具名 function;非法或未知值被静默忽略 |
+| `response_format` | ◐ | `json_object`、`json_schema` 转为 Responses `text.format`;未知类型交给 OCI 处理 |
+| `reasoning_effort` | ◐ | 转小写后映射为 `reasoning.effort`,不校验模型或档位 |
+| `store` | 🔄 | 客户端取值被忽略,转换后的上游请求始终使用 `store:false` |
+
+不支持(返回 400):`input_audio`、`file`、`refusal` 等消息内容块;`function` 以外的工具类型(含 `custom`)。
+
+静默忽略(转换后的上游请求不包含):消息级 `name` / `refusal` / `audio` / 旧式 `function_call`;采样与输出控制类 `stop`、`seed`、`n`(恒返回单个 choice)、`frequency_penalty`、`presence_penalty`、`logprobs`、`top_logprobs`、`logit_bias`;平台类 `user`、`audio`、`modalities`、`prediction`、`metadata`、`moderation`、`prompt_cache_key`、`safety_identifier`、`service_tier`、`verbosity`、`web_search_options`、`stream_options.include_obfuscation` 及其他未知字段。
+
+响应边界:
+
+- 非流式固定生成一个 `choices[0]`;文本会合并,函数调用转为 `tool_calls`
+- `finish_reason` 只生成 `stop`、`tool_calls`、`length`;其他上游终止原因不保留
+- reasoning 输出、logprobs、refusal、annotations、audio、service tier 和 system fingerprint 不返回
+- usage 保留 `prompt_tokens`、`completion_tokens`、`total_tokens` 和 `prompt_tokens_details.cached_tokens`
+- 已建立的流中断或上游 `response.failed` 不会转换成标准 SSE 错误事件
+
+实现依据:[`chatresponses.go`](../internal/service/chatresponses.go) · [`openai.go`](../internal/aiwire/openai.go) · [`aigateway.go`](../internal/api/aigateway.go)
+
+
+
+
+POST /ai/v1/embeddings 对比 OpenAI Embeddings
+
+| 标准字段 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| `model` | ◐ | 必填,受密钥白名单限制,并且必须存在具有 `EMBEDDING` 能力的渠道 |
+| `input` 为字符串 | ✅ | 包装为单个输入后调用 OCI |
+| `input` 为字符串数组 | ✅ | 按原顺序调用 OCI;空字符串不在本地拒绝,由 OCI 决定 |
+| `dimensions` | ◐ | 映射为 OCI 输出维度,不做范围或模型能力校验 |
+| `encoding_format=float` | ✅ | 返回 float 数组;省略时行为相同 |
+
+不支持(返回 400):token ID 数组(一维或二维)形态的 `input`、空数组、`null`,以及 `encoding_format=base64`。静默忽略:`user` 及其他未知字段。
+
+响应使用标准的 `object:"list"`、`data[].object:"embedding"`、`index`、`model` 和可选 `usage` 外壳;向量为 `float32` 数组,不支持流式。
+
+实现依据:[`embeddings.go`](../internal/aiwire/embeddings.go) · [`aigateway_chat.go`](../internal/service/aigateway_chat.go) · [`aigateway.go`](../internal/api/aigateway.go)
+
+
+
+
+POST /ai/v1/messages 对比 Anthropic Messages
+
+网关接受 `Authorization: Bearer` 或 `x-api-key`,但不会校验或使用标准 Anthropic `anthropic-version`、`anthropic-beta` 请求头。
+
+| 标准字段 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| `model` | ◐ | 用于模型与渠道选择,但空字符串不会在 handler 中按参数错误拒绝,通常最终返回模型不存在 |
+| `max_tokens` | 🔄 | 可缺省(缺省或 ≤0 时按默认值 8192),转换为 `max_output_tokens` |
+| `messages` | ◐ | 必须非空;角色、交替顺序和空内容不做完整校验 |
+| `system` | ◐ | 支持字符串或 text 块数组;多个文本块直接拼接,`cache_control` 等附加字段被忽略 |
+| `temperature`、`top_p` | ◐ | 写入 Responses 请求,不做取值范围或模型能力校验 |
+| `stream` | 🔄 | Responses SSE 桥接为 Anthropic 事件序列;上游断流且尚无输出时自动降级非流式重做,结果按事件序列一次推送 |
+| `tools` | ◐ | 每个工具都转换成 Responses `function`;自定义客户端工具可用,Anthropic 服务端工具类型不保留原语义 |
+| `tool_choice` | ◐ | 支持 `auto`、`any`、`none`、具名 `tool`;`disable_parallel_tool_use` 等附加字段被忽略 |
+| `output_config.effort` | 🔄 | 转小写后映射为 Responses `reasoning.effort` |
+
+顶层静默忽略(能解析但不传上游):`top_k`、`stop_sequences`(响应 `stop_sequence` 恒为 `null`)、`metadata`、`thinking`(不控制上游思考预算)、`output_config` 其余子字段、`cache_control`、`container`、`inference_geo`、`service_tier` 及其他未知顶层字段。
+
+`messages[].content`:
+
+| 标准内容块 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| 字符串 / `text` | 🔄 | user 转 `input_text`,assistant 历史转 `output_text` |
+| `image` | ◐ | 仅支持 `base64` 和 `url` source;缺字段或其他 source 类型返回 400 |
+| `tool_use` | 🔄 | 转为 `function_call`,保留 ID、名称和输入 |
+| `tool_result` | ◐ | 转为 `function_call_output`;块数组只拼接 text,`is_error` 和非文本结果丢失 |
+| `null` / 空块数组 | ◐ | 该消息可能从上游 input 中消失,不返回参数错误 |
+
+不支持的内容块(返回 400):`document`、服务端工具结果及其他未知块。历史 `thinking` / `redacted_thinking` 块会被删除,不进入上游上下文。
+
+响应边界:
+
+- 非流式只把 Responses `output_text` 转成 `text`、`function_call` 转成 `tool_use`
+- `stop_reason` 只生成 `end_turn`、`tool_use`、`max_tokens`;`stop_sequence` 恒为 `null`
+- reasoning 不会生成 Anthropic `thinking` / `redacted_thinking` 块,也没有 signature
+- usage 只保留 `input_tokens`、`output_tokens` 和 `cache_read_input_tokens`,不提供 `cache_creation_input_tokens`
+- 流式输出标准事件骨架,但不生成 `thinking_delta` 和 `signature_delta`;上游错误事件与无终态断流会转成 Anthropic `error` 事件
+
+实现依据:[`anthresponses.go`](../internal/service/anthresponses.go) · [`anthropic.go`](../internal/aiwire/anthropic.go) · [`aigateway.go`](../internal/api/aigateway.go)
+
+
+
+
+POST /ai/v1/audio/speech 对比 OpenAI Audio Speech
+
+Audio Speech 与 Responses 同为“原始 JSON 直通 + 本地门禁”:除缺省注入 `language` 外不重建请求体,未知字段原样透传。
+
+| 标准字段 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| `model` | ◐ | 必填,受密钥白名单限制,并且必须存在具有 `TTS` 能力的渠道(当前上游仅 `xai.grok-tts`) |
+| `input` | ◐ | 必填非空,随后原样透传 |
+| `voice` | ➡️ | 原样透传;取 xAI Grok Voice 音色(`ara` / `eve` / `leo` / `rex` / `sal`),OpenAI 标准音色名不可用 |
+| `response_format` | ➡️ | 原样透传;实测 `mp3` 可用,其余格式由上游决定 |
+| `language`(扩展字段) | 🔄 | 上游必填;客户端缺省时网关自动注入 `"auto"` |
+| `speed`、`instructions` 及其他未知字段 | ➡️ | 原样透传(含 xAI 专属参数如 `output_format`),是否生效由上游决定 |
+
+不支持:流式音频(`stream_format` 等流式选项无效,响应恒为一次性完整音频)与 WebSocket 语音会话。
+
+响应边界:
+
+- 成功响应为音频字节,`Content-Type` 透传上游(缺省 `audio/mpeg`)
+- 无 token 用量口径,调用日志只记时延与渠道
+
+实现依据:[`genai_speech.go`](../internal/oci/genai_speech.go) · [`service/aigateway_extras.go`](../internal/service/aigateway_extras.go) · [`api/aigateway_extras.go`](../internal/api/aigateway_extras.go)
+
+
+
+
+POST /ai/v1/rerank 对比 Cohere Rerank
+
+Rerank 无 OpenAI 对应端点,协议取 Jina / Cohere 通行风格,上游走 OCI typed 面(`cohere.rerank-v4.0-pro` / `-fast`)。
+
+| 字段 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| `model` | ◐ | 必填,受密钥白名单限制,并且必须存在具有 `RERANK` 能力的渠道 |
+| `query` | ✅ | 必填非空 |
+| `documents` | ◐ | 必填,仅接受字符串数组;Cohere 旧版 `{"text": ...}` 对象数组形态返回 400 |
+| `top_n` | ✅ | 可选,传给上游限制返回条数;缺省返回全部文档的重排结果 |
+| `return_documents` | ✅ | 可选,`true` 时 `results[].document.text` 回带原文 |
+
+静默忽略:`max_tokens_per_doc` 等 Cohere 专属参数及其他未知字段。
+
+响应边界:
+
+- `results[]` 按相关度降序,`index` 指向入参 `documents` 下标,`relevance_score` 为 0–1 浮点;响应 `model` 回显请求值
+- 无 token 用量口径,调用日志只记时延与渠道
+
+实现依据:[`genai_guard.go`](../internal/oci/genai_guard.go) · [`rerank.go`](../internal/aiwire/rerank.go) · [`service/aigateway_extras.go`](../internal/service/aigateway_extras.go)
+
+
+
+
+POST /ai/v1/moderations 对比 OpenAI Moderations
+
+Moderations 是 OpenAI moderations 外壳映射 OCI Guardrails(内容审核 / PII / 提示注入)。上游是服务级 API,没有模型与白名单维度;渠道按分组直接挑选。
+
+| 标准字段 | 状态 | 网关行为 |
+| --- | :---: | --- |
+| `input` 为字符串 | ✅ | 单条审核 |
+| `input` 为字符串数组 | ✅ | 逐条审核,单次 1~8 条 |
+
+不支持(返回 400):多模态 input(图片等对象数组形态)、空字符串条目、空数组或超过 8 条的数组。静默忽略:`model`(接受任意值,不校验白名单)及其他未知字段。
+
+响应边界:
+
+- `categories` / `category_scores` 用 OCI 原生维度 `overall` / `blocklist` / `prompt_injection`,而非 OpenAI 标准类目(`hate` / `violence` 等);任一维度得分 ≥ 0.5 判定 `flagged`
+- PII 命中放扩展字段 `results[].pii`(`text` / `label` / `score` / `offset` / `length`),不参与 `flagged` 判定;实测中文人名 / 手机号识别较弱,英文 PII 识别正常
+- 响应 `model` 恒为 `oci-guardrails`
+
+实现依据:[`genai_guard.go`](../internal/oci/genai_guard.go) · [`moderations.go`](../internal/aiwire/moderations.go) · [`service/aigateway_extras.go`](../internal/service/aigateway_extras.go)
+
+
+
+`GET /ai/v1/models` 使用 OpenAI Models 列表外壳(`object`、`data[].id/object/created/owned_by`),但只返回当前渠道目录中通过分组、全局黑名单和密钥白名单筛选后的模型;网关不提供标准的单模型检索端点。
diff --git a/docs/docs.go b/docs/docs.go
index d49d016..b43985c 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -15,6 +15,33 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
+ "/ai/v1/audio/speech": {
+ "post": {
+ "tags": [
+ "AI 网关"
+ ],
+ "summary": "OpenAI Audio Speech 兼容端点(文本转语音)",
+ "parameters": [
+ {
+ "description": "OpenAI audio speech 请求体(model/input 必填,voice 见 xAI Grok Voice 列表,language 缺省 auto;未列字段原样透传)",
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.SpeechRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "音频字节(Content-Type 透传上游,默认 audio/mpeg)",
+ "schema": {
+ "type": "file"
+ }
+ }
+ }
+ }
+ },
"/ai/v1/chat/completions": {
"post": {
"tags": [
@@ -28,16 +55,15 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatRequest"
}
}
],
"responses": {
"200": {
- "description": "OpenAI 兼容响应(流式为 SSE,末尾 data: [DONE])",
+ "description": "OpenAI 兼容响应(非流式;流式为 SSE,末尾 data: [DONE])",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatResponse"
}
}
}
@@ -56,7 +82,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.EmbeddingsRequest"
}
}
],
@@ -64,8 +90,7 @@ const docTemplate = `{
"200": {
"description": "OpenAI 兼容响应",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.EmbeddingsResponse"
}
}
}
@@ -84,16 +109,15 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.MessagesRequest"
}
}
],
"responses": {
"200": {
- "description": "Anthropic 兼容响应(流式为 SSE)",
+ "description": "Anthropic 兼容响应(非流式;流式为 SSE 事件序列)",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.MessagesResponse"
}
}
}
@@ -109,8 +133,61 @@ const docTemplate = `{
"200": {
"description": "OpenAI 兼容 models 列表",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModelList"
+ }
+ }
+ }
+ }
+ },
+ "/ai/v1/moderations": {
+ "post": {
+ "tags": [
+ "AI 网关"
+ ],
+ "summary": "内容审核端点(OCI Guardrails)",
+ "parameters": [
+ {
+ "description": "审核请求体(input 为字符串或字符串数组,单次至多 8 条;model 接受但忽略)",
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationsRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "审核结果(categories/category_scores 为 overall/blocklist/prompt_injection,pii 为扩展字段)",
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationsResponse"
+ }
+ }
+ }
+ }
+ },
+ "/ai/v1/rerank": {
+ "post": {
+ "tags": [
+ "AI 网关"
+ ],
+ "summary": "文档重排端点(Cohere Rerank)",
+ "parameters": [
+ {
+ "description": "重排请求体(model/query/documents 必填,可选 top_n/return_documents)",
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "重排结果(results[].index 指向入参下标)",
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankResponse"
}
}
}
@@ -124,21 +201,20 @@ const docTemplate = `{
"summary": "OpenAI Responses 兼容端点",
"parameters": [
{
- "description": "OpenAI responses 请求体(支持 stream;web_search/x_search 服务端工具仅非流式)",
+ "description": "OpenAI responses 请求体(支持 stream;服务端工具 web_search/x_search/code_interpreter/mcp 含流式;未列字段原样透传上游)",
"name": "body",
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespRequest"
}
}
],
"responses": {
"200": {
- "description": "OpenAI 兼容响应(流式为 SSE)",
+ "description": "OpenAI 兼容响应(非流式;流式为 SSE);直通仅建模常用字段,未列字段原样返回",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespResponse"
}
}
}
@@ -159,8 +235,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.aboutResponse"
}
}
}
@@ -181,8 +256,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiModelBlacklist"
}
}
}
@@ -212,8 +286,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemResponse-oci-portal_internal_model_AiModelBlacklist"
}
}
}
@@ -261,8 +334,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiChannel"
}
}
}
@@ -292,8 +364,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.AiChannel"
}
}
}
@@ -384,8 +455,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.AiChannel"
}
}
}
@@ -415,8 +485,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiModelCache"
}
}
}
@@ -437,8 +506,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_AiCallLog"
}
}
}
@@ -459,8 +527,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiKey"
}
}
}
@@ -488,10 +555,9 @@ const docTemplate = `{
],
"responses": {
"201": {
- "description": "Created",
+ "description": "key 为明文密钥,仅本次返回",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.aiKeyCreateResponse"
}
}
}
@@ -591,8 +657,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.AiKey"
}
}
}
@@ -613,8 +678,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_AiContentLog"
}
}
}
@@ -635,8 +699,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_aiwire_Model"
}
}
}
@@ -657,8 +720,7 @@ const docTemplate = `{
"200": {
"description": "username 与 passwordLoginDisabled",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.credentialsResponse"
}
}
}
@@ -691,10 +753,7 @@ const docTemplate = `{
"401": {
"description": "当前密码错误",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -715,8 +774,7 @@ const docTemplate = `{
"200": {
"description": "items",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_UserIdentity"
}
}
}
@@ -749,10 +807,7 @@ const docTemplate = `{
"409": {
"description": "最后一个身份不可解绑",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -785,24 +840,19 @@ const docTemplate = `{
"200": {
"description": "token 与 expiresAt",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.tokenResponse"
}
},
"401": {
"description": "凭据错误",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
},
"428": {
"description": "需要两步验证码(totpRequired=true)",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.totpRequiredResponse"
}
}
}
@@ -836,8 +886,7 @@ const docTemplate = `{
"200": {
"description": "providers 与 passwordLoginDisabled",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.oauthProvidersResponse"
}
}
}
@@ -868,10 +917,7 @@ const docTemplate = `{
"200": {
"description": "url",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.urlResponse"
}
}
}
@@ -942,10 +988,7 @@ const docTemplate = `{
"409": {
"description": "未绑定外部身份",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -966,10 +1009,7 @@ const docTemplate = `{
"200": {
"description": "新 token 与 expiresAt",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.tokenResponse"
}
}
}
@@ -990,10 +1030,7 @@ const docTemplate = `{
"200": {
"description": "enabled",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "boolean"
- }
+ "$ref": "#/definitions/internal_api.enabledResponse"
}
}
}
@@ -1072,19 +1109,13 @@ const docTemplate = `{
"200": {
"description": "secret 与 otpauthUri",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.totpSetupResponse"
}
},
"409": {
"description": "已启用",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -1175,8 +1206,7 @@ const docTemplate = `{
"200": {
"description": "items 与 total",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_LogEvent"
}
}
}
@@ -1195,10 +1225,12 @@ const docTemplate = `{
"summary": "租户配置列表",
"responses": {
"200": {
- "description": "items",
+ "description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ConfigSummary"
+ }
}
}
}
@@ -1228,8 +1260,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.OciConfig"
}
}
}
@@ -1259,8 +1290,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.OciConfig"
}
}
}
@@ -1295,10 +1325,9 @@ const docTemplate = `{
],
"responses": {
"200": {
- "description": "OK",
+ "description": "config 与 changes 字段变更对照",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.configChangesResponse"
}
}
}
@@ -1366,8 +1395,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.AuditEventsView"
}
}
}
@@ -1395,10 +1423,9 @@ const docTemplate = `{
],
"responses": {
"200": {
- "description": "OK",
+ "description": "raw 为事件原文 JSON",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.rawDetailResponse"
}
}
}
@@ -1428,8 +1455,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
}
}
}
@@ -1493,8 +1522,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolume"
+ }
}
}
}
@@ -1531,8 +1562,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolume"
}
}
}
@@ -1576,8 +1606,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolume"
}
}
}
@@ -1639,8 +1668,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Compartment"
+ }
}
}
}
@@ -1670,8 +1701,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.RegionSubscriptionView"
+ }
}
}
}
@@ -1701,8 +1734,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Compartment"
+ }
}
}
}
@@ -1766,8 +1801,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.CostItem"
+ }
}
}
}
@@ -1797,8 +1834,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityDomain"
+ }
}
}
}
@@ -1834,8 +1873,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityProviderInfo"
+ }
}
}
}
@@ -1878,8 +1919,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityProviderInfo"
}
}
}
@@ -1971,8 +2011,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityProviderInfo"
}
}
}
@@ -2008,8 +2047,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentitySettingInfo"
}
}
}
@@ -2052,8 +2090,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentitySettingInfo"
}
}
}
@@ -2083,8 +2120,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Image"
+ }
}
}
}
@@ -2121,8 +2160,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Image"
}
}
}
@@ -2152,8 +2190,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
+ }
}
}
}
@@ -2188,10 +2228,9 @@ const docTemplate = `{
],
"responses": {
"201": {
- "description": "Created",
+ "description": "部分成功仍 201,errors 为逐台失败信息",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.createInstancesResponse"
}
}
}
@@ -2228,8 +2267,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
}
}
}
@@ -2273,8 +2311,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
}
}
}
@@ -2352,8 +2389,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
}
}
}
@@ -2390,8 +2426,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolumeAttachment"
+ }
}
}
}
@@ -2435,8 +2473,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolumeAttachment"
}
}
}
@@ -2482,8 +2519,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.publicIpResponse"
}
}
}
@@ -2520,8 +2556,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.ConsoleConnection"
+ }
}
}
}
@@ -2565,8 +2603,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.ConsoleConnection"
}
}
}
@@ -2609,11 +2646,10 @@ const docTemplate = `{
}
],
"responses": {
- "200": {
- "description": "sessionId 与 wsPath",
+ "201": {
+ "description": "sessionId 与 type",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.webConsoleSessionResponse"
}
}
}
@@ -2659,8 +2695,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.ipv6AddressResponse"
}
}
}
@@ -2738,8 +2773,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolumeAttachment"
}
}
}
@@ -2776,8 +2810,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.InstanceTraffic"
}
}
}
@@ -2814,8 +2847,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Vnic"
+ }
}
}
}
@@ -2859,8 +2894,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Vnic"
}
}
}
@@ -2897,8 +2931,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.VolumeAttachment"
+ }
}
}
}
@@ -2942,8 +2978,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VolumeAttachment"
}
}
}
@@ -2973,8 +3008,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.LimitValue"
+ }
}
}
}
@@ -3004,8 +3041,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.LimitService"
+ }
}
}
}
@@ -3035,8 +3074,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.RelayView"
}
}
}
@@ -3064,8 +3102,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.RelayView"
}
}
}
@@ -3120,8 +3157,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.logWebhookStatusResponse"
}
}
}
@@ -3149,8 +3185,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.LogWebhookInfo"
}
}
}
@@ -3211,8 +3246,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.NotificationRecipients"
}
}
}
@@ -3255,8 +3289,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.NotificationRecipients"
}
}
}
@@ -3292,8 +3325,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.PasswordPolicyInfo"
+ }
}
}
}
@@ -3345,8 +3380,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.PasswordPolicyInfo"
}
}
}
@@ -3376,8 +3410,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.RegionSubscriptionView"
+ }
}
}
}
@@ -3414,8 +3450,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.RegionSubscriptionView"
+ }
}
}
}
@@ -3449,10 +3487,9 @@ const docTemplate = `{
],
"responses": {
"200": {
- "description": "OK",
+ "description": "SAML 元数据 XML(附件下载)",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "file"
}
}
}
@@ -3482,8 +3519,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
+ }
}
}
}
@@ -3520,8 +3559,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
}
}
}
@@ -3558,8 +3596,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
}
}
}
@@ -3603,8 +3640,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
}
}
}
@@ -3666,8 +3702,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.ComputeShape"
+ }
}
}
}
@@ -3712,8 +3750,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SignOnRuleInfo"
}
}
}
@@ -3789,8 +3826,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SignOnRuleInfo"
+ }
}
}
}
@@ -3820,8 +3859,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
+ }
}
}
}
@@ -3858,8 +3899,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
}
}
}
@@ -3896,8 +3936,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
}
}
}
@@ -3941,8 +3980,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
}
}
}
@@ -4004,8 +4042,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SubscriptionInfo"
+ }
}
}
}
@@ -4042,8 +4082,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SubscriptionDetail"
}
}
}
@@ -4079,8 +4118,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUser"
+ }
}
}
}
@@ -4123,8 +4164,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUser"
}
}
}
@@ -4167,8 +4207,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUserDetail"
}
}
}
@@ -4218,8 +4257,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUser"
}
}
}
@@ -4294,8 +4332,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.deletedApiKeysResponse"
}
}
}
@@ -4338,8 +4375,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.deletedTotpResponse"
}
}
}
@@ -4380,10 +4416,9 @@ const docTemplate = `{
],
"responses": {
"200": {
- "description": "OK",
+ "description": "一次性明文密码",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.passwordResponse"
}
}
}
@@ -4413,8 +4448,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
+ }
}
}
}
@@ -4451,8 +4488,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
}
}
}
@@ -4489,8 +4525,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
}
}
}
@@ -4534,8 +4569,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
}
}
}
@@ -4613,8 +4647,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.ipv6StepsResponse"
}
}
}
@@ -4642,10 +4675,9 @@ const docTemplate = `{
],
"responses": {
"200": {
- "description": "OK",
+ "description": "config 与 changes 字段变更对照",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.configChangesResponse"
}
}
}
@@ -4725,8 +4757,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.addressResponse"
}
}
}
@@ -4790,8 +4821,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.BlockVolume"
+ }
}
}
}
@@ -4812,8 +4845,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.Overview"
}
}
}
@@ -4834,8 +4866,7 @@ const docTemplate = `{
"200": {
"description": "items",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_ProxyView"
}
}
}
@@ -4865,8 +4896,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
}
}
}
@@ -4898,8 +4928,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ImportResult"
}
}
}
@@ -4938,8 +4967,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
}
}
}
@@ -4994,8 +5022,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
}
}
}
@@ -5034,8 +5061,7 @@ const docTemplate = `{
"200": {
"description": "usedBy",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.usedByResponse"
}
}
}
@@ -5056,8 +5082,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RegionInfo"
+ }
}
}
}
@@ -5078,8 +5106,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView"
}
}
}
@@ -5118,8 +5145,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView"
}
}
}
@@ -5167,8 +5193,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyEventsView"
}
}
}
@@ -5198,8 +5223,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyEventsView"
}
}
}
@@ -5220,8 +5244,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyTemplateView"
}
}
}
@@ -5365,8 +5388,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.SecuritySettings"
}
}
}
@@ -5396,8 +5418,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.SecuritySettings"
}
}
}
@@ -5418,8 +5439,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TaskSettingsView"
}
}
}
@@ -5449,8 +5469,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TaskSettingsView"
}
}
}
@@ -5471,8 +5490,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TelegramView"
}
}
}
@@ -5502,8 +5520,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TelegramView"
}
}
}
@@ -5542,8 +5559,7 @@ const docTemplate = `{
"200": {
"description": "items 与 total",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_SystemLog"
}
}
}
@@ -5566,8 +5582,7 @@ const docTemplate = `{
"schema": {
"type": "array",
"items": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5598,8 +5613,7 @@ const docTemplate = `{
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5629,8 +5643,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5667,8 +5680,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5723,8 +5735,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.TaskLog"
+ }
}
}
}
@@ -5754,15 +5768,13 @@ const docTemplate = `{
"202": {
"description": "Accepted",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.triggerResponse"
}
},
"409": {
"description": "任务正在执行中",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -5799,10 +5811,7 @@ const docTemplate = `{
"403": {
"description": "时间戳超窗或证书源非 Oracle 域",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
},
"404": {
@@ -5813,6 +5822,77 @@ const docTemplate = `{
}
},
"definitions": {
+ "internal_api.aboutResources": {
+ "type": "object",
+ "properties": {
+ "cpuAvgPercent": {
+ "type": "number"
+ },
+ "dbBytes": {
+ "type": "integer"
+ },
+ "dbEngine": {
+ "type": "string"
+ },
+ "goroutines": {
+ "type": "integer"
+ },
+ "memHeapBytes": {
+ "type": "integer"
+ },
+ "memSysBytes": {
+ "type": "integer"
+ },
+ "numCpu": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.aboutResponse": {
+ "type": "object",
+ "properties": {
+ "buildTime": {
+ "type": "string"
+ },
+ "goVersion": {
+ "type": "string"
+ },
+ "platform": {
+ "type": "string"
+ },
+ "resources": {
+ "$ref": "#/definitions/internal_api.aboutResources"
+ },
+ "startedAt": {
+ "type": "string"
+ },
+ "uptimeSeconds": {
+ "type": "integer"
+ },
+ "version": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.addressResponse": {
+ "type": "object",
+ "properties": {
+ "address": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.aiKeyCreateResponse": {
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiKey"
+ },
+ "key": {
+ "type": "string"
+ }
+ }
+ },
"internal_api.attachBootVolumeRequest": {
"type": "object",
"required": [
@@ -5871,6 +5951,17 @@ const docTemplate = `{
}
}
},
+ "internal_api.configChangesResponse": {
+ "type": "object",
+ "properties": {
+ "changes": {
+ "$ref": "#/definitions/oci-portal_internal_service.Changes"
+ },
+ "config": {
+ "$ref": "#/definitions/oci-portal_internal_model.OciConfig"
+ }
+ }
+ },
"internal_api.createConsoleConnectionRequest": {
"type": "object",
"required": [
@@ -6001,6 +6092,23 @@ const docTemplate = `{
}
}
},
+ "internal_api.createInstancesResponse": {
+ "type": "object",
+ "properties": {
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "instances": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
+ }
+ }
+ }
+ },
"internal_api.createSecurityListRequest": {
"type": "object",
"required": [
@@ -6077,10 +6185,7 @@ const docTemplate = `{
"type": "string"
},
"payload": {
- "type": "array",
- "items": {
- "type": "integer"
- }
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
},
"type": {
"type": "string"
@@ -6148,6 +6253,33 @@ const docTemplate = `{
}
}
},
+ "internal_api.credentialsResponse": {
+ "type": "object",
+ "properties": {
+ "passwordLoginDisabled": {
+ "type": "boolean"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.deletedApiKeysResponse": {
+ "type": "object",
+ "properties": {
+ "deletedApiKeys": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.deletedTotpResponse": {
+ "type": "object",
+ "properties": {
+ "deletedTotpDevices": {
+ "type": "integer"
+ }
+ }
+ },
"internal_api.enableIPv6Request": {
"type": "object",
"properties": {
@@ -6156,6 +6288,22 @@ const docTemplate = `{
}
}
},
+ "internal_api.enabledResponse": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ }
+ }
+ },
+ "internal_api.errorResponse": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ }
+ }
+ },
"internal_api.importRequest": {
"type": "object",
"required": [
@@ -6219,6 +6367,143 @@ const docTemplate = `{
}
}
},
+ "internal_api.ipv6AddressResponse": {
+ "type": "object",
+ "properties": {
+ "ipv6Address": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.ipv6StepsResponse": {
+ "type": "object",
+ "properties": {
+ "steps": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.IPv6Step"
+ }
+ }
+ }
+ },
+ "internal_api.itemResponse-oci-portal_internal_model_AiModelBlacklist": {
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiModelBlacklist"
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_aiwire_Model": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Model"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiChannel": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiChannel"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiKey": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiKey"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiModelBlacklist": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiModelBlacklist"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiModelCache": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiModelCache"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_UserIdentity": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.UserIdentity"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyChannelView"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_service_NotifyTemplateView": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyTemplateView"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_service_ProxyView": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
+ }
+ }
+ }
+ },
+ "internal_api.logWebhookStatusResponse": {
+ "type": "object",
+ "properties": {
+ "exists": {
+ "type": "boolean"
+ },
+ "webhook": {
+ "$ref": "#/definitions/oci-portal_internal_service.LogWebhookInfo"
+ }
+ }
+ },
"internal_api.loginRequest": {
"type": "object",
"required": [
@@ -6242,6 +6527,100 @@ const docTemplate = `{
}
}
},
+ "internal_api.oauthProvidersResponse": {
+ "type": "object",
+ "properties": {
+ "passwordLoginDisabled": {
+ "type": "boolean"
+ },
+ "providers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ProviderInfo"
+ }
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_AiCallLog": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiCallLog"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_AiContentLog": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiContentLog"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_LogEvent": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.LogEvent"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_SystemLog": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.SystemLog"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.passwordResponse": {
+ "type": "object",
+ "properties": {
+ "password": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.publicIpResponse": {
+ "type": "object",
+ "properties": {
+ "publicIp": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.rawDetailResponse": {
+ "type": "object",
+ "properties": {
+ "raw": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ }
+ }
+ },
"internal_api.renameRequest": {
"type": "object",
"required": [
@@ -6267,6 +6646,47 @@ const docTemplate = `{
}
}
},
+ "internal_api.tokenResponse": {
+ "type": "object",
+ "properties": {
+ "expiresAt": {
+ "type": "string"
+ },
+ "token": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.totpRequiredResponse": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ },
+ "totpRequired": {
+ "type": "boolean"
+ }
+ }
+ },
+ "internal_api.totpSetupResponse": {
+ "type": "object",
+ "properties": {
+ "otpauthUri": {
+ "type": "string"
+ },
+ "secret": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.triggerResponse": {
+ "type": "object",
+ "properties": {
+ "triggered": {
+ "type": "boolean"
+ }
+ }
+ },
"internal_api.updateBootVolumeRequest": {
"type": "object",
"properties": {
@@ -6376,10 +6796,7 @@ const docTemplate = `{
"type": "string"
},
"payload": {
- "type": "array",
- "items": {
- "type": "integer"
- }
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
},
"status": {
"type": "string"
@@ -6423,6 +6840,1927 @@ const docTemplate = `{
}
}
},
+ "internal_api.urlResponse": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.usedByResponse": {
+ "type": "object",
+ "properties": {
+ "usedBy": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.webConsoleSessionResponse": {
+ "type": "object",
+ "properties": {
+ "sessionId": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthBlock": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "id": {
+ "description": "tool_use",
+ "type": "string"
+ },
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "is_error": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "source": {
+ "description": "image",
+ "allOf": [
+ {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ }
+ ]
+ },
+ "text": {
+ "type": "string"
+ },
+ "tool_use_id": {
+ "description": "tool_result",
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthContent": {
+ "type": "object",
+ "properties": {
+ "blocks": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthBlock"
+ }
+ },
+ "text": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthMessage": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthContent"
+ },
+ "role": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthOutputConfig": {
+ "type": "object",
+ "properties": {
+ "effort": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthTool": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "input_schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthUsage": {
+ "type": "object",
+ "properties": {
+ "cache_read_input_tokens": {
+ "description": "CacheReadInputTokens 是缓存命中读取数;OCI 隐式缓存无「写入」计数,cache_creation 恒缺",
+ "type": "integer"
+ },
+ "input_tokens": {
+ "type": "integer"
+ },
+ "output_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnyJSON": {
+ "type": "object"
+ },
+ "oci-portal_internal_aiwire.ChatMessage": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "role": {
+ "type": "string"
+ },
+ "tool_call_id": {
+ "type": "string"
+ },
+ "tool_calls": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ToolCall"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ChatRequest": {
+ "type": "object",
+ "properties": {
+ "max_completion_tokens": {
+ "type": "integer"
+ },
+ "max_tokens": {
+ "type": "integer"
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatMessage"
+ }
+ },
+ "model": {
+ "type": "string"
+ },
+ "parallel_tool_calls": {
+ "type": "boolean"
+ },
+ "reasoning_effort": {
+ "type": "string"
+ },
+ "response_format": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ResponseFormat"
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "stream_options": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.StreamOptions"
+ },
+ "temperature": {
+ "type": "number"
+ },
+ "tool_choice": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tools": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Tool"
+ }
+ },
+ "top_p": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ChatResponse": {
+ "type": "object",
+ "properties": {
+ "choices": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Choice"
+ }
+ },
+ "created": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Usage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Choice": {
+ "type": "object",
+ "properties": {
+ "finish_reason": {
+ "type": "string"
+ },
+ "index": {
+ "type": "integer"
+ },
+ "message": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatMessage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.EmbedUsage": {
+ "type": "object",
+ "properties": {
+ "prompt_tokens": {
+ "type": "integer"
+ },
+ "total_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Embedding": {
+ "type": "object",
+ "properties": {
+ "embedding": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ }
+ },
+ "index": {
+ "type": "integer"
+ },
+ "object": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.EmbeddingsRequest": {
+ "type": "object",
+ "properties": {
+ "dimensions": {
+ "type": "integer"
+ },
+ "encoding_format": {
+ "type": "string"
+ },
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "model": {
+ "type": "string"
+ },
+ "user": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.EmbeddingsResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Embedding"
+ }
+ },
+ "model": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.EmbedUsage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.FunctionCall": {
+ "type": "object",
+ "properties": {
+ "arguments": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.FunctionDef": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "parameters": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.MessagesRequest": {
+ "type": "object",
+ "properties": {
+ "max_tokens": {
+ "type": "integer"
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthMessage"
+ }
+ },
+ "metadata": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "model": {
+ "type": "string"
+ },
+ "output_config": {
+ "description": "OutputConfig 是 Anthropic 官方输出控制(effort 等);网关映射 effort 到 OCI reasoningEffort。",
+ "allOf": [
+ {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthOutputConfig"
+ }
+ ]
+ },
+ "stop_sequences": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "system": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "temperature": {
+ "type": "number"
+ },
+ "thinking": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tool_choice": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tools": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthTool"
+ }
+ },
+ "top_k": {
+ "type": "integer"
+ },
+ "top_p": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.MessagesResponse": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthBlock"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "role": {
+ "type": "string"
+ },
+ "stop_reason": {
+ "type": "string"
+ },
+ "stop_sequence": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthUsage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Model": {
+ "type": "object",
+ "properties": {
+ "created": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "owned_by": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModelList": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Model"
+ }
+ },
+ "object": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationPii": {
+ "type": "object",
+ "properties": {
+ "label": {
+ "type": "string"
+ },
+ "length": {
+ "type": "integer"
+ },
+ "offset": {
+ "type": "integer"
+ },
+ "score": {
+ "type": "number"
+ },
+ "text": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationResult": {
+ "type": "object",
+ "properties": {
+ "categories": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "boolean"
+ }
+ },
+ "category_scores": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "format": "float64"
+ }
+ },
+ "flagged": {
+ "type": "boolean"
+ },
+ "pii": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationPii"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationsRequest": {
+ "type": "object",
+ "properties": {
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "model": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationsResponse": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "results": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationResult"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.PromptTokensDetails": {
+ "type": "object",
+ "properties": {
+ "cached_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankDocument": {
+ "type": "object",
+ "properties": {
+ "text": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankRequest": {
+ "type": "object",
+ "properties": {
+ "documents": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "model": {
+ "type": "string"
+ },
+ "query": {
+ "type": "string"
+ },
+ "return_documents": {
+ "type": "boolean"
+ },
+ "top_n": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankResponse": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "type": "string"
+ },
+ "results": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankResult"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankResult": {
+ "type": "object",
+ "properties": {
+ "document": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankDocument"
+ },
+ "index": {
+ "type": "integer"
+ },
+ "relevance_score": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespError": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespInDetails": {
+ "type": "object",
+ "properties": {
+ "cached_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespOutDetails": {
+ "type": "object",
+ "properties": {
+ "reasoning_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespReasoning": {
+ "type": "object",
+ "properties": {
+ "effort": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespRequest": {
+ "type": "object",
+ "properties": {
+ "background": {
+ "type": "boolean"
+ },
+ "conversation": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "instructions": {
+ "type": "string"
+ },
+ "max_output_tokens": {
+ "type": "integer"
+ },
+ "model": {
+ "type": "string"
+ },
+ "parallel_tool_calls": {
+ "type": "boolean"
+ },
+ "previous_response_id": {
+ "type": "string"
+ },
+ "reasoning": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespReasoning"
+ },
+ "store": {
+ "type": "boolean"
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "temperature": {
+ "type": "number"
+ },
+ "text": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespText"
+ },
+ "tool_choice": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tools": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespTool"
+ }
+ },
+ "top_p": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespResponse": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "type": "integer"
+ },
+ "error": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespError"
+ },
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "output": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "status": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespUsage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespText": {
+ "type": "object",
+ "properties": {
+ "format": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespTextFormat"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespTextFormat": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "strict": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespTool": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "parameters": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "strict": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespUsage": {
+ "type": "object",
+ "properties": {
+ "input_tokens": {
+ "type": "integer"
+ },
+ "input_tokens_details": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespInDetails"
+ },
+ "output_tokens": {
+ "type": "integer"
+ },
+ "output_tokens_details": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespOutDetails"
+ },
+ "total_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ResponseFormat": {
+ "type": "object",
+ "properties": {
+ "json_schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.SpeechRequest": {
+ "type": "object",
+ "properties": {
+ "input": {
+ "type": "string"
+ },
+ "language": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "response_format": {
+ "type": "string"
+ },
+ "voice": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.StreamOptions": {
+ "type": "object",
+ "properties": {
+ "include_usage": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Tool": {
+ "type": "object",
+ "properties": {
+ "function": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.FunctionDef"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ToolCall": {
+ "type": "object",
+ "properties": {
+ "function": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.FunctionCall"
+ },
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Usage": {
+ "type": "object",
+ "properties": {
+ "completion_tokens": {
+ "type": "integer"
+ },
+ "prompt_tokens": {
+ "type": "integer"
+ },
+ "prompt_tokens_details": {
+ "description": "PromptTokensDetails 携带缓存命中细分;OCI 为隐式 prompt 缓存,只有读取计数",
+ "allOf": [
+ {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.PromptTokensDetails"
+ }
+ ]
+ },
+ "total_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiCallLog": {
+ "type": "object",
+ "properties": {
+ "cachedTokens": {
+ "description": "CachedTokens 是输入中缓存命中(读取)的部分;OCI 隐式缓存无写入计数",
+ "type": "integer"
+ },
+ "channelId": {
+ "type": "integer"
+ },
+ "channelName": {
+ "type": "string"
+ },
+ "clientIp": {
+ "description": "ClientIP 是网关调用方来源 IP(尊重「真实 IP 头」安全设置,与系统日志同源)",
+ "type": "string"
+ },
+ "completionTokens": {
+ "type": "integer"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "endpoint": {
+ "description": "openai / anthropic",
+ "type": "string"
+ },
+ "errMsg": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "keyId": {
+ "type": "integer"
+ },
+ "keyName": {
+ "type": "string"
+ },
+ "latencyMs": {
+ "type": "integer"
+ },
+ "model": {
+ "type": "string"
+ },
+ "promptTokens": {
+ "type": "integer"
+ },
+ "retries": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "integer"
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "totalTokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiChannel": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "disabledUntil": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "failCount": {
+ "description": "FailCount 连续失败计数;达阈值后 DisabledUntil 指数退避熔断,成功/探测通过复位",
+ "type": "integer"
+ },
+ "group": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastProbeAt": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "ociConfigId": {
+ "type": "integer"
+ },
+ "priority": {
+ "type": "integer"
+ },
+ "probeError": {
+ "type": "string"
+ },
+ "probeStatus": {
+ "description": "ok / no_service / no_quota / error",
+ "type": "string"
+ },
+ "region": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ },
+ "weight": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiContentLog": {
+ "type": "object",
+ "properties": {
+ "callLogId": {
+ "description": "CallLogID 关联同次调用的 AiCallLog,调用日志详情据此反查正文",
+ "type": "integer"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "endpoint": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "keyId": {
+ "type": "integer"
+ },
+ "keyName": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "requestBody": {
+ "description": "RequestBody / ResponseBody 是截断后的正文 JSON;\n64KB 截断恰在 MySQL TEXT 上限(65535B)边界,size 上探一档 → MEDIUMTEXT",
+ "type": "string"
+ },
+ "responseBody": {
+ "type": "string"
+ },
+ "stream": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiKey": {
+ "type": "object",
+ "properties": {
+ "contentLogUntil": {
+ "description": "ContentLogUntil 是内容日志开启截止时间;nil = 永关(默认,红线),\n开启必须限时,到期自动停写",
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "group": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastUsedAt": {
+ "type": "string"
+ },
+ "models": {
+ "description": "Models 是模型白名单(精确匹配模型名);空 = 不限,非空时网关仅放行列表内模型",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "name": {
+ "type": "string"
+ },
+ "tail": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiModelBlacklist": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiModelCache": {
+ "type": "object",
+ "properties": {
+ "capability": {
+ "type": "string"
+ },
+ "channelId": {
+ "type": "integer"
+ },
+ "deprecatedAt": {
+ "description": "DeprecatedAt 是 OCI 宣布的模型弃用时间;nil 表示未宣布。\n弃用后仍可调用,直到 RetiredAt(按需推理退役,同步层已剔除过期项)。",
+ "type": "string"
+ },
+ "modelOcid": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "retiredAt": {
+ "type": "string"
+ },
+ "syncedAt": {
+ "type": "string"
+ },
+ "vendor": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.LogEvent": {
+ "type": "object",
+ "properties": {
+ "eventTime": {
+ "type": "string"
+ },
+ "eventType": {
+ "description": "异步解析回填,如 com.oraclecloud.ComputeApi.TerminateInstance",
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "messageId": {
+ "description": "幂等键(X-OCI-NS-MessageId)",
+ "type": "string"
+ },
+ "ociConfigId": {
+ "description": "经 secret 反查归属租户",
+ "type": "integer"
+ },
+ "payload": {
+ "description": "防御上限 256KB 超 MySQL TEXT(64KB),size 上探一档 → MEDIUMTEXT;PG/SQLite 仍为 text",
+ "type": "string"
+ },
+ "processed": {
+ "type": "boolean"
+ },
+ "receivedAt": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "sourceIp": {
+ "description": "异步解析回填,Audit 事件的发起方 IP",
+ "type": "string"
+ },
+ "truncated": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_model.OciConfig": {
+ "type": "object",
+ "properties": {
+ "accountType": {
+ "type": "string"
+ },
+ "alias": {
+ "type": "string"
+ },
+ "aliveStatus": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "fingerprint": {
+ "type": "string"
+ },
+ "group": {
+ "description": "Group 是面板内的自定义分组标签,空串表示未分组;\n列名避开 SQL 保留字 GROUP",
+ "type": "string"
+ },
+ "homeRegionKey": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastError": {
+ "type": "string"
+ },
+ "lastVerifiedAt": {
+ "type": "string"
+ },
+ "multiCompartment": {
+ "type": "boolean"
+ },
+ "multiRegion": {
+ "description": "多区域 / 多区间支持:开启后订阅区域与 compartment 列表入库缓存,\n供筛选器免实时调 OCI;未开启的租户筛选器锁定主区域 / 根区间。",
+ "type": "boolean"
+ },
+ "paymentModel": {
+ "type": "string"
+ },
+ "promotionAmount": {
+ "type": "number"
+ },
+ "promotionExpires": {
+ "type": "string"
+ },
+ "promotionStatus": {
+ "type": "string"
+ },
+ "proxyId": {
+ "description": "ProxyID 关联出站代理,nil 表示直连;该租户全部 SDK 调用经此代理",
+ "type": "integer"
+ },
+ "region": {
+ "type": "string"
+ },
+ "subscriptionId": {
+ "type": "string"
+ },
+ "subscriptionTier": {
+ "type": "string"
+ },
+ "tenancyName": {
+ "type": "string"
+ },
+ "tenancyOcid": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ },
+ "userOcid": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.SystemLog": {
+ "type": "object",
+ "properties": {
+ "clientIp": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "durationMs": {
+ "type": "integer"
+ },
+ "errMsg": {
+ "description": "ErrMsg 仅失败请求(\u003e=400)存响应的 error 文案,便于免翻服务端日志定位原因",
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "method": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "status": {
+ "type": "integer"
+ },
+ "userAgent": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.Task": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "cronExpr": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastError": {
+ "type": "string"
+ },
+ "lastRunAt": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "payload": {
+ "type": "string"
+ },
+ "runCount": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.TaskLog": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "durationMs": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "message": {
+ "type": "string"
+ },
+ "success": {
+ "type": "boolean"
+ },
+ "taskId": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.UserIdentity": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "display": {
+ "description": "展示名:邮箱 / GitHub login",
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "provider": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.AuditEvent": {
+ "type": "object",
+ "properties": {
+ "compartmentName": {
+ "type": "string"
+ },
+ "eventId": {
+ "type": "string"
+ },
+ "eventName": {
+ "type": "string"
+ },
+ "eventTime": {
+ "type": "string"
+ },
+ "ipAddress": {
+ "type": "string"
+ },
+ "principalName": {
+ "type": "string"
+ },
+ "raw": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "requestAction": {
+ "type": "string"
+ },
+ "requestPath": {
+ "type": "string"
+ },
+ "resourceName": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.BlockVolume": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "sizeInGBs": {
+ "type": "integer"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vpusPerGB": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.BootVolume": {
+ "type": "object",
+ "properties": {
+ "attachedInstanceId": {
+ "type": "string"
+ },
+ "attachedInstanceName": {
+ "type": "string"
+ },
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "compartmentId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "imageId": {
+ "type": "string"
+ },
+ "imageName": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "sizeInGBs": {
+ "type": "integer"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vpusPerGB": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.BootVolumeAttachment": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "bootVolumeId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Compartment": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "parentId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.ComputeShape": {
+ "type": "object",
+ "properties": {
+ "billingType": {
+ "description": "ALWAYS_FREE / LIMITED_FREE / PAID",
+ "type": "string"
+ },
+ "gpus": {
+ "type": "integer"
+ },
+ "isFlexible": {
+ "type": "boolean"
+ },
+ "memoryInGBs": {
+ "type": "number"
+ },
+ "memoryMaxGBs": {
+ "type": "number"
+ },
+ "memoryMinGBs": {
+ "type": "number"
+ },
+ "name": {
+ "type": "string"
+ },
+ "ocpus": {
+ "type": "number"
+ },
+ "ocpusMax": {
+ "type": "number"
+ },
+ "ocpusMin": {
+ "type": "number"
+ },
+ "processorDescription": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.ConsoleConnection": {
+ "type": "object",
+ "properties": {
+ "connectionString": {
+ "description": "串口控制台 SSH 命令",
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "vncConnectionString": {
+ "description": "VNC over SSH 隧道命令",
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.CostItem": {
+ "type": "object",
+ "properties": {
+ "computedAmount": {
+ "type": "number"
+ },
+ "computedQuantity": {
+ "type": "number"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "groupValue": {
+ "type": "string"
+ },
+ "timeStart": {
+ "type": "string"
+ },
+ "unit": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IPv6Step": {
+ "type": "object",
+ "properties": {
+ "detail": {
+ "type": "string"
+ },
+ "status": {
+ "description": "done / skipped / failed",
+ "type": "string"
+ },
+ "step": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IdentityDomain": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "homeRegion": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "licenseType": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IdentityProviderInfo": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "jitEnabled": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "partnerProviderId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IdentitySettingInfo": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "primaryEmailRequired": {
+ "description": "用户需要提供主电子邮件地址:开启后创建用户 / JIT 预配必须带邮箱",
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Image": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "operatingSystem": {
+ "type": "string"
+ },
+ "operatingSystemVersion": {
+ "type": "string"
+ },
+ "sizeInMBs": {
+ "type": "integer"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Instance": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "compartmentId": {
+ "type": "string"
+ },
+ "definedTags": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": {}
+ }
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "freeformTags": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "imageId": {
+ "type": "string"
+ },
+ "ipv6Addresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "memoryInGBs": {
+ "type": "number"
+ },
+ "ocpus": {
+ "type": "number"
+ },
+ "privateIp": {
+ "type": "string"
+ },
+ "publicIp": {
+ "type": "string"
+ },
+ "region": {
+ "type": "string"
+ },
+ "shape": {
+ "type": "string"
+ },
+ "subnetId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.InstanceTraffic": {
+ "type": "object",
+ "properties": {
+ "inboundBytes": {
+ "type": "number"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "outboundBytes": {
+ "type": "number"
+ },
+ "vnics": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.VnicTraffic"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_oci.LimitService": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.LimitValue": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "available": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "scopeType": {
+ "type": "string"
+ },
+ "used": {
+ "type": "integer"
+ },
+ "value": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.NotificationRecipients": {
+ "type": "object",
+ "properties": {
+ "recipients": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "testModeEnabled": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_oci.PasswordPolicyInfo": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "minLength": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "numPasswordsInHistory": {
+ "type": "integer"
+ },
+ "passwordExpiresAfter": {
+ "type": "integer"
+ },
+ "passwordStrength": {
+ "type": "string"
+ },
+ "priority": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.PromotionInfo": {
+ "type": "object",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "currencyUnit": {
+ "type": "string"
+ },
+ "duration": {
+ "type": "integer"
+ },
+ "durationUnit": {
+ "type": "string"
+ },
+ "isIntentToPay": {
+ "type": "boolean"
+ },
+ "status": {
+ "type": "string"
+ },
+ "timeExpired": {
+ "type": "string"
+ },
+ "timeStarted": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.RegionInfo": {
+ "type": "object",
+ "properties": {
+ "alias": {
+ "type": "string"
+ },
+ "key": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.RelayResource": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "state": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.SecurityList": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "egressRules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityRule"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "ingressRules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityRule"
+ }
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vcnId": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_oci.SecurityRule": {
"type": "object",
"properties": {
@@ -6456,6 +8794,379 @@ const docTemplate = `{
}
}
},
+ "oci-portal_internal_oci.SignOnRuleInfo": {
+ "type": "object",
+ "properties": {
+ "authenticationFactor": {
+ "type": "string"
+ },
+ "builtIn": {
+ "type": "boolean"
+ },
+ "conditionAttribute": {
+ "type": "string"
+ },
+ "conditionValue": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "sequence": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Subnet": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "cidrBlock": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "dnsLabel": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "ipv6CidrBlock": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "prohibitPublicIp": {
+ "type": "boolean"
+ },
+ "routeTableId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vcnId": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.SubscriptionDetail": {
+ "type": "object",
+ "properties": {
+ "classicSubscriptionId": {
+ "type": "string"
+ },
+ "cloudAmountCurrency": {
+ "type": "string"
+ },
+ "csiNumber": {
+ "type": "string"
+ },
+ "customerCountryCode": {
+ "type": "string"
+ },
+ "endDate": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "isGovernmentSubscription": {
+ "type": "boolean"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "paymentModel": {
+ "type": "string"
+ },
+ "programType": {
+ "type": "string"
+ },
+ "promotions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.PromotionInfo"
+ }
+ },
+ "regionAssignment": {
+ "type": "string"
+ },
+ "serviceName": {
+ "type": "string"
+ },
+ "startDate": {
+ "type": "string"
+ },
+ "subscriptionTier": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "timeUpdated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.SubscriptionInfo": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "serviceName": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "timeUpdated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.TenantUser": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "emailVerified": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "isCurrentUser": {
+ "type": "boolean"
+ },
+ "lastLoginTime": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "mfaActivated": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.TenantUserDetail": {
+ "type": "object",
+ "properties": {
+ "familyName": {
+ "type": "string"
+ },
+ "givenName": {
+ "type": "string"
+ },
+ "inAdminGroup": {
+ "type": "boolean"
+ },
+ "inDomain": {
+ "type": "boolean"
+ },
+ "isDomainAdmin": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_oci.TrafficPoint": {
+ "type": "object",
+ "properties": {
+ "bytes": {
+ "type": "number"
+ },
+ "timestamp": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.VCN": {
+ "type": "object",
+ "properties": {
+ "cidrBlocks": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "compartmentId": {
+ "type": "string"
+ },
+ "defaultRouteTableId": {
+ "type": "string"
+ },
+ "defaultSecurityListId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "dnsLabel": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "ipv6CidrBlocks": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Vnic": {
+ "type": "object",
+ "properties": {
+ "attachmentId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "ipv6Addresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "isPrimary": {
+ "type": "boolean"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "privateIp": {
+ "type": "string"
+ },
+ "publicIp": {
+ "type": "string"
+ },
+ "subnetId": {
+ "type": "string"
+ },
+ "subnetName": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vnicId": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.VnicTraffic": {
+ "type": "object",
+ "properties": {
+ "inbound": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.TrafficPoint"
+ }
+ },
+ "inboundBytes": {
+ "type": "number"
+ },
+ "outbound": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.TrafficPoint"
+ }
+ },
+ "outboundBytes": {
+ "type": "number"
+ },
+ "vnicId": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.VolumeAttachment": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "device": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "isReadOnly": {
+ "type": "boolean"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "volumeId": {
+ "type": "string"
+ },
+ "volumeName": {
+ "description": "卷本身的名称(attachment 名是自动生成的)",
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.AuditEventsView": {
+ "type": "object",
+ "properties": {
+ "cursor": {
+ "type": "string"
+ },
+ "exhausted": {
+ "type": "boolean"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.AuditEvent"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_service.Changes": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.ChannelInput": {
"type": "object",
"properties": {
@@ -6482,6 +9193,150 @@ const docTemplate = `{
}
}
},
+ "oci-portal_internal_service.ConfigSummary": {
+ "type": "object",
+ "properties": {
+ "accountType": {
+ "type": "string"
+ },
+ "alias": {
+ "type": "string"
+ },
+ "aliveStatus": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "group": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastError": {
+ "type": "string"
+ },
+ "lastVerifiedAt": {
+ "type": "string"
+ },
+ "multiCompartment": {
+ "type": "boolean"
+ },
+ "multiRegion": {
+ "type": "boolean"
+ },
+ "proxyId": {
+ "type": "integer"
+ },
+ "proxyName": {
+ "description": "ProxyName 由 List 按关联填充,供表格代理列 hover 展示",
+ "type": "string"
+ },
+ "region": {
+ "type": "string"
+ },
+ "tenancyName": {
+ "type": "string"
+ },
+ "tenancyOcid": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.ImportFail": {
+ "type": "object",
+ "properties": {
+ "line": {
+ "type": "string"
+ },
+ "lineNo": {
+ "type": "integer"
+ },
+ "reason": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.ImportResult": {
+ "type": "object",
+ "properties": {
+ "created": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
+ }
+ },
+ "failed": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ImportFail"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_service.LogWebhookInfo": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "secret": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.NotifyChannelView": {
+ "type": "object",
+ "properties": {
+ "bodyTemplate": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "from": {
+ "type": "string"
+ },
+ "host": {
+ "description": "smtp",
+ "type": "string"
+ },
+ "port": {
+ "type": "integer"
+ },
+ "secretSet": {
+ "description": "密文字段状态(ntfy token / bark device key / smtp password)",
+ "type": "boolean"
+ },
+ "secretTail": {
+ "type": "string"
+ },
+ "server": {
+ "description": "ntfy / bark 共用 Server",
+ "type": "string"
+ },
+ "to": {
+ "type": "string"
+ },
+ "topic": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "url": {
+ "description": "webhook",
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.NotifyEventsView": {
"type": "object",
"properties": {
@@ -6523,6 +9378,30 @@ const docTemplate = `{
}
}
},
+ "oci-portal_internal_service.NotifyTemplateView": {
+ "type": "object",
+ "properties": {
+ "defaultTemplate": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "label": {
+ "type": "string"
+ },
+ "template": {
+ "description": "Template 是自定义模板;空串表示未自定义(按默认发送)",
+ "type": "string"
+ },
+ "vars": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
"oci-portal_internal_service.OAuthProvidersView": {
"type": "object",
"properties": {
@@ -6555,6 +9434,128 @@ const docTemplate = `{
}
}
},
+ "oci-portal_internal_service.Overview": {
+ "type": "object",
+ "properties": {
+ "check": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewCheck"
+ },
+ "cost": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewCost"
+ },
+ "tasks": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewTasks"
+ },
+ "tenants": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewTenants"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewCheck": {
+ "type": "object",
+ "properties": {
+ "coveredConfigs": {
+ "type": "integer"
+ },
+ "hasActiveTask": {
+ "type": "boolean"
+ },
+ "instanceCount": {
+ "type": "integer"
+ },
+ "lastCheckedAt": {
+ "type": "string"
+ },
+ "totalConfigs": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewCost": {
+ "type": "object",
+ "properties": {
+ "coveredConfigs": {
+ "type": "integer"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "days": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewCostDay"
+ }
+ },
+ "hasActiveTask": {
+ "type": "boolean"
+ },
+ "total": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewCostDay": {
+ "type": "object",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "day": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewTasks": {
+ "type": "object",
+ "properties": {
+ "active": {
+ "type": "integer"
+ },
+ "cost": {
+ "type": "integer"
+ },
+ "healthCheck": {
+ "type": "integer"
+ },
+ "snatch": {
+ "type": "integer"
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewTenants": {
+ "type": "object",
+ "properties": {
+ "alive": {
+ "type": "integer"
+ },
+ "byType": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer"
+ }
+ },
+ "dead": {
+ "type": "integer"
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_service.ProviderInfo": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.ProxyInput": {
"type": "object",
"required": [
@@ -6583,6 +9584,101 @@ const docTemplate = `{
}
}
},
+ "oci-portal_internal_service.ProxyView": {
+ "type": "object",
+ "properties": {
+ "city": {
+ "type": "string"
+ },
+ "country": {
+ "description": "Country / City 为出口实测地区;GeoAt 空串表示尚未探测(前端显示「检测中」)",
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "geoAt": {
+ "type": "string"
+ },
+ "host": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "passwordSet": {
+ "type": "boolean"
+ },
+ "port": {
+ "type": "integer"
+ },
+ "type": {
+ "type": "string"
+ },
+ "usedBy": {
+ "description": "UsedBy 为关联此代理的租户数,前端据此提示删除约束",
+ "type": "integer"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.RegionSubscriptionView": {
+ "type": "object",
+ "properties": {
+ "alias": {
+ "type": "string"
+ },
+ "isHomeRegion": {
+ "type": "boolean"
+ },
+ "key": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.RelayView": {
+ "type": "object",
+ "properties": {
+ "connector": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "endpoint": {
+ "type": "string"
+ },
+ "events": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "policy": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "ready": {
+ "type": "boolean"
+ },
+ "subscription": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "topic": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "webhook": {
+ "$ref": "#/definitions/oci-portal_internal_service.LogWebhookInfo"
+ }
+ }
+ },
"oci-portal_internal_service.SecuritySettings": {
"type": "object",
"properties": {
@@ -6618,6 +9714,23 @@ const docTemplate = `{
}
}
},
+ "oci-portal_internal_service.TelegramView": {
+ "type": "object",
+ "properties": {
+ "chatId": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "tokenSet": {
+ "type": "boolean"
+ },
+ "tokenTail": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.UpdateCredentialsInput": {
"type": "object",
"required": [
diff --git a/docs/swagger.json b/docs/swagger.json
index 1c98a76..9c2e24d 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -8,6 +8,33 @@
},
"basePath": "/",
"paths": {
+ "/ai/v1/audio/speech": {
+ "post": {
+ "tags": [
+ "AI 网关"
+ ],
+ "summary": "OpenAI Audio Speech 兼容端点(文本转语音)",
+ "parameters": [
+ {
+ "description": "OpenAI audio speech 请求体(model/input 必填,voice 见 xAI Grok Voice 列表,language 缺省 auto;未列字段原样透传)",
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.SpeechRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "音频字节(Content-Type 透传上游,默认 audio/mpeg)",
+ "schema": {
+ "type": "file"
+ }
+ }
+ }
+ }
+ },
"/ai/v1/chat/completions": {
"post": {
"tags": [
@@ -21,16 +48,15 @@
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatRequest"
}
}
],
"responses": {
"200": {
- "description": "OpenAI 兼容响应(流式为 SSE,末尾 data: [DONE])",
+ "description": "OpenAI 兼容响应(非流式;流式为 SSE,末尾 data: [DONE])",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatResponse"
}
}
}
@@ -49,7 +75,7 @@
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.EmbeddingsRequest"
}
}
],
@@ -57,8 +83,7 @@
"200": {
"description": "OpenAI 兼容响应",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.EmbeddingsResponse"
}
}
}
@@ -77,16 +102,15 @@
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.MessagesRequest"
}
}
],
"responses": {
"200": {
- "description": "Anthropic 兼容响应(流式为 SSE)",
+ "description": "Anthropic 兼容响应(非流式;流式为 SSE 事件序列)",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.MessagesResponse"
}
}
}
@@ -102,8 +126,61 @@
"200": {
"description": "OpenAI 兼容 models 列表",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModelList"
+ }
+ }
+ }
+ }
+ },
+ "/ai/v1/moderations": {
+ "post": {
+ "tags": [
+ "AI 网关"
+ ],
+ "summary": "内容审核端点(OCI Guardrails)",
+ "parameters": [
+ {
+ "description": "审核请求体(input 为字符串或字符串数组,单次至多 8 条;model 接受但忽略)",
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationsRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "审核结果(categories/category_scores 为 overall/blocklist/prompt_injection,pii 为扩展字段)",
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationsResponse"
+ }
+ }
+ }
+ }
+ },
+ "/ai/v1/rerank": {
+ "post": {
+ "tags": [
+ "AI 网关"
+ ],
+ "summary": "文档重排端点(Cohere Rerank)",
+ "parameters": [
+ {
+ "description": "重排请求体(model/query/documents 必填,可选 top_n/return_documents)",
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankRequest"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "重排结果(results[].index 指向入参下标)",
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankResponse"
}
}
}
@@ -117,21 +194,20 @@
"summary": "OpenAI Responses 兼容端点",
"parameters": [
{
- "description": "OpenAI responses 请求体(支持 stream;web_search/x_search 服务端工具仅非流式)",
+ "description": "OpenAI responses 请求体(支持 stream;服务端工具 web_search/x_search/code_interpreter/mcp 含流式;未列字段原样透传上游)",
"name": "body",
"in": "body",
"required": true,
"schema": {
- "type": "object"
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespRequest"
}
}
],
"responses": {
"200": {
- "description": "OpenAI 兼容响应(流式为 SSE)",
+ "description": "OpenAI 兼容响应(非流式;流式为 SSE);直通仅建模常用字段,未列字段原样返回",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespResponse"
}
}
}
@@ -152,8 +228,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.aboutResponse"
}
}
}
@@ -174,8 +249,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiModelBlacklist"
}
}
}
@@ -205,8 +279,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemResponse-oci-portal_internal_model_AiModelBlacklist"
}
}
}
@@ -254,8 +327,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiChannel"
}
}
}
@@ -285,8 +357,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.AiChannel"
}
}
}
@@ -377,8 +448,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.AiChannel"
}
}
}
@@ -408,8 +478,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiModelCache"
}
}
}
@@ -430,8 +499,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_AiCallLog"
}
}
}
@@ -452,8 +520,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiKey"
}
}
}
@@ -481,10 +548,9 @@
],
"responses": {
"201": {
- "description": "Created",
+ "description": "key 为明文密钥,仅本次返回",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.aiKeyCreateResponse"
}
}
}
@@ -584,8 +650,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.AiKey"
}
}
}
@@ -606,8 +671,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_AiContentLog"
}
}
}
@@ -628,8 +692,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_aiwire_Model"
}
}
}
@@ -650,8 +713,7 @@
"200": {
"description": "username 与 passwordLoginDisabled",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.credentialsResponse"
}
}
}
@@ -684,10 +746,7 @@
"401": {
"description": "当前密码错误",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -708,8 +767,7 @@
"200": {
"description": "items",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_model_UserIdentity"
}
}
}
@@ -742,10 +800,7 @@
"409": {
"description": "最后一个身份不可解绑",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -778,24 +833,19 @@
"200": {
"description": "token 与 expiresAt",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.tokenResponse"
}
},
"401": {
"description": "凭据错误",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
},
"428": {
"description": "需要两步验证码(totpRequired=true)",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.totpRequiredResponse"
}
}
}
@@ -829,8 +879,7 @@
"200": {
"description": "providers 与 passwordLoginDisabled",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.oauthProvidersResponse"
}
}
}
@@ -861,10 +910,7 @@
"200": {
"description": "url",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.urlResponse"
}
}
}
@@ -935,10 +981,7 @@
"409": {
"description": "未绑定外部身份",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -959,10 +1002,7 @@
"200": {
"description": "新 token 与 expiresAt",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.tokenResponse"
}
}
}
@@ -983,10 +1023,7 @@
"200": {
"description": "enabled",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "boolean"
- }
+ "$ref": "#/definitions/internal_api.enabledResponse"
}
}
}
@@ -1065,19 +1102,13 @@
"200": {
"description": "secret 与 otpauthUri",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.totpSetupResponse"
}
},
"409": {
"description": "已启用",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -1168,8 +1199,7 @@
"200": {
"description": "items 与 total",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_LogEvent"
}
}
}
@@ -1188,10 +1218,12 @@
"summary": "租户配置列表",
"responses": {
"200": {
- "description": "items",
+ "description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ConfigSummary"
+ }
}
}
}
@@ -1221,8 +1253,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.OciConfig"
}
}
}
@@ -1252,8 +1283,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.OciConfig"
}
}
}
@@ -1288,10 +1318,9 @@
],
"responses": {
"200": {
- "description": "OK",
+ "description": "config 与 changes 字段变更对照",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.configChangesResponse"
}
}
}
@@ -1359,8 +1388,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.AuditEventsView"
}
}
}
@@ -1388,10 +1416,9 @@
],
"responses": {
"200": {
- "description": "OK",
+ "description": "raw 为事件原文 JSON",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.rawDetailResponse"
}
}
}
@@ -1421,8 +1448,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
}
}
}
@@ -1486,8 +1515,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolume"
+ }
}
}
}
@@ -1524,8 +1555,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolume"
}
}
}
@@ -1569,8 +1599,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolume"
}
}
}
@@ -1632,8 +1661,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Compartment"
+ }
}
}
}
@@ -1663,8 +1694,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.RegionSubscriptionView"
+ }
}
}
}
@@ -1694,8 +1727,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Compartment"
+ }
}
}
}
@@ -1759,8 +1794,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.CostItem"
+ }
}
}
}
@@ -1790,8 +1827,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityDomain"
+ }
}
}
}
@@ -1827,8 +1866,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityProviderInfo"
+ }
}
}
}
@@ -1871,8 +1912,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityProviderInfo"
}
}
}
@@ -1964,8 +2004,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentityProviderInfo"
}
}
}
@@ -2001,8 +2040,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentitySettingInfo"
}
}
}
@@ -2045,8 +2083,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.IdentitySettingInfo"
}
}
}
@@ -2076,8 +2113,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Image"
+ }
}
}
}
@@ -2114,8 +2153,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Image"
}
}
}
@@ -2145,8 +2183,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
+ }
}
}
}
@@ -2181,10 +2221,9 @@
],
"responses": {
"201": {
- "description": "Created",
+ "description": "部分成功仍 201,errors 为逐台失败信息",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.createInstancesResponse"
}
}
}
@@ -2221,8 +2260,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
}
}
}
@@ -2266,8 +2304,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
}
}
}
@@ -2345,8 +2382,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
}
}
}
@@ -2383,8 +2419,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolumeAttachment"
+ }
}
}
}
@@ -2428,8 +2466,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolumeAttachment"
}
}
}
@@ -2475,8 +2512,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.publicIpResponse"
}
}
}
@@ -2513,8 +2549,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.ConsoleConnection"
+ }
}
}
}
@@ -2558,8 +2596,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.ConsoleConnection"
}
}
}
@@ -2602,11 +2639,10 @@
}
],
"responses": {
- "200": {
- "description": "sessionId 与 wsPath",
+ "201": {
+ "description": "sessionId 与 type",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.webConsoleSessionResponse"
}
}
}
@@ -2652,8 +2688,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.ipv6AddressResponse"
}
}
}
@@ -2731,8 +2766,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.BootVolumeAttachment"
}
}
}
@@ -2769,8 +2803,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.InstanceTraffic"
}
}
}
@@ -2807,8 +2840,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Vnic"
+ }
}
}
}
@@ -2852,8 +2887,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Vnic"
}
}
}
@@ -2890,8 +2924,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.VolumeAttachment"
+ }
}
}
}
@@ -2935,8 +2971,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VolumeAttachment"
}
}
}
@@ -2966,8 +3001,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.LimitValue"
+ }
}
}
}
@@ -2997,8 +3034,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.LimitService"
+ }
}
}
}
@@ -3028,8 +3067,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.RelayView"
}
}
}
@@ -3057,8 +3095,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.RelayView"
}
}
}
@@ -3113,8 +3150,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.logWebhookStatusResponse"
}
}
}
@@ -3142,8 +3178,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.LogWebhookInfo"
}
}
}
@@ -3204,8 +3239,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.NotificationRecipients"
}
}
}
@@ -3248,8 +3282,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.NotificationRecipients"
}
}
}
@@ -3285,8 +3318,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.PasswordPolicyInfo"
+ }
}
}
}
@@ -3338,8 +3373,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.PasswordPolicyInfo"
}
}
}
@@ -3369,8 +3403,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.RegionSubscriptionView"
+ }
}
}
}
@@ -3407,8 +3443,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.RegionSubscriptionView"
+ }
}
}
}
@@ -3442,10 +3480,9 @@
],
"responses": {
"200": {
- "description": "OK",
+ "description": "SAML 元数据 XML(附件下载)",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "file"
}
}
}
@@ -3475,8 +3512,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
+ }
}
}
}
@@ -3513,8 +3552,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
}
}
}
@@ -3551,8 +3589,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
}
}
}
@@ -3596,8 +3633,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityList"
}
}
}
@@ -3659,8 +3695,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.ComputeShape"
+ }
}
}
}
@@ -3705,8 +3743,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SignOnRuleInfo"
}
}
}
@@ -3782,8 +3819,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SignOnRuleInfo"
+ }
}
}
}
@@ -3813,8 +3852,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
+ }
}
}
}
@@ -3851,8 +3892,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
}
}
}
@@ -3889,8 +3929,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
}
}
}
@@ -3934,8 +3973,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.Subnet"
}
}
}
@@ -3997,8 +4035,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SubscriptionInfo"
+ }
}
}
}
@@ -4035,8 +4075,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.SubscriptionDetail"
}
}
}
@@ -4072,8 +4111,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUser"
+ }
}
}
}
@@ -4116,8 +4157,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUser"
}
}
}
@@ -4160,8 +4200,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUserDetail"
}
}
}
@@ -4211,8 +4250,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.TenantUser"
}
}
}
@@ -4287,8 +4325,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.deletedApiKeysResponse"
}
}
}
@@ -4331,8 +4368,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.deletedTotpResponse"
}
}
}
@@ -4373,10 +4409,9 @@
],
"responses": {
"200": {
- "description": "OK",
+ "description": "一次性明文密码",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.passwordResponse"
}
}
}
@@ -4406,8 +4441,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
+ }
}
}
}
@@ -4444,8 +4481,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
}
}
}
@@ -4482,8 +4518,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
}
}
}
@@ -4527,8 +4562,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_oci.VCN"
}
}
}
@@ -4606,8 +4640,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.ipv6StepsResponse"
}
}
}
@@ -4635,10 +4668,9 @@
],
"responses": {
"200": {
- "description": "OK",
+ "description": "config 与 changes 字段变更对照",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.configChangesResponse"
}
}
}
@@ -4718,8 +4750,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.addressResponse"
}
}
}
@@ -4783,8 +4814,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.BlockVolume"
+ }
}
}
}
@@ -4805,8 +4838,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.Overview"
}
}
}
@@ -4827,8 +4859,7 @@
"200": {
"description": "items",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_ProxyView"
}
}
}
@@ -4858,8 +4889,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
}
}
}
@@ -4891,8 +4921,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ImportResult"
}
}
}
@@ -4931,8 +4960,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
}
}
}
@@ -4987,8 +5015,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
}
}
}
@@ -5027,8 +5054,7 @@
"200": {
"description": "usedBy",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.usedByResponse"
}
}
}
@@ -5049,8 +5075,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RegionInfo"
+ }
}
}
}
@@ -5071,8 +5099,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView"
}
}
}
@@ -5111,8 +5138,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView"
}
}
}
@@ -5160,8 +5186,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyEventsView"
}
}
}
@@ -5191,8 +5216,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyEventsView"
}
}
}
@@ -5213,8 +5237,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyTemplateView"
}
}
}
@@ -5358,8 +5381,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.SecuritySettings"
}
}
}
@@ -5389,8 +5411,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.SecuritySettings"
}
}
}
@@ -5411,8 +5432,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TaskSettingsView"
}
}
}
@@ -5442,8 +5462,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TaskSettingsView"
}
}
}
@@ -5464,8 +5483,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TelegramView"
}
}
}
@@ -5495,8 +5513,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_service.TelegramView"
}
}
}
@@ -5535,8 +5552,7 @@
"200": {
"description": "items 与 total",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.pagedResponse-oci-portal_internal_model_SystemLog"
}
}
}
@@ -5559,8 +5575,7 @@
"schema": {
"type": "array",
"items": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5591,8 +5606,7 @@
"201": {
"description": "Created",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5622,8 +5636,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5660,8 +5673,7 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/oci-portal_internal_model.Task"
}
}
}
@@ -5716,8 +5728,10 @@
"200": {
"description": "OK",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.TaskLog"
+ }
}
}
}
@@ -5747,15 +5761,13 @@
"202": {
"description": "Accepted",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.triggerResponse"
}
},
"409": {
"description": "任务正在执行中",
"schema": {
- "type": "object",
- "additionalProperties": true
+ "$ref": "#/definitions/internal_api.errorResponse"
}
}
}
@@ -5792,10 +5804,7 @@
"403": {
"description": "时间戳超窗或证书源非 Oracle 域",
"schema": {
- "type": "object",
- "additionalProperties": {
- "type": "string"
- }
+ "$ref": "#/definitions/internal_api.errorResponse"
}
},
"404": {
@@ -5806,6 +5815,77 @@
}
},
"definitions": {
+ "internal_api.aboutResources": {
+ "type": "object",
+ "properties": {
+ "cpuAvgPercent": {
+ "type": "number"
+ },
+ "dbBytes": {
+ "type": "integer"
+ },
+ "dbEngine": {
+ "type": "string"
+ },
+ "goroutines": {
+ "type": "integer"
+ },
+ "memHeapBytes": {
+ "type": "integer"
+ },
+ "memSysBytes": {
+ "type": "integer"
+ },
+ "numCpu": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.aboutResponse": {
+ "type": "object",
+ "properties": {
+ "buildTime": {
+ "type": "string"
+ },
+ "goVersion": {
+ "type": "string"
+ },
+ "platform": {
+ "type": "string"
+ },
+ "resources": {
+ "$ref": "#/definitions/internal_api.aboutResources"
+ },
+ "startedAt": {
+ "type": "string"
+ },
+ "uptimeSeconds": {
+ "type": "integer"
+ },
+ "version": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.addressResponse": {
+ "type": "object",
+ "properties": {
+ "address": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.aiKeyCreateResponse": {
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiKey"
+ },
+ "key": {
+ "type": "string"
+ }
+ }
+ },
"internal_api.attachBootVolumeRequest": {
"type": "object",
"required": [
@@ -5864,6 +5944,17 @@
}
}
},
+ "internal_api.configChangesResponse": {
+ "type": "object",
+ "properties": {
+ "changes": {
+ "$ref": "#/definitions/oci-portal_internal_service.Changes"
+ },
+ "config": {
+ "$ref": "#/definitions/oci-portal_internal_model.OciConfig"
+ }
+ }
+ },
"internal_api.createConsoleConnectionRequest": {
"type": "object",
"required": [
@@ -5994,6 +6085,23 @@
}
}
},
+ "internal_api.createInstancesResponse": {
+ "type": "object",
+ "properties": {
+ "errors": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "instances": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.Instance"
+ }
+ }
+ }
+ },
"internal_api.createSecurityListRequest": {
"type": "object",
"required": [
@@ -6070,10 +6178,7 @@
"type": "string"
},
"payload": {
- "type": "array",
- "items": {
- "type": "integer"
- }
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
},
"type": {
"type": "string"
@@ -6141,6 +6246,33 @@
}
}
},
+ "internal_api.credentialsResponse": {
+ "type": "object",
+ "properties": {
+ "passwordLoginDisabled": {
+ "type": "boolean"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.deletedApiKeysResponse": {
+ "type": "object",
+ "properties": {
+ "deletedApiKeys": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.deletedTotpResponse": {
+ "type": "object",
+ "properties": {
+ "deletedTotpDevices": {
+ "type": "integer"
+ }
+ }
+ },
"internal_api.enableIPv6Request": {
"type": "object",
"properties": {
@@ -6149,6 +6281,22 @@
}
}
},
+ "internal_api.enabledResponse": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ }
+ }
+ },
+ "internal_api.errorResponse": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ }
+ }
+ },
"internal_api.importRequest": {
"type": "object",
"required": [
@@ -6212,6 +6360,143 @@
}
}
},
+ "internal_api.ipv6AddressResponse": {
+ "type": "object",
+ "properties": {
+ "ipv6Address": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.ipv6StepsResponse": {
+ "type": "object",
+ "properties": {
+ "steps": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.IPv6Step"
+ }
+ }
+ }
+ },
+ "internal_api.itemResponse-oci-portal_internal_model_AiModelBlacklist": {
+ "type": "object",
+ "properties": {
+ "item": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiModelBlacklist"
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_aiwire_Model": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Model"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiChannel": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiChannel"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiKey": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiKey"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiModelBlacklist": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiModelBlacklist"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_AiModelCache": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiModelCache"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_model_UserIdentity": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.UserIdentity"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyChannelView"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_service_NotifyTemplateView": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.NotifyTemplateView"
+ }
+ }
+ }
+ },
+ "internal_api.itemsResponse-oci-portal_internal_service_ProxyView": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
+ }
+ }
+ }
+ },
+ "internal_api.logWebhookStatusResponse": {
+ "type": "object",
+ "properties": {
+ "exists": {
+ "type": "boolean"
+ },
+ "webhook": {
+ "$ref": "#/definitions/oci-portal_internal_service.LogWebhookInfo"
+ }
+ }
+ },
"internal_api.loginRequest": {
"type": "object",
"required": [
@@ -6235,6 +6520,100 @@
}
}
},
+ "internal_api.oauthProvidersResponse": {
+ "type": "object",
+ "properties": {
+ "passwordLoginDisabled": {
+ "type": "boolean"
+ },
+ "providers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ProviderInfo"
+ }
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_AiCallLog": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiCallLog"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_AiContentLog": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.AiContentLog"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_LogEvent": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.LogEvent"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.pagedResponse-oci-portal_internal_model_SystemLog": {
+ "type": "object",
+ "properties": {
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_model.SystemLog"
+ }
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.passwordResponse": {
+ "type": "object",
+ "properties": {
+ "password": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.publicIpResponse": {
+ "type": "object",
+ "properties": {
+ "publicIp": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.rawDetailResponse": {
+ "type": "object",
+ "properties": {
+ "raw": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ }
+ }
+ },
"internal_api.renameRequest": {
"type": "object",
"required": [
@@ -6260,6 +6639,47 @@
}
}
},
+ "internal_api.tokenResponse": {
+ "type": "object",
+ "properties": {
+ "expiresAt": {
+ "type": "string"
+ },
+ "token": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.totpRequiredResponse": {
+ "type": "object",
+ "properties": {
+ "error": {
+ "type": "string"
+ },
+ "totpRequired": {
+ "type": "boolean"
+ }
+ }
+ },
+ "internal_api.totpSetupResponse": {
+ "type": "object",
+ "properties": {
+ "otpauthUri": {
+ "type": "string"
+ },
+ "secret": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.triggerResponse": {
+ "type": "object",
+ "properties": {
+ "triggered": {
+ "type": "boolean"
+ }
+ }
+ },
"internal_api.updateBootVolumeRequest": {
"type": "object",
"properties": {
@@ -6369,10 +6789,7 @@
"type": "string"
},
"payload": {
- "type": "array",
- "items": {
- "type": "integer"
- }
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
},
"status": {
"type": "string"
@@ -6416,6 +6833,1927 @@
}
}
},
+ "internal_api.urlResponse": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string"
+ }
+ }
+ },
+ "internal_api.usedByResponse": {
+ "type": "object",
+ "properties": {
+ "usedBy": {
+ "type": "integer"
+ }
+ }
+ },
+ "internal_api.webConsoleSessionResponse": {
+ "type": "object",
+ "properties": {
+ "sessionId": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthBlock": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "id": {
+ "description": "tool_use",
+ "type": "string"
+ },
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "is_error": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "source": {
+ "description": "image",
+ "allOf": [
+ {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ }
+ ]
+ },
+ "text": {
+ "type": "string"
+ },
+ "tool_use_id": {
+ "description": "tool_result",
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthContent": {
+ "type": "object",
+ "properties": {
+ "blocks": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthBlock"
+ }
+ },
+ "text": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthMessage": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthContent"
+ },
+ "role": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthOutputConfig": {
+ "type": "object",
+ "properties": {
+ "effort": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthTool": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "input_schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnthUsage": {
+ "type": "object",
+ "properties": {
+ "cache_read_input_tokens": {
+ "description": "CacheReadInputTokens 是缓存命中读取数;OCI 隐式缓存无「写入」计数,cache_creation 恒缺",
+ "type": "integer"
+ },
+ "input_tokens": {
+ "type": "integer"
+ },
+ "output_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.AnyJSON": {
+ "type": "object"
+ },
+ "oci-portal_internal_aiwire.ChatMessage": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "role": {
+ "type": "string"
+ },
+ "tool_call_id": {
+ "type": "string"
+ },
+ "tool_calls": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ToolCall"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ChatRequest": {
+ "type": "object",
+ "properties": {
+ "max_completion_tokens": {
+ "type": "integer"
+ },
+ "max_tokens": {
+ "type": "integer"
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatMessage"
+ }
+ },
+ "model": {
+ "type": "string"
+ },
+ "parallel_tool_calls": {
+ "type": "boolean"
+ },
+ "reasoning_effort": {
+ "type": "string"
+ },
+ "response_format": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ResponseFormat"
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "stream_options": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.StreamOptions"
+ },
+ "temperature": {
+ "type": "number"
+ },
+ "tool_choice": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tools": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Tool"
+ }
+ },
+ "top_p": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ChatResponse": {
+ "type": "object",
+ "properties": {
+ "choices": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Choice"
+ }
+ },
+ "created": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Usage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Choice": {
+ "type": "object",
+ "properties": {
+ "finish_reason": {
+ "type": "string"
+ },
+ "index": {
+ "type": "integer"
+ },
+ "message": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ChatMessage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.EmbedUsage": {
+ "type": "object",
+ "properties": {
+ "prompt_tokens": {
+ "type": "integer"
+ },
+ "total_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Embedding": {
+ "type": "object",
+ "properties": {
+ "embedding": {
+ "type": "array",
+ "items": {
+ "type": "number"
+ }
+ },
+ "index": {
+ "type": "integer"
+ },
+ "object": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.EmbeddingsRequest": {
+ "type": "object",
+ "properties": {
+ "dimensions": {
+ "type": "integer"
+ },
+ "encoding_format": {
+ "type": "string"
+ },
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "model": {
+ "type": "string"
+ },
+ "user": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.EmbeddingsResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Embedding"
+ }
+ },
+ "model": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.EmbedUsage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.FunctionCall": {
+ "type": "object",
+ "properties": {
+ "arguments": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.FunctionDef": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "parameters": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.MessagesRequest": {
+ "type": "object",
+ "properties": {
+ "max_tokens": {
+ "type": "integer"
+ },
+ "messages": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthMessage"
+ }
+ },
+ "metadata": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "model": {
+ "type": "string"
+ },
+ "output_config": {
+ "description": "OutputConfig 是 Anthropic 官方输出控制(effort 等);网关映射 effort 到 OCI reasoningEffort。",
+ "allOf": [
+ {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthOutputConfig"
+ }
+ ]
+ },
+ "stop_sequences": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "system": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "temperature": {
+ "type": "number"
+ },
+ "thinking": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tool_choice": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tools": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthTool"
+ }
+ },
+ "top_k": {
+ "type": "integer"
+ },
+ "top_p": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.MessagesResponse": {
+ "type": "object",
+ "properties": {
+ "content": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthBlock"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "role": {
+ "type": "string"
+ },
+ "stop_reason": {
+ "type": "string"
+ },
+ "stop_sequence": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnthUsage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Model": {
+ "type": "object",
+ "properties": {
+ "created": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "owned_by": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModelList": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.Model"
+ }
+ },
+ "object": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationPii": {
+ "type": "object",
+ "properties": {
+ "label": {
+ "type": "string"
+ },
+ "length": {
+ "type": "integer"
+ },
+ "offset": {
+ "type": "integer"
+ },
+ "score": {
+ "type": "number"
+ },
+ "text": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationResult": {
+ "type": "object",
+ "properties": {
+ "categories": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "boolean"
+ }
+ },
+ "category_scores": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "format": "float64"
+ }
+ },
+ "flagged": {
+ "type": "boolean"
+ },
+ "pii": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationPii"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationsRequest": {
+ "type": "object",
+ "properties": {
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "model": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ModerationsResponse": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "results": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.ModerationResult"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.PromptTokensDetails": {
+ "type": "object",
+ "properties": {
+ "cached_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankDocument": {
+ "type": "object",
+ "properties": {
+ "text": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankRequest": {
+ "type": "object",
+ "properties": {
+ "documents": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "model": {
+ "type": "string"
+ },
+ "query": {
+ "type": "string"
+ },
+ "return_documents": {
+ "type": "boolean"
+ },
+ "top_n": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankResponse": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "type": "string"
+ },
+ "results": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankResult"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RerankResult": {
+ "type": "object",
+ "properties": {
+ "document": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RerankDocument"
+ },
+ "index": {
+ "type": "integer"
+ },
+ "relevance_score": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespError": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespInDetails": {
+ "type": "object",
+ "properties": {
+ "cached_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespOutDetails": {
+ "type": "object",
+ "properties": {
+ "reasoning_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespReasoning": {
+ "type": "object",
+ "properties": {
+ "effort": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespRequest": {
+ "type": "object",
+ "properties": {
+ "background": {
+ "type": "boolean"
+ },
+ "conversation": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "input": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "instructions": {
+ "type": "string"
+ },
+ "max_output_tokens": {
+ "type": "integer"
+ },
+ "model": {
+ "type": "string"
+ },
+ "parallel_tool_calls": {
+ "type": "boolean"
+ },
+ "previous_response_id": {
+ "type": "string"
+ },
+ "reasoning": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespReasoning"
+ },
+ "store": {
+ "type": "boolean"
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "temperature": {
+ "type": "number"
+ },
+ "text": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespText"
+ },
+ "tool_choice": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "tools": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespTool"
+ }
+ },
+ "top_p": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespResponse": {
+ "type": "object",
+ "properties": {
+ "created_at": {
+ "type": "integer"
+ },
+ "error": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespError"
+ },
+ "id": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "object": {
+ "type": "string"
+ },
+ "output": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "status": {
+ "type": "string"
+ },
+ "usage": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespUsage"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespText": {
+ "type": "object",
+ "properties": {
+ "format": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespTextFormat"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespTextFormat": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "strict": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespTool": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "parameters": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "strict": {
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.RespUsage": {
+ "type": "object",
+ "properties": {
+ "input_tokens": {
+ "type": "integer"
+ },
+ "input_tokens_details": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespInDetails"
+ },
+ "output_tokens": {
+ "type": "integer"
+ },
+ "output_tokens_details": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.RespOutDetails"
+ },
+ "total_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ResponseFormat": {
+ "type": "object",
+ "properties": {
+ "json_schema": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.SpeechRequest": {
+ "type": "object",
+ "properties": {
+ "input": {
+ "type": "string"
+ },
+ "language": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "response_format": {
+ "type": "string"
+ },
+ "voice": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.StreamOptions": {
+ "type": "object",
+ "properties": {
+ "include_usage": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Tool": {
+ "type": "object",
+ "properties": {
+ "function": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.FunctionDef"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.ToolCall": {
+ "type": "object",
+ "properties": {
+ "function": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.FunctionCall"
+ },
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_aiwire.Usage": {
+ "type": "object",
+ "properties": {
+ "completion_tokens": {
+ "type": "integer"
+ },
+ "prompt_tokens": {
+ "type": "integer"
+ },
+ "prompt_tokens_details": {
+ "description": "PromptTokensDetails 携带缓存命中细分;OCI 为隐式 prompt 缓存,只有读取计数",
+ "allOf": [
+ {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.PromptTokensDetails"
+ }
+ ]
+ },
+ "total_tokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiCallLog": {
+ "type": "object",
+ "properties": {
+ "cachedTokens": {
+ "description": "CachedTokens 是输入中缓存命中(读取)的部分;OCI 隐式缓存无写入计数",
+ "type": "integer"
+ },
+ "channelId": {
+ "type": "integer"
+ },
+ "channelName": {
+ "type": "string"
+ },
+ "clientIp": {
+ "description": "ClientIP 是网关调用方来源 IP(尊重「真实 IP 头」安全设置,与系统日志同源)",
+ "type": "string"
+ },
+ "completionTokens": {
+ "type": "integer"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "endpoint": {
+ "description": "openai / anthropic",
+ "type": "string"
+ },
+ "errMsg": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "keyId": {
+ "type": "integer"
+ },
+ "keyName": {
+ "type": "string"
+ },
+ "latencyMs": {
+ "type": "integer"
+ },
+ "model": {
+ "type": "string"
+ },
+ "promptTokens": {
+ "type": "integer"
+ },
+ "retries": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "integer"
+ },
+ "stream": {
+ "type": "boolean"
+ },
+ "totalTokens": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiChannel": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "disabledUntil": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "failCount": {
+ "description": "FailCount 连续失败计数;达阈值后 DisabledUntil 指数退避熔断,成功/探测通过复位",
+ "type": "integer"
+ },
+ "group": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastProbeAt": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "ociConfigId": {
+ "type": "integer"
+ },
+ "priority": {
+ "type": "integer"
+ },
+ "probeError": {
+ "type": "string"
+ },
+ "probeStatus": {
+ "description": "ok / no_service / no_quota / error",
+ "type": "string"
+ },
+ "region": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ },
+ "weight": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiContentLog": {
+ "type": "object",
+ "properties": {
+ "callLogId": {
+ "description": "CallLogID 关联同次调用的 AiCallLog,调用日志详情据此反查正文",
+ "type": "integer"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "endpoint": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "keyId": {
+ "type": "integer"
+ },
+ "keyName": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "requestBody": {
+ "description": "RequestBody / ResponseBody 是截断后的正文 JSON;\n64KB 截断恰在 MySQL TEXT 上限(65535B)边界,size 上探一档 → MEDIUMTEXT",
+ "type": "string"
+ },
+ "responseBody": {
+ "type": "string"
+ },
+ "stream": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiKey": {
+ "type": "object",
+ "properties": {
+ "contentLogUntil": {
+ "description": "ContentLogUntil 是内容日志开启截止时间;nil = 永关(默认,红线),\n开启必须限时,到期自动停写",
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "group": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastUsedAt": {
+ "type": "string"
+ },
+ "models": {
+ "description": "Models 是模型白名单(精确匹配模型名);空 = 不限,非空时网关仅放行列表内模型",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "name": {
+ "type": "string"
+ },
+ "tail": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiModelBlacklist": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.AiModelCache": {
+ "type": "object",
+ "properties": {
+ "capability": {
+ "type": "string"
+ },
+ "channelId": {
+ "type": "integer"
+ },
+ "deprecatedAt": {
+ "description": "DeprecatedAt 是 OCI 宣布的模型弃用时间;nil 表示未宣布。\n弃用后仍可调用,直到 RetiredAt(按需推理退役,同步层已剔除过期项)。",
+ "type": "string"
+ },
+ "modelOcid": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "retiredAt": {
+ "type": "string"
+ },
+ "syncedAt": {
+ "type": "string"
+ },
+ "vendor": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.LogEvent": {
+ "type": "object",
+ "properties": {
+ "eventTime": {
+ "type": "string"
+ },
+ "eventType": {
+ "description": "异步解析回填,如 com.oraclecloud.ComputeApi.TerminateInstance",
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "messageId": {
+ "description": "幂等键(X-OCI-NS-MessageId)",
+ "type": "string"
+ },
+ "ociConfigId": {
+ "description": "经 secret 反查归属租户",
+ "type": "integer"
+ },
+ "payload": {
+ "description": "防御上限 256KB 超 MySQL TEXT(64KB),size 上探一档 → MEDIUMTEXT;PG/SQLite 仍为 text",
+ "type": "string"
+ },
+ "processed": {
+ "type": "boolean"
+ },
+ "receivedAt": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "sourceIp": {
+ "description": "异步解析回填,Audit 事件的发起方 IP",
+ "type": "string"
+ },
+ "truncated": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_model.OciConfig": {
+ "type": "object",
+ "properties": {
+ "accountType": {
+ "type": "string"
+ },
+ "alias": {
+ "type": "string"
+ },
+ "aliveStatus": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "fingerprint": {
+ "type": "string"
+ },
+ "group": {
+ "description": "Group 是面板内的自定义分组标签,空串表示未分组;\n列名避开 SQL 保留字 GROUP",
+ "type": "string"
+ },
+ "homeRegionKey": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastError": {
+ "type": "string"
+ },
+ "lastVerifiedAt": {
+ "type": "string"
+ },
+ "multiCompartment": {
+ "type": "boolean"
+ },
+ "multiRegion": {
+ "description": "多区域 / 多区间支持:开启后订阅区域与 compartment 列表入库缓存,\n供筛选器免实时调 OCI;未开启的租户筛选器锁定主区域 / 根区间。",
+ "type": "boolean"
+ },
+ "paymentModel": {
+ "type": "string"
+ },
+ "promotionAmount": {
+ "type": "number"
+ },
+ "promotionExpires": {
+ "type": "string"
+ },
+ "promotionStatus": {
+ "type": "string"
+ },
+ "proxyId": {
+ "description": "ProxyID 关联出站代理,nil 表示直连;该租户全部 SDK 调用经此代理",
+ "type": "integer"
+ },
+ "region": {
+ "type": "string"
+ },
+ "subscriptionId": {
+ "type": "string"
+ },
+ "subscriptionTier": {
+ "type": "string"
+ },
+ "tenancyName": {
+ "type": "string"
+ },
+ "tenancyOcid": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ },
+ "userOcid": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.SystemLog": {
+ "type": "object",
+ "properties": {
+ "clientIp": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "durationMs": {
+ "type": "integer"
+ },
+ "errMsg": {
+ "description": "ErrMsg 仅失败请求(\u003e=400)存响应的 error 文案,便于免翻服务端日志定位原因",
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "method": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "status": {
+ "type": "integer"
+ },
+ "userAgent": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.Task": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "cronExpr": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastError": {
+ "type": "string"
+ },
+ "lastRunAt": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "payload": {
+ "type": "string"
+ },
+ "runCount": {
+ "type": "integer"
+ },
+ "status": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "updatedAt": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_model.TaskLog": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "durationMs": {
+ "type": "integer"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "message": {
+ "type": "string"
+ },
+ "success": {
+ "type": "boolean"
+ },
+ "taskId": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_model.UserIdentity": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "display": {
+ "description": "展示名:邮箱 / GitHub login",
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "provider": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.AuditEvent": {
+ "type": "object",
+ "properties": {
+ "compartmentName": {
+ "type": "string"
+ },
+ "eventId": {
+ "type": "string"
+ },
+ "eventName": {
+ "type": "string"
+ },
+ "eventTime": {
+ "type": "string"
+ },
+ "ipAddress": {
+ "type": "string"
+ },
+ "principalName": {
+ "type": "string"
+ },
+ "raw": {
+ "$ref": "#/definitions/oci-portal_internal_aiwire.AnyJSON"
+ },
+ "requestAction": {
+ "type": "string"
+ },
+ "requestPath": {
+ "type": "string"
+ },
+ "resourceName": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.BlockVolume": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "sizeInGBs": {
+ "type": "integer"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vpusPerGB": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.BootVolume": {
+ "type": "object",
+ "properties": {
+ "attachedInstanceId": {
+ "type": "string"
+ },
+ "attachedInstanceName": {
+ "type": "string"
+ },
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "compartmentId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "imageId": {
+ "type": "string"
+ },
+ "imageName": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "sizeInGBs": {
+ "type": "integer"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vpusPerGB": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.BootVolumeAttachment": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "bootVolumeId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Compartment": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "parentId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.ComputeShape": {
+ "type": "object",
+ "properties": {
+ "billingType": {
+ "description": "ALWAYS_FREE / LIMITED_FREE / PAID",
+ "type": "string"
+ },
+ "gpus": {
+ "type": "integer"
+ },
+ "isFlexible": {
+ "type": "boolean"
+ },
+ "memoryInGBs": {
+ "type": "number"
+ },
+ "memoryMaxGBs": {
+ "type": "number"
+ },
+ "memoryMinGBs": {
+ "type": "number"
+ },
+ "name": {
+ "type": "string"
+ },
+ "ocpus": {
+ "type": "number"
+ },
+ "ocpusMax": {
+ "type": "number"
+ },
+ "ocpusMin": {
+ "type": "number"
+ },
+ "processorDescription": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.ConsoleConnection": {
+ "type": "object",
+ "properties": {
+ "connectionString": {
+ "description": "串口控制台 SSH 命令",
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "vncConnectionString": {
+ "description": "VNC over SSH 隧道命令",
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.CostItem": {
+ "type": "object",
+ "properties": {
+ "computedAmount": {
+ "type": "number"
+ },
+ "computedQuantity": {
+ "type": "number"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "groupValue": {
+ "type": "string"
+ },
+ "timeStart": {
+ "type": "string"
+ },
+ "unit": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IPv6Step": {
+ "type": "object",
+ "properties": {
+ "detail": {
+ "type": "string"
+ },
+ "status": {
+ "description": "done / skipped / failed",
+ "type": "string"
+ },
+ "step": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IdentityDomain": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "homeRegion": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "licenseType": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IdentityProviderInfo": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "jitEnabled": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "partnerProviderId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.IdentitySettingInfo": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "primaryEmailRequired": {
+ "description": "用户需要提供主电子邮件地址:开启后创建用户 / JIT 预配必须带邮箱",
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Image": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "operatingSystem": {
+ "type": "string"
+ },
+ "operatingSystemVersion": {
+ "type": "string"
+ },
+ "sizeInMBs": {
+ "type": "integer"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Instance": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "compartmentId": {
+ "type": "string"
+ },
+ "definedTags": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": {}
+ }
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "freeformTags": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "imageId": {
+ "type": "string"
+ },
+ "ipv6Addresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "memoryInGBs": {
+ "type": "number"
+ },
+ "ocpus": {
+ "type": "number"
+ },
+ "privateIp": {
+ "type": "string"
+ },
+ "publicIp": {
+ "type": "string"
+ },
+ "region": {
+ "type": "string"
+ },
+ "shape": {
+ "type": "string"
+ },
+ "subnetId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.InstanceTraffic": {
+ "type": "object",
+ "properties": {
+ "inboundBytes": {
+ "type": "number"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "outboundBytes": {
+ "type": "number"
+ },
+ "vnics": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.VnicTraffic"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_oci.LimitService": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.LimitValue": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "available": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "scopeType": {
+ "type": "string"
+ },
+ "used": {
+ "type": "integer"
+ },
+ "value": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.NotificationRecipients": {
+ "type": "object",
+ "properties": {
+ "recipients": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "testModeEnabled": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_oci.PasswordPolicyInfo": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "minLength": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "numPasswordsInHistory": {
+ "type": "integer"
+ },
+ "passwordExpiresAfter": {
+ "type": "integer"
+ },
+ "passwordStrength": {
+ "type": "string"
+ },
+ "priority": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.PromotionInfo": {
+ "type": "object",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "currencyUnit": {
+ "type": "string"
+ },
+ "duration": {
+ "type": "integer"
+ },
+ "durationUnit": {
+ "type": "string"
+ },
+ "isIntentToPay": {
+ "type": "boolean"
+ },
+ "status": {
+ "type": "string"
+ },
+ "timeExpired": {
+ "type": "string"
+ },
+ "timeStarted": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.RegionInfo": {
+ "type": "object",
+ "properties": {
+ "alias": {
+ "type": "string"
+ },
+ "key": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.RelayResource": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "state": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.SecurityList": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "egressRules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityRule"
+ }
+ },
+ "id": {
+ "type": "string"
+ },
+ "ingressRules": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.SecurityRule"
+ }
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vcnId": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_oci.SecurityRule": {
"type": "object",
"properties": {
@@ -6449,6 +8787,379 @@
}
}
},
+ "oci-portal_internal_oci.SignOnRuleInfo": {
+ "type": "object",
+ "properties": {
+ "authenticationFactor": {
+ "type": "string"
+ },
+ "builtIn": {
+ "type": "boolean"
+ },
+ "conditionAttribute": {
+ "type": "string"
+ },
+ "conditionValue": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "sequence": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Subnet": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "cidrBlock": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "dnsLabel": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "ipv6CidrBlock": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "prohibitPublicIp": {
+ "type": "boolean"
+ },
+ "routeTableId": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vcnId": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.SubscriptionDetail": {
+ "type": "object",
+ "properties": {
+ "classicSubscriptionId": {
+ "type": "string"
+ },
+ "cloudAmountCurrency": {
+ "type": "string"
+ },
+ "csiNumber": {
+ "type": "string"
+ },
+ "customerCountryCode": {
+ "type": "string"
+ },
+ "endDate": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "isGovernmentSubscription": {
+ "type": "boolean"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "paymentModel": {
+ "type": "string"
+ },
+ "programType": {
+ "type": "string"
+ },
+ "promotions": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.PromotionInfo"
+ }
+ },
+ "regionAssignment": {
+ "type": "string"
+ },
+ "serviceName": {
+ "type": "string"
+ },
+ "startDate": {
+ "type": "string"
+ },
+ "subscriptionTier": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "timeUpdated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.SubscriptionInfo": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "serviceName": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "timeUpdated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.TenantUser": {
+ "type": "object",
+ "properties": {
+ "description": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "emailVerified": {
+ "type": "boolean"
+ },
+ "id": {
+ "type": "string"
+ },
+ "isCurrentUser": {
+ "type": "boolean"
+ },
+ "lastLoginTime": {
+ "type": "string"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "mfaActivated": {
+ "type": "boolean"
+ },
+ "name": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.TenantUserDetail": {
+ "type": "object",
+ "properties": {
+ "familyName": {
+ "type": "string"
+ },
+ "givenName": {
+ "type": "string"
+ },
+ "inAdminGroup": {
+ "type": "boolean"
+ },
+ "inDomain": {
+ "type": "boolean"
+ },
+ "isDomainAdmin": {
+ "type": "boolean"
+ }
+ }
+ },
+ "oci-portal_internal_oci.TrafficPoint": {
+ "type": "object",
+ "properties": {
+ "bytes": {
+ "type": "number"
+ },
+ "timestamp": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.VCN": {
+ "type": "object",
+ "properties": {
+ "cidrBlocks": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "compartmentId": {
+ "type": "string"
+ },
+ "defaultRouteTableId": {
+ "type": "string"
+ },
+ "defaultSecurityListId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "dnsLabel": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "ipv6CidrBlocks": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.Vnic": {
+ "type": "object",
+ "properties": {
+ "attachmentId": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "ipv6Addresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "isPrimary": {
+ "type": "boolean"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "privateIp": {
+ "type": "string"
+ },
+ "publicIp": {
+ "type": "string"
+ },
+ "subnetId": {
+ "type": "string"
+ },
+ "subnetName": {
+ "type": "string"
+ },
+ "timeCreated": {
+ "type": "string"
+ },
+ "vnicId": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.VnicTraffic": {
+ "type": "object",
+ "properties": {
+ "inbound": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.TrafficPoint"
+ }
+ },
+ "inboundBytes": {
+ "type": "number"
+ },
+ "outbound": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.TrafficPoint"
+ }
+ },
+ "outboundBytes": {
+ "type": "number"
+ },
+ "vnicId": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_oci.VolumeAttachment": {
+ "type": "object",
+ "properties": {
+ "availabilityDomain": {
+ "type": "string"
+ },
+ "device": {
+ "type": "string"
+ },
+ "displayName": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "instanceId": {
+ "type": "string"
+ },
+ "isReadOnly": {
+ "type": "boolean"
+ },
+ "lifecycleState": {
+ "type": "string"
+ },
+ "volumeId": {
+ "type": "string"
+ },
+ "volumeName": {
+ "description": "卷本身的名称(attachment 名是自动生成的)",
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.AuditEventsView": {
+ "type": "object",
+ "properties": {
+ "cursor": {
+ "type": "string"
+ },
+ "exhausted": {
+ "type": "boolean"
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_oci.AuditEvent"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_service.Changes": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.ChannelInput": {
"type": "object",
"properties": {
@@ -6475,6 +9186,150 @@
}
}
},
+ "oci-portal_internal_service.ConfigSummary": {
+ "type": "object",
+ "properties": {
+ "accountType": {
+ "type": "string"
+ },
+ "alias": {
+ "type": "string"
+ },
+ "aliveStatus": {
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "group": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "lastError": {
+ "type": "string"
+ },
+ "lastVerifiedAt": {
+ "type": "string"
+ },
+ "multiCompartment": {
+ "type": "boolean"
+ },
+ "multiRegion": {
+ "type": "boolean"
+ },
+ "proxyId": {
+ "type": "integer"
+ },
+ "proxyName": {
+ "description": "ProxyName 由 List 按关联填充,供表格代理列 hover 展示",
+ "type": "string"
+ },
+ "region": {
+ "type": "string"
+ },
+ "tenancyName": {
+ "type": "string"
+ },
+ "tenancyOcid": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.ImportFail": {
+ "type": "object",
+ "properties": {
+ "line": {
+ "type": "string"
+ },
+ "lineNo": {
+ "type": "integer"
+ },
+ "reason": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.ImportResult": {
+ "type": "object",
+ "properties": {
+ "created": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ProxyView"
+ }
+ },
+ "failed": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.ImportFail"
+ }
+ }
+ }
+ },
+ "oci-portal_internal_service.LogWebhookInfo": {
+ "type": "object",
+ "properties": {
+ "createdAt": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "secret": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.NotifyChannelView": {
+ "type": "object",
+ "properties": {
+ "bodyTemplate": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "from": {
+ "type": "string"
+ },
+ "host": {
+ "description": "smtp",
+ "type": "string"
+ },
+ "port": {
+ "type": "integer"
+ },
+ "secretSet": {
+ "description": "密文字段状态(ntfy token / bark device key / smtp password)",
+ "type": "boolean"
+ },
+ "secretTail": {
+ "type": "string"
+ },
+ "server": {
+ "description": "ntfy / bark 共用 Server",
+ "type": "string"
+ },
+ "to": {
+ "type": "string"
+ },
+ "topic": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "url": {
+ "description": "webhook",
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.NotifyEventsView": {
"type": "object",
"properties": {
@@ -6516,6 +9371,30 @@
}
}
},
+ "oci-portal_internal_service.NotifyTemplateView": {
+ "type": "object",
+ "properties": {
+ "defaultTemplate": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string"
+ },
+ "label": {
+ "type": "string"
+ },
+ "template": {
+ "description": "Template 是自定义模板;空串表示未自定义(按默认发送)",
+ "type": "string"
+ },
+ "vars": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ },
"oci-portal_internal_service.OAuthProvidersView": {
"type": "object",
"properties": {
@@ -6548,6 +9427,128 @@
}
}
},
+ "oci-portal_internal_service.Overview": {
+ "type": "object",
+ "properties": {
+ "check": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewCheck"
+ },
+ "cost": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewCost"
+ },
+ "tasks": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewTasks"
+ },
+ "tenants": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewTenants"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewCheck": {
+ "type": "object",
+ "properties": {
+ "coveredConfigs": {
+ "type": "integer"
+ },
+ "hasActiveTask": {
+ "type": "boolean"
+ },
+ "instanceCount": {
+ "type": "integer"
+ },
+ "lastCheckedAt": {
+ "type": "string"
+ },
+ "totalConfigs": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewCost": {
+ "type": "object",
+ "properties": {
+ "coveredConfigs": {
+ "type": "integer"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "days": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/oci-portal_internal_service.OverviewCostDay"
+ }
+ },
+ "hasActiveTask": {
+ "type": "boolean"
+ },
+ "total": {
+ "type": "number"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewCostDay": {
+ "type": "object",
+ "properties": {
+ "amount": {
+ "type": "number"
+ },
+ "day": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewTasks": {
+ "type": "object",
+ "properties": {
+ "active": {
+ "type": "integer"
+ },
+ "cost": {
+ "type": "integer"
+ },
+ "healthCheck": {
+ "type": "integer"
+ },
+ "snatch": {
+ "type": "integer"
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_service.OverviewTenants": {
+ "type": "object",
+ "properties": {
+ "alive": {
+ "type": "integer"
+ },
+ "byType": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer"
+ }
+ },
+ "dead": {
+ "type": "integer"
+ },
+ "total": {
+ "type": "integer"
+ }
+ }
+ },
+ "oci-portal_internal_service.ProviderInfo": {
+ "type": "object",
+ "properties": {
+ "displayName": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.ProxyInput": {
"type": "object",
"required": [
@@ -6576,6 +9577,101 @@
}
}
},
+ "oci-portal_internal_service.ProxyView": {
+ "type": "object",
+ "properties": {
+ "city": {
+ "type": "string"
+ },
+ "country": {
+ "description": "Country / City 为出口实测地区;GeoAt 空串表示尚未探测(前端显示「检测中」)",
+ "type": "string"
+ },
+ "createdAt": {
+ "type": "string"
+ },
+ "geoAt": {
+ "type": "string"
+ },
+ "host": {
+ "type": "string"
+ },
+ "id": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "passwordSet": {
+ "type": "boolean"
+ },
+ "port": {
+ "type": "integer"
+ },
+ "type": {
+ "type": "string"
+ },
+ "usedBy": {
+ "description": "UsedBy 为关联此代理的租户数,前端据此提示删除约束",
+ "type": "integer"
+ },
+ "username": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.RegionSubscriptionView": {
+ "type": "object",
+ "properties": {
+ "alias": {
+ "type": "string"
+ },
+ "isHomeRegion": {
+ "type": "boolean"
+ },
+ "key": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "status": {
+ "type": "string"
+ }
+ }
+ },
+ "oci-portal_internal_service.RelayView": {
+ "type": "object",
+ "properties": {
+ "connector": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "endpoint": {
+ "type": "string"
+ },
+ "events": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "policy": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "ready": {
+ "type": "boolean"
+ },
+ "subscription": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "topic": {
+ "$ref": "#/definitions/oci-portal_internal_oci.RelayResource"
+ },
+ "webhook": {
+ "$ref": "#/definitions/oci-portal_internal_service.LogWebhookInfo"
+ }
+ }
+ },
"oci-portal_internal_service.SecuritySettings": {
"type": "object",
"properties": {
@@ -6611,6 +9707,23 @@
}
}
},
+ "oci-portal_internal_service.TelegramView": {
+ "type": "object",
+ "properties": {
+ "chatId": {
+ "type": "string"
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "tokenSet": {
+ "type": "boolean"
+ },
+ "tokenTail": {
+ "type": "string"
+ }
+ }
+ },
"oci-portal_internal_service.UpdateCredentialsInput": {
"type": "object",
"required": [
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index 636a6c5..51f46d9 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -1,5 +1,51 @@
basePath: /
definitions:
+ internal_api.aboutResources:
+ properties:
+ cpuAvgPercent:
+ type: number
+ dbBytes:
+ type: integer
+ dbEngine:
+ type: string
+ goroutines:
+ type: integer
+ memHeapBytes:
+ type: integer
+ memSysBytes:
+ type: integer
+ numCpu:
+ type: integer
+ type: object
+ internal_api.aboutResponse:
+ properties:
+ buildTime:
+ type: string
+ goVersion:
+ type: string
+ platform:
+ type: string
+ resources:
+ $ref: '#/definitions/internal_api.aboutResources'
+ startedAt:
+ type: string
+ uptimeSeconds:
+ type: integer
+ version:
+ type: string
+ type: object
+ internal_api.addressResponse:
+ properties:
+ address:
+ type: string
+ type: object
+ internal_api.aiKeyCreateResponse:
+ properties:
+ item:
+ $ref: '#/definitions/oci-portal_internal_model.AiKey'
+ key:
+ type: string
+ type: object
internal_api.attachBootVolumeRequest:
properties:
bootVolumeId:
@@ -38,6 +84,13 @@ definitions:
required:
- volumeId
type: object
+ internal_api.configChangesResponse:
+ properties:
+ changes:
+ $ref: '#/definitions/oci-portal_internal_service.Changes'
+ config:
+ $ref: '#/definitions/oci-portal_internal_model.OciConfig'
+ type: object
internal_api.createConsoleConnectionRequest:
properties:
region:
@@ -126,6 +179,17 @@ definitions:
- displayName
- shape
type: object
+ internal_api.createInstancesResponse:
+ properties:
+ errors:
+ items:
+ type: string
+ type: array
+ instances:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.Instance'
+ type: array
+ type: object
internal_api.createSecurityListRequest:
properties:
displayName:
@@ -174,9 +238,7 @@ definitions:
name:
type: string
payload:
- items:
- type: integer
- type: array
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
type:
type: string
required:
@@ -226,11 +288,38 @@ definitions:
- cidrBlock
- displayName
type: object
+ internal_api.credentialsResponse:
+ properties:
+ passwordLoginDisabled:
+ type: boolean
+ username:
+ type: string
+ type: object
+ internal_api.deletedApiKeysResponse:
+ properties:
+ deletedApiKeys:
+ type: integer
+ type: object
+ internal_api.deletedTotpResponse:
+ properties:
+ deletedTotpDevices:
+ type: integer
+ type: object
internal_api.enableIPv6Request:
properties:
region:
type: string
type: object
+ internal_api.enabledResponse:
+ properties:
+ enabled:
+ type: boolean
+ type: object
+ internal_api.errorResponse:
+ properties:
+ error:
+ type: string
+ type: object
internal_api.importRequest:
properties:
alias:
@@ -274,6 +363,93 @@ definitions:
required:
- action
type: object
+ internal_api.ipv6AddressResponse:
+ properties:
+ ipv6Address:
+ type: string
+ type: object
+ internal_api.ipv6StepsResponse:
+ properties:
+ steps:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.IPv6Step'
+ type: array
+ type: object
+ internal_api.itemResponse-oci-portal_internal_model_AiModelBlacklist:
+ properties:
+ item:
+ $ref: '#/definitions/oci-portal_internal_model.AiModelBlacklist'
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_aiwire_Model:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.Model'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_model_AiChannel:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.AiChannel'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_model_AiKey:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.AiKey'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_model_AiModelBlacklist:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.AiModelBlacklist'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_model_AiModelCache:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.AiModelCache'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_model_UserIdentity:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.UserIdentity'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.NotifyChannelView'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_service_NotifyTemplateView:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.NotifyTemplateView'
+ type: array
+ type: object
+ internal_api.itemsResponse-oci-portal_internal_service_ProxyView:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.ProxyView'
+ type: array
+ type: object
+ internal_api.logWebhookStatusResponse:
+ properties:
+ exists:
+ type: boolean
+ webhook:
+ $ref: '#/definitions/oci-portal_internal_service.LogWebhookInfo'
+ type: object
internal_api.loginRequest:
properties:
password:
@@ -291,6 +467,66 @@ definitions:
- password
- username
type: object
+ internal_api.oauthProvidersResponse:
+ properties:
+ passwordLoginDisabled:
+ type: boolean
+ providers:
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.ProviderInfo'
+ type: array
+ type: object
+ internal_api.pagedResponse-oci-portal_internal_model_AiCallLog:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.AiCallLog'
+ type: array
+ total:
+ type: integer
+ type: object
+ internal_api.pagedResponse-oci-portal_internal_model_AiContentLog:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.AiContentLog'
+ type: array
+ total:
+ type: integer
+ type: object
+ internal_api.pagedResponse-oci-portal_internal_model_LogEvent:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.LogEvent'
+ type: array
+ total:
+ type: integer
+ type: object
+ internal_api.pagedResponse-oci-portal_internal_model_SystemLog:
+ properties:
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.SystemLog'
+ type: array
+ total:
+ type: integer
+ type: object
+ internal_api.passwordResponse:
+ properties:
+ password:
+ type: string
+ type: object
+ internal_api.publicIpResponse:
+ properties:
+ publicIp:
+ type: string
+ type: object
+ internal_api.rawDetailResponse:
+ properties:
+ raw:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ type: object
internal_api.renameRequest:
properties:
displayName:
@@ -307,6 +543,32 @@ definitions:
required:
- regionKey
type: object
+ internal_api.tokenResponse:
+ properties:
+ expiresAt:
+ type: string
+ token:
+ type: string
+ type: object
+ internal_api.totpRequiredResponse:
+ properties:
+ error:
+ type: string
+ totpRequired:
+ type: boolean
+ type: object
+ internal_api.totpSetupResponse:
+ properties:
+ otpauthUri:
+ type: string
+ secret:
+ type: string
+ type: object
+ internal_api.triggerResponse:
+ properties:
+ triggered:
+ type: boolean
+ type: object
internal_api.updateBootVolumeRequest:
properties:
displayName:
@@ -379,9 +641,7 @@ definitions:
name:
type: string
payload:
- items:
- type: integer
- type: array
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
status:
type: string
type: object
@@ -409,6 +669,1277 @@ definitions:
grantDomainAdmin:
type: boolean
type: object
+ internal_api.urlResponse:
+ properties:
+ url:
+ type: string
+ type: object
+ internal_api.usedByResponse:
+ properties:
+ usedBy:
+ type: integer
+ type: object
+ internal_api.webConsoleSessionResponse:
+ properties:
+ sessionId:
+ type: string
+ type:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.AnthBlock:
+ properties:
+ content:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ id:
+ description: tool_use
+ type: string
+ input:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ is_error:
+ type: boolean
+ name:
+ type: string
+ source:
+ allOf:
+ - $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ description: image
+ text:
+ type: string
+ tool_use_id:
+ description: tool_result
+ type: string
+ type:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.AnthContent:
+ properties:
+ blocks:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnthBlock'
+ type: array
+ text:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.AnthMessage:
+ properties:
+ content:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnthContent'
+ role:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.AnthOutputConfig:
+ properties:
+ effort:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.AnthTool:
+ properties:
+ description:
+ type: string
+ input_schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ name:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.AnthUsage:
+ properties:
+ cache_read_input_tokens:
+ description: CacheReadInputTokens 是缓存命中读取数;OCI 隐式缓存无「写入」计数,cache_creation
+ 恒缺
+ type: integer
+ input_tokens:
+ type: integer
+ output_tokens:
+ type: integer
+ type: object
+ oci-portal_internal_aiwire.AnyJSON:
+ type: object
+ oci-portal_internal_aiwire.ChatMessage:
+ properties:
+ content:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ role:
+ type: string
+ tool_call_id:
+ type: string
+ tool_calls:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ToolCall'
+ type: array
+ type: object
+ oci-portal_internal_aiwire.ChatRequest:
+ properties:
+ max_completion_tokens:
+ type: integer
+ max_tokens:
+ type: integer
+ messages:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ChatMessage'
+ type: array
+ model:
+ type: string
+ parallel_tool_calls:
+ type: boolean
+ reasoning_effort:
+ type: string
+ response_format:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ResponseFormat'
+ stream:
+ type: boolean
+ stream_options:
+ $ref: '#/definitions/oci-portal_internal_aiwire.StreamOptions'
+ temperature:
+ type: number
+ tool_choice:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ tools:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.Tool'
+ type: array
+ top_p:
+ type: number
+ type: object
+ oci-portal_internal_aiwire.ChatResponse:
+ properties:
+ choices:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.Choice'
+ type: array
+ created:
+ type: integer
+ id:
+ type: string
+ model:
+ type: string
+ object:
+ type: string
+ usage:
+ $ref: '#/definitions/oci-portal_internal_aiwire.Usage'
+ type: object
+ oci-portal_internal_aiwire.Choice:
+ properties:
+ finish_reason:
+ type: string
+ index:
+ type: integer
+ message:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ChatMessage'
+ type: object
+ oci-portal_internal_aiwire.EmbedUsage:
+ properties:
+ prompt_tokens:
+ type: integer
+ total_tokens:
+ type: integer
+ type: object
+ oci-portal_internal_aiwire.Embedding:
+ properties:
+ embedding:
+ items:
+ type: number
+ type: array
+ index:
+ type: integer
+ object:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.EmbeddingsRequest:
+ properties:
+ dimensions:
+ type: integer
+ encoding_format:
+ type: string
+ input:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ model:
+ type: string
+ user:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.EmbeddingsResponse:
+ properties:
+ data:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.Embedding'
+ type: array
+ model:
+ type: string
+ object:
+ type: string
+ usage:
+ $ref: '#/definitions/oci-portal_internal_aiwire.EmbedUsage'
+ type: object
+ oci-portal_internal_aiwire.FunctionCall:
+ properties:
+ arguments:
+ type: string
+ name:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.FunctionDef:
+ properties:
+ description:
+ type: string
+ name:
+ type: string
+ parameters:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ type: object
+ oci-portal_internal_aiwire.MessagesRequest:
+ properties:
+ max_tokens:
+ type: integer
+ messages:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnthMessage'
+ type: array
+ metadata:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ model:
+ type: string
+ output_config:
+ allOf:
+ - $ref: '#/definitions/oci-portal_internal_aiwire.AnthOutputConfig'
+ description: OutputConfig 是 Anthropic 官方输出控制(effort 等);网关映射 effort 到 OCI reasoningEffort。
+ stop_sequences:
+ items:
+ type: string
+ type: array
+ stream:
+ type: boolean
+ system:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ temperature:
+ type: number
+ thinking:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ tool_choice:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ tools:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnthTool'
+ type: array
+ top_k:
+ type: integer
+ top_p:
+ type: number
+ type: object
+ oci-portal_internal_aiwire.MessagesResponse:
+ properties:
+ content:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnthBlock'
+ type: array
+ id:
+ type: string
+ model:
+ type: string
+ role:
+ type: string
+ stop_reason:
+ type: string
+ stop_sequence:
+ type: string
+ type:
+ type: string
+ usage:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnthUsage'
+ type: object
+ oci-portal_internal_aiwire.Model:
+ properties:
+ created:
+ type: integer
+ id:
+ type: string
+ object:
+ type: string
+ owned_by:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.ModelList:
+ properties:
+ data:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.Model'
+ type: array
+ object:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.ModerationPii:
+ properties:
+ label:
+ type: string
+ length:
+ type: integer
+ offset:
+ type: integer
+ score:
+ type: number
+ text:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.ModerationResult:
+ properties:
+ categories:
+ additionalProperties:
+ type: boolean
+ type: object
+ category_scores:
+ additionalProperties:
+ format: float64
+ type: number
+ type: object
+ flagged:
+ type: boolean
+ pii:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ModerationPii'
+ type: array
+ type: object
+ oci-portal_internal_aiwire.ModerationsRequest:
+ properties:
+ input:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ model:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.ModerationsResponse:
+ properties:
+ id:
+ type: string
+ model:
+ type: string
+ results:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ModerationResult'
+ type: array
+ type: object
+ oci-portal_internal_aiwire.PromptTokensDetails:
+ properties:
+ cached_tokens:
+ type: integer
+ type: object
+ oci-portal_internal_aiwire.RerankDocument:
+ properties:
+ text:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.RerankRequest:
+ properties:
+ documents:
+ items:
+ type: string
+ type: array
+ model:
+ type: string
+ query:
+ type: string
+ return_documents:
+ type: boolean
+ top_n:
+ type: integer
+ type: object
+ oci-portal_internal_aiwire.RerankResponse:
+ properties:
+ model:
+ type: string
+ results:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RerankResult'
+ type: array
+ type: object
+ oci-portal_internal_aiwire.RerankResult:
+ properties:
+ document:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RerankDocument'
+ index:
+ type: integer
+ relevance_score:
+ type: number
+ type: object
+ oci-portal_internal_aiwire.RespError:
+ properties:
+ code:
+ type: string
+ message:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.RespInDetails:
+ properties:
+ cached_tokens:
+ type: integer
+ type: object
+ oci-portal_internal_aiwire.RespOutDetails:
+ properties:
+ reasoning_tokens:
+ type: integer
+ type: object
+ oci-portal_internal_aiwire.RespReasoning:
+ properties:
+ effort:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.RespRequest:
+ properties:
+ background:
+ type: boolean
+ conversation:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ input:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ instructions:
+ type: string
+ max_output_tokens:
+ type: integer
+ model:
+ type: string
+ parallel_tool_calls:
+ type: boolean
+ previous_response_id:
+ type: string
+ reasoning:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespReasoning'
+ store:
+ type: boolean
+ stream:
+ type: boolean
+ temperature:
+ type: number
+ text:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespText'
+ tool_choice:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ tools:
+ items:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespTool'
+ type: array
+ top_p:
+ type: number
+ type: object
+ oci-portal_internal_aiwire.RespResponse:
+ properties:
+ created_at:
+ type: integer
+ error:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespError'
+ id:
+ type: string
+ model:
+ type: string
+ object:
+ type: string
+ output:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ status:
+ type: string
+ usage:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespUsage'
+ type: object
+ oci-portal_internal_aiwire.RespText:
+ properties:
+ format:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespTextFormat'
+ type: object
+ oci-portal_internal_aiwire.RespTextFormat:
+ properties:
+ name:
+ type: string
+ schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ strict:
+ type: boolean
+ type:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.RespTool:
+ properties:
+ description:
+ type: string
+ name:
+ type: string
+ parameters:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ strict:
+ type: boolean
+ type:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.RespUsage:
+ properties:
+ input_tokens:
+ type: integer
+ input_tokens_details:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespInDetails'
+ output_tokens:
+ type: integer
+ output_tokens_details:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespOutDetails'
+ total_tokens:
+ type: integer
+ type: object
+ oci-portal_internal_aiwire.ResponseFormat:
+ properties:
+ json_schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ type:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.SpeechRequest:
+ properties:
+ input:
+ type: string
+ language:
+ type: string
+ model:
+ type: string
+ response_format:
+ type: string
+ voice:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.StreamOptions:
+ properties:
+ include_usage:
+ type: boolean
+ type: object
+ oci-portal_internal_aiwire.Tool:
+ properties:
+ function:
+ $ref: '#/definitions/oci-portal_internal_aiwire.FunctionDef'
+ type:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.ToolCall:
+ properties:
+ function:
+ $ref: '#/definitions/oci-portal_internal_aiwire.FunctionCall'
+ id:
+ type: string
+ type:
+ type: string
+ type: object
+ oci-portal_internal_aiwire.Usage:
+ properties:
+ completion_tokens:
+ type: integer
+ prompt_tokens:
+ type: integer
+ prompt_tokens_details:
+ allOf:
+ - $ref: '#/definitions/oci-portal_internal_aiwire.PromptTokensDetails'
+ description: PromptTokensDetails 携带缓存命中细分;OCI 为隐式 prompt 缓存,只有读取计数
+ total_tokens:
+ type: integer
+ type: object
+ oci-portal_internal_model.AiCallLog:
+ properties:
+ cachedTokens:
+ description: CachedTokens 是输入中缓存命中(读取)的部分;OCI 隐式缓存无写入计数
+ type: integer
+ channelId:
+ type: integer
+ channelName:
+ type: string
+ clientIp:
+ description: ClientIP 是网关调用方来源 IP(尊重「真实 IP 头」安全设置,与系统日志同源)
+ type: string
+ completionTokens:
+ type: integer
+ createdAt:
+ type: string
+ endpoint:
+ description: openai / anthropic
+ type: string
+ errMsg:
+ type: string
+ id:
+ type: integer
+ keyId:
+ type: integer
+ keyName:
+ type: string
+ latencyMs:
+ type: integer
+ model:
+ type: string
+ promptTokens:
+ type: integer
+ retries:
+ type: integer
+ status:
+ type: integer
+ stream:
+ type: boolean
+ totalTokens:
+ type: integer
+ type: object
+ oci-portal_internal_model.AiChannel:
+ properties:
+ createdAt:
+ type: string
+ disabledUntil:
+ type: string
+ enabled:
+ type: boolean
+ failCount:
+ description: FailCount 连续失败计数;达阈值后 DisabledUntil 指数退避熔断,成功/探测通过复位
+ type: integer
+ group:
+ type: string
+ id:
+ type: integer
+ lastProbeAt:
+ type: string
+ name:
+ type: string
+ ociConfigId:
+ type: integer
+ priority:
+ type: integer
+ probeError:
+ type: string
+ probeStatus:
+ description: ok / no_service / no_quota / error
+ type: string
+ region:
+ type: string
+ updatedAt:
+ type: string
+ weight:
+ type: integer
+ type: object
+ oci-portal_internal_model.AiContentLog:
+ properties:
+ callLogId:
+ description: CallLogID 关联同次调用的 AiCallLog,调用日志详情据此反查正文
+ type: integer
+ createdAt:
+ type: string
+ endpoint:
+ type: string
+ id:
+ type: integer
+ keyId:
+ type: integer
+ keyName:
+ type: string
+ model:
+ type: string
+ requestBody:
+ description: |-
+ RequestBody / ResponseBody 是截断后的正文 JSON;
+ 64KB 截断恰在 MySQL TEXT 上限(65535B)边界,size 上探一档 → MEDIUMTEXT
+ type: string
+ responseBody:
+ type: string
+ stream:
+ type: boolean
+ type: object
+ oci-portal_internal_model.AiKey:
+ properties:
+ contentLogUntil:
+ description: |-
+ ContentLogUntil 是内容日志开启截止时间;nil = 永关(默认,红线),
+ 开启必须限时,到期自动停写
+ type: string
+ createdAt:
+ type: string
+ enabled:
+ type: boolean
+ group:
+ type: string
+ id:
+ type: integer
+ lastUsedAt:
+ type: string
+ models:
+ description: Models 是模型白名单(精确匹配模型名);空 = 不限,非空时网关仅放行列表内模型
+ items:
+ type: string
+ type: array
+ name:
+ type: string
+ tail:
+ type: string
+ type: object
+ oci-portal_internal_model.AiModelBlacklist:
+ properties:
+ createdAt:
+ type: string
+ id:
+ type: integer
+ name:
+ type: string
+ type: object
+ oci-portal_internal_model.AiModelCache:
+ properties:
+ capability:
+ type: string
+ channelId:
+ type: integer
+ deprecatedAt:
+ description: |-
+ DeprecatedAt 是 OCI 宣布的模型弃用时间;nil 表示未宣布。
+ 弃用后仍可调用,直到 RetiredAt(按需推理退役,同步层已剔除过期项)。
+ type: string
+ modelOcid:
+ type: string
+ name:
+ type: string
+ retiredAt:
+ type: string
+ syncedAt:
+ type: string
+ vendor:
+ type: string
+ type: object
+ oci-portal_internal_model.LogEvent:
+ properties:
+ eventTime:
+ type: string
+ eventType:
+ description: 异步解析回填,如 com.oraclecloud.ComputeApi.TerminateInstance
+ type: string
+ id:
+ type: integer
+ messageId:
+ description: 幂等键(X-OCI-NS-MessageId)
+ type: string
+ ociConfigId:
+ description: 经 secret 反查归属租户
+ type: integer
+ payload:
+ description: 防御上限 256KB 超 MySQL TEXT(64KB),size 上探一档 → MEDIUMTEXT;PG/SQLite
+ 仍为 text
+ type: string
+ processed:
+ type: boolean
+ receivedAt:
+ type: string
+ source:
+ type: string
+ sourceIp:
+ description: 异步解析回填,Audit 事件的发起方 IP
+ type: string
+ truncated:
+ type: boolean
+ type: object
+ oci-portal_internal_model.OciConfig:
+ properties:
+ accountType:
+ type: string
+ alias:
+ type: string
+ aliveStatus:
+ type: string
+ createdAt:
+ type: string
+ fingerprint:
+ type: string
+ group:
+ description: |-
+ Group 是面板内的自定义分组标签,空串表示未分组;
+ 列名避开 SQL 保留字 GROUP
+ type: string
+ homeRegionKey:
+ type: string
+ id:
+ type: integer
+ lastError:
+ type: string
+ lastVerifiedAt:
+ type: string
+ multiCompartment:
+ type: boolean
+ multiRegion:
+ description: |-
+ 多区域 / 多区间支持:开启后订阅区域与 compartment 列表入库缓存,
+ 供筛选器免实时调 OCI;未开启的租户筛选器锁定主区域 / 根区间。
+ type: boolean
+ paymentModel:
+ type: string
+ promotionAmount:
+ type: number
+ promotionExpires:
+ type: string
+ promotionStatus:
+ type: string
+ proxyId:
+ description: ProxyID 关联出站代理,nil 表示直连;该租户全部 SDK 调用经此代理
+ type: integer
+ region:
+ type: string
+ subscriptionId:
+ type: string
+ subscriptionTier:
+ type: string
+ tenancyName:
+ type: string
+ tenancyOcid:
+ type: string
+ updatedAt:
+ type: string
+ userOcid:
+ type: string
+ type: object
+ oci-portal_internal_model.SystemLog:
+ properties:
+ clientIp:
+ type: string
+ createdAt:
+ type: string
+ durationMs:
+ type: integer
+ errMsg:
+ description: ErrMsg 仅失败请求(>=400)存响应的 error 文案,便于免翻服务端日志定位原因
+ type: string
+ id:
+ type: integer
+ method:
+ type: string
+ path:
+ type: string
+ status:
+ type: integer
+ userAgent:
+ type: string
+ username:
+ type: string
+ type: object
+ oci-portal_internal_model.Task:
+ properties:
+ createdAt:
+ type: string
+ cronExpr:
+ type: string
+ id:
+ type: integer
+ lastError:
+ type: string
+ lastRunAt:
+ type: string
+ name:
+ type: string
+ payload:
+ type: string
+ runCount:
+ type: integer
+ status:
+ type: string
+ type:
+ type: string
+ updatedAt:
+ type: string
+ type: object
+ oci-portal_internal_model.TaskLog:
+ properties:
+ createdAt:
+ type: string
+ durationMs:
+ type: integer
+ id:
+ type: integer
+ message:
+ type: string
+ success:
+ type: boolean
+ taskId:
+ type: integer
+ type: object
+ oci-portal_internal_model.UserIdentity:
+ properties:
+ createdAt:
+ type: string
+ display:
+ description: 展示名:邮箱 / GitHub login
+ type: string
+ id:
+ type: integer
+ provider:
+ type: string
+ type: object
+ oci-portal_internal_oci.AuditEvent:
+ properties:
+ compartmentName:
+ type: string
+ eventId:
+ type: string
+ eventName:
+ type: string
+ eventTime:
+ type: string
+ ipAddress:
+ type: string
+ principalName:
+ type: string
+ raw:
+ $ref: '#/definitions/oci-portal_internal_aiwire.AnyJSON'
+ requestAction:
+ type: string
+ requestPath:
+ type: string
+ resourceName:
+ type: string
+ source:
+ type: string
+ status:
+ type: string
+ type: object
+ oci-portal_internal_oci.BlockVolume:
+ properties:
+ availabilityDomain:
+ type: string
+ displayName:
+ type: string
+ id:
+ type: string
+ lifecycleState:
+ type: string
+ sizeInGBs:
+ type: integer
+ timeCreated:
+ type: string
+ vpusPerGB:
+ type: integer
+ type: object
+ oci-portal_internal_oci.BootVolume:
+ properties:
+ attachedInstanceId:
+ type: string
+ attachedInstanceName:
+ type: string
+ availabilityDomain:
+ type: string
+ compartmentId:
+ type: string
+ displayName:
+ type: string
+ id:
+ type: string
+ imageId:
+ type: string
+ imageName:
+ type: string
+ lifecycleState:
+ type: string
+ sizeInGBs:
+ type: integer
+ timeCreated:
+ type: string
+ vpusPerGB:
+ type: integer
+ type: object
+ oci-portal_internal_oci.BootVolumeAttachment:
+ properties:
+ availabilityDomain:
+ type: string
+ bootVolumeId:
+ type: string
+ displayName:
+ type: string
+ id:
+ type: string
+ instanceId:
+ type: string
+ lifecycleState:
+ type: string
+ type: object
+ oci-portal_internal_oci.Compartment:
+ properties:
+ description:
+ type: string
+ id:
+ type: string
+ lifecycleState:
+ type: string
+ name:
+ type: string
+ parentId:
+ type: string
+ timeCreated:
+ type: string
+ type: object
+ oci-portal_internal_oci.ComputeShape:
+ properties:
+ billingType:
+ description: ALWAYS_FREE / LIMITED_FREE / PAID
+ type: string
+ gpus:
+ type: integer
+ isFlexible:
+ type: boolean
+ memoryInGBs:
+ type: number
+ memoryMaxGBs:
+ type: number
+ memoryMinGBs:
+ type: number
+ name:
+ type: string
+ ocpus:
+ type: number
+ ocpusMax:
+ type: number
+ ocpusMin:
+ type: number
+ processorDescription:
+ type: string
+ type: object
+ oci-portal_internal_oci.ConsoleConnection:
+ properties:
+ connectionString:
+ description: 串口控制台 SSH 命令
+ type: string
+ id:
+ type: string
+ instanceId:
+ type: string
+ lifecycleState:
+ type: string
+ vncConnectionString:
+ description: VNC over SSH 隧道命令
+ type: string
+ type: object
+ oci-portal_internal_oci.CostItem:
+ properties:
+ computedAmount:
+ type: number
+ computedQuantity:
+ type: number
+ currency:
+ type: string
+ groupValue:
+ type: string
+ timeStart:
+ type: string
+ unit:
+ type: string
+ type: object
+ oci-portal_internal_oci.IPv6Step:
+ properties:
+ detail:
+ type: string
+ status:
+ description: done / skipped / failed
+ type: string
+ step:
+ type: string
+ type: object
+ oci-portal_internal_oci.IdentityDomain:
+ properties:
+ displayName:
+ type: string
+ homeRegion:
+ type: string
+ id:
+ type: string
+ licenseType:
+ type: string
+ type:
+ type: string
+ type: object
+ oci-portal_internal_oci.IdentityProviderInfo:
+ properties:
+ enabled:
+ type: boolean
+ id:
+ type: string
+ jitEnabled:
+ type: boolean
+ name:
+ type: string
+ partnerProviderId:
+ type: string
+ timeCreated:
+ type: string
+ type:
+ type: string
+ type: object
+ oci-portal_internal_oci.IdentitySettingInfo:
+ properties:
+ id:
+ type: string
+ primaryEmailRequired:
+ description: 用户需要提供主电子邮件地址:开启后创建用户 / JIT 预配必须带邮箱
+ type: boolean
+ type: object
+ oci-portal_internal_oci.Image:
+ properties:
+ displayName:
+ type: string
+ id:
+ type: string
+ operatingSystem:
+ type: string
+ operatingSystemVersion:
+ type: string
+ sizeInMBs:
+ type: integer
+ timeCreated:
+ type: string
+ type: object
+ oci-portal_internal_oci.Instance:
+ properties:
+ availabilityDomain:
+ type: string
+ compartmentId:
+ type: string
+ definedTags:
+ additionalProperties:
+ additionalProperties: {}
+ type: object
+ type: object
+ displayName:
+ type: string
+ freeformTags:
+ additionalProperties:
+ type: string
+ type: object
+ id:
+ type: string
+ imageId:
+ type: string
+ ipv6Addresses:
+ items:
+ type: string
+ type: array
+ lifecycleState:
+ type: string
+ memoryInGBs:
+ type: number
+ ocpus:
+ type: number
+ privateIp:
+ type: string
+ publicIp:
+ type: string
+ region:
+ type: string
+ shape:
+ type: string
+ subnetId:
+ type: string
+ timeCreated:
+ type: string
+ type: object
+ oci-portal_internal_oci.InstanceTraffic:
+ properties:
+ inboundBytes:
+ type: number
+ instanceId:
+ type: string
+ outboundBytes:
+ type: number
+ vnics:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.VnicTraffic'
+ type: array
+ type: object
+ oci-portal_internal_oci.LimitService:
+ properties:
+ description:
+ type: string
+ name:
+ type: string
+ type: object
+ oci-portal_internal_oci.LimitValue:
+ properties:
+ availabilityDomain:
+ type: string
+ available:
+ type: integer
+ name:
+ type: string
+ scopeType:
+ type: string
+ used:
+ type: integer
+ value:
+ type: integer
+ type: object
+ oci-portal_internal_oci.NotificationRecipients:
+ properties:
+ recipients:
+ items:
+ type: string
+ type: array
+ testModeEnabled:
+ type: boolean
+ type: object
+ oci-portal_internal_oci.PasswordPolicyInfo:
+ properties:
+ id:
+ type: string
+ minLength:
+ type: integer
+ name:
+ type: string
+ numPasswordsInHistory:
+ type: integer
+ passwordExpiresAfter:
+ type: integer
+ passwordStrength:
+ type: string
+ priority:
+ type: integer
+ type: object
+ oci-portal_internal_oci.PromotionInfo:
+ properties:
+ amount:
+ type: number
+ currencyUnit:
+ type: string
+ duration:
+ type: integer
+ durationUnit:
+ type: string
+ isIntentToPay:
+ type: boolean
+ status:
+ type: string
+ timeExpired:
+ type: string
+ timeStarted:
+ type: string
+ type: object
+ oci-portal_internal_oci.RegionInfo:
+ properties:
+ alias:
+ type: string
+ key:
+ type: string
+ name:
+ type: string
+ type: object
+ oci-portal_internal_oci.RelayResource:
+ properties:
+ id:
+ type: string
+ state:
+ type: string
+ type: object
+ oci-portal_internal_oci.SecurityList:
+ properties:
+ displayName:
+ type: string
+ egressRules:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.SecurityRule'
+ type: array
+ id:
+ type: string
+ ingressRules:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.SecurityRule'
+ type: array
+ lifecycleState:
+ type: string
+ timeCreated:
+ type: string
+ vcnId:
+ type: string
+ type: object
oci-portal_internal_oci.SecurityRule:
properties:
description:
@@ -431,6 +1962,251 @@ definitions:
source:
type: string
type: object
+ oci-portal_internal_oci.SignOnRuleInfo:
+ properties:
+ authenticationFactor:
+ type: string
+ builtIn:
+ type: boolean
+ conditionAttribute:
+ type: string
+ conditionValue:
+ type: string
+ id:
+ type: string
+ name:
+ type: string
+ sequence:
+ type: integer
+ type: object
+ oci-portal_internal_oci.Subnet:
+ properties:
+ availabilityDomain:
+ type: string
+ cidrBlock:
+ type: string
+ displayName:
+ type: string
+ dnsLabel:
+ type: string
+ id:
+ type: string
+ ipv6CidrBlock:
+ type: string
+ lifecycleState:
+ type: string
+ prohibitPublicIp:
+ type: boolean
+ routeTableId:
+ type: string
+ timeCreated:
+ type: string
+ vcnId:
+ type: string
+ type: object
+ oci-portal_internal_oci.SubscriptionDetail:
+ properties:
+ classicSubscriptionId:
+ type: string
+ cloudAmountCurrency:
+ type: string
+ csiNumber:
+ type: string
+ customerCountryCode:
+ type: string
+ endDate:
+ type: string
+ id:
+ type: string
+ isGovernmentSubscription:
+ type: boolean
+ lifecycleState:
+ type: string
+ paymentModel:
+ type: string
+ programType:
+ type: string
+ promotions:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.PromotionInfo'
+ type: array
+ regionAssignment:
+ type: string
+ serviceName:
+ type: string
+ startDate:
+ type: string
+ subscriptionTier:
+ type: string
+ timeCreated:
+ type: string
+ timeUpdated:
+ type: string
+ type: object
+ oci-portal_internal_oci.SubscriptionInfo:
+ properties:
+ id:
+ type: string
+ serviceName:
+ type: string
+ timeCreated:
+ type: string
+ timeUpdated:
+ type: string
+ type: object
+ oci-portal_internal_oci.TenantUser:
+ properties:
+ description:
+ type: string
+ email:
+ type: string
+ emailVerified:
+ type: boolean
+ id:
+ type: string
+ isCurrentUser:
+ type: boolean
+ lastLoginTime:
+ type: string
+ lifecycleState:
+ type: string
+ mfaActivated:
+ type: boolean
+ name:
+ type: string
+ timeCreated:
+ type: string
+ type: object
+ oci-portal_internal_oci.TenantUserDetail:
+ properties:
+ familyName:
+ type: string
+ givenName:
+ type: string
+ inAdminGroup:
+ type: boolean
+ inDomain:
+ type: boolean
+ isDomainAdmin:
+ type: boolean
+ type: object
+ oci-portal_internal_oci.TrafficPoint:
+ properties:
+ bytes:
+ type: number
+ timestamp:
+ type: string
+ type: object
+ oci-portal_internal_oci.VCN:
+ properties:
+ cidrBlocks:
+ items:
+ type: string
+ type: array
+ compartmentId:
+ type: string
+ defaultRouteTableId:
+ type: string
+ defaultSecurityListId:
+ type: string
+ displayName:
+ type: string
+ dnsLabel:
+ type: string
+ id:
+ type: string
+ ipv6CidrBlocks:
+ items:
+ type: string
+ type: array
+ lifecycleState:
+ type: string
+ timeCreated:
+ type: string
+ type: object
+ oci-portal_internal_oci.Vnic:
+ properties:
+ attachmentId:
+ type: string
+ displayName:
+ type: string
+ ipv6Addresses:
+ items:
+ type: string
+ type: array
+ isPrimary:
+ type: boolean
+ lifecycleState:
+ type: string
+ privateIp:
+ type: string
+ publicIp:
+ type: string
+ subnetId:
+ type: string
+ subnetName:
+ type: string
+ timeCreated:
+ type: string
+ vnicId:
+ type: string
+ type: object
+ oci-portal_internal_oci.VnicTraffic:
+ properties:
+ inbound:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.TrafficPoint'
+ type: array
+ inboundBytes:
+ type: number
+ outbound:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.TrafficPoint'
+ type: array
+ outboundBytes:
+ type: number
+ vnicId:
+ type: string
+ type: object
+ oci-portal_internal_oci.VolumeAttachment:
+ properties:
+ availabilityDomain:
+ type: string
+ device:
+ type: string
+ displayName:
+ type: string
+ id:
+ type: string
+ instanceId:
+ type: string
+ isReadOnly:
+ type: boolean
+ lifecycleState:
+ type: string
+ volumeId:
+ type: string
+ volumeName:
+ description: 卷本身的名称(attachment 名是自动生成的)
+ type: string
+ type: object
+ oci-portal_internal_service.AuditEventsView:
+ properties:
+ cursor:
+ type: string
+ exhausted:
+ type: boolean
+ items:
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.AuditEvent'
+ type: array
+ type: object
+ oci-portal_internal_service.Changes:
+ additionalProperties:
+ items:
+ type: string
+ type: array
+ type: object
oci-portal_internal_service.ChannelInput:
properties:
enabled:
@@ -448,6 +2224,102 @@ definitions:
weight:
type: integer
type: object
+ oci-portal_internal_service.ConfigSummary:
+ properties:
+ accountType:
+ type: string
+ alias:
+ type: string
+ aliveStatus:
+ type: string
+ createdAt:
+ type: string
+ group:
+ type: string
+ id:
+ type: integer
+ lastError:
+ type: string
+ lastVerifiedAt:
+ type: string
+ multiCompartment:
+ type: boolean
+ multiRegion:
+ type: boolean
+ proxyId:
+ type: integer
+ proxyName:
+ description: ProxyName 由 List 按关联填充,供表格代理列 hover 展示
+ type: string
+ region:
+ type: string
+ tenancyName:
+ type: string
+ tenancyOcid:
+ type: string
+ type: object
+ oci-portal_internal_service.ImportFail:
+ properties:
+ line:
+ type: string
+ lineNo:
+ type: integer
+ reason:
+ type: string
+ type: object
+ oci-portal_internal_service.ImportResult:
+ properties:
+ created:
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.ProxyView'
+ type: array
+ failed:
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.ImportFail'
+ type: array
+ type: object
+ oci-portal_internal_service.LogWebhookInfo:
+ properties:
+ createdAt:
+ type: string
+ path:
+ type: string
+ secret:
+ type: string
+ type: object
+ oci-portal_internal_service.NotifyChannelView:
+ properties:
+ bodyTemplate:
+ type: string
+ enabled:
+ type: boolean
+ from:
+ type: string
+ host:
+ description: smtp
+ type: string
+ port:
+ type: integer
+ secretSet:
+ description: 密文字段状态(ntfy token / bark device key / smtp password)
+ type: boolean
+ secretTail:
+ type: string
+ server:
+ description: ntfy / bark 共用 Server
+ type: string
+ to:
+ type: string
+ topic:
+ type: string
+ type:
+ type: string
+ url:
+ description: webhook
+ type: string
+ username:
+ type: string
+ type: object
oci-portal_internal_service.NotifyEventsView:
properties:
logEventIdentity:
@@ -475,6 +2347,22 @@ definitions:
tenantDead:
type: boolean
type: object
+ oci-portal_internal_service.NotifyTemplateView:
+ properties:
+ defaultTemplate:
+ type: string
+ kind:
+ type: string
+ label:
+ type: string
+ template:
+ description: Template 是自定义模板;空串表示未自定义(按默认发送)
+ type: string
+ vars:
+ items:
+ type: string
+ type: array
+ type: object
oci-portal_internal_service.OAuthProvidersView:
properties:
githubClientId:
@@ -496,6 +2384,85 @@ definitions:
oidcSecretSet:
type: boolean
type: object
+ oci-portal_internal_service.Overview:
+ properties:
+ check:
+ $ref: '#/definitions/oci-portal_internal_service.OverviewCheck'
+ cost:
+ $ref: '#/definitions/oci-portal_internal_service.OverviewCost'
+ tasks:
+ $ref: '#/definitions/oci-portal_internal_service.OverviewTasks'
+ tenants:
+ $ref: '#/definitions/oci-portal_internal_service.OverviewTenants'
+ type: object
+ oci-portal_internal_service.OverviewCheck:
+ properties:
+ coveredConfigs:
+ type: integer
+ hasActiveTask:
+ type: boolean
+ instanceCount:
+ type: integer
+ lastCheckedAt:
+ type: string
+ totalConfigs:
+ type: integer
+ type: object
+ oci-portal_internal_service.OverviewCost:
+ properties:
+ coveredConfigs:
+ type: integer
+ currency:
+ type: string
+ days:
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.OverviewCostDay'
+ type: array
+ hasActiveTask:
+ type: boolean
+ total:
+ type: number
+ type: object
+ oci-portal_internal_service.OverviewCostDay:
+ properties:
+ amount:
+ type: number
+ day:
+ type: string
+ type: object
+ oci-portal_internal_service.OverviewTasks:
+ properties:
+ active:
+ type: integer
+ cost:
+ type: integer
+ healthCheck:
+ type: integer
+ snatch:
+ type: integer
+ total:
+ type: integer
+ type: object
+ oci-portal_internal_service.OverviewTenants:
+ properties:
+ alive:
+ type: integer
+ byType:
+ additionalProperties:
+ type: integer
+ type: object
+ dead:
+ type: integer
+ total:
+ type: integer
+ type: object
+ oci-portal_internal_service.ProviderInfo:
+ properties:
+ displayName:
+ type: string
+ provider:
+ type: string
+ type: object
oci-portal_internal_service.ProxyInput:
properties:
host:
@@ -515,6 +2482,69 @@ definitions:
- port
- type
type: object
+ oci-portal_internal_service.ProxyView:
+ properties:
+ city:
+ type: string
+ country:
+ description: Country / City 为出口实测地区;GeoAt 空串表示尚未探测(前端显示「检测中」)
+ type: string
+ createdAt:
+ type: string
+ geoAt:
+ type: string
+ host:
+ type: string
+ id:
+ type: integer
+ name:
+ type: string
+ passwordSet:
+ type: boolean
+ port:
+ type: integer
+ type:
+ type: string
+ usedBy:
+ description: UsedBy 为关联此代理的租户数,前端据此提示删除约束
+ type: integer
+ username:
+ type: string
+ type: object
+ oci-portal_internal_service.RegionSubscriptionView:
+ properties:
+ alias:
+ type: string
+ isHomeRegion:
+ type: boolean
+ key:
+ type: string
+ name:
+ type: string
+ status:
+ type: string
+ type: object
+ oci-portal_internal_service.RelayView:
+ properties:
+ connector:
+ $ref: '#/definitions/oci-portal_internal_oci.RelayResource'
+ endpoint:
+ type: string
+ events:
+ items:
+ type: string
+ type: array
+ policy:
+ $ref: '#/definitions/oci-portal_internal_oci.RelayResource'
+ ready:
+ type: boolean
+ subscription:
+ $ref: '#/definitions/oci-portal_internal_oci.RelayResource'
+ topic:
+ $ref: '#/definitions/oci-portal_internal_oci.RelayResource'
+ webhook:
+ $ref: '#/definitions/oci-portal_internal_service.LogWebhookInfo'
+ type: object
oci-portal_internal_service.SecuritySettings:
properties:
appUrl:
@@ -539,6 +2569,17 @@ definitions:
snatchAuthFailLimit:
type: integer
type: object
+ oci-portal_internal_service.TelegramView:
+ properties:
+ chatId:
+ type: string
+ enabled:
+ type: boolean
+ tokenSet:
+ type: boolean
+ tokenTail:
+ type: string
+ type: object
oci-portal_internal_service.UpdateCredentialsInput:
properties:
currentPassword:
@@ -578,6 +2619,24 @@ info:
title: OCI Portal API
version: 0.0.1
paths:
+ /ai/v1/audio/speech:
+ post:
+ parameters:
+ - description: OpenAI audio speech 请求体(model/input 必填,voice 见 xAI Grok Voice
+ 列表,language 缺省 auto;未列字段原样透传)
+ in: body
+ name: body
+ required: true
+ schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.SpeechRequest'
+ responses:
+ "200":
+ description: 音频字节(Content-Type 透传上游,默认 audio/mpeg)
+ schema:
+ type: file
+ summary: OpenAI Audio Speech 兼容端点(文本转语音)
+ tags:
+ - AI 网关
/ai/v1/chat/completions:
post:
parameters:
@@ -586,13 +2645,12 @@ paths:
name: body
required: true
schema:
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.ChatRequest'
responses:
"200":
- description: 'OpenAI 兼容响应(流式为 SSE,末尾 data: [DONE])'
+ description: 'OpenAI 兼容响应(非流式;流式为 SSE,末尾 data: [DONE])'
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.ChatResponse'
summary: OpenAI Chat Completions 兼容端点
tags:
- AI 网关
@@ -604,13 +2662,12 @@ paths:
name: body
required: true
schema:
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.EmbeddingsRequest'
responses:
"200":
description: OpenAI 兼容响应
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.EmbeddingsResponse'
summary: OpenAI 兼容向量嵌入
tags:
- AI 网关
@@ -623,13 +2680,12 @@ paths:
name: body
required: true
schema:
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.MessagesRequest'
responses:
"200":
- description: Anthropic 兼容响应(流式为 SSE)
+ description: Anthropic 兼容响应(非流式;流式为 SSE 事件序列)
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.MessagesResponse'
summary: Anthropic Messages 兼容端点
tags:
- AI 网关
@@ -639,26 +2695,60 @@ paths:
"200":
description: OpenAI 兼容 models 列表
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.ModelList'
summary: 可用模型列表
tags:
- AI 网关
+ /ai/v1/moderations:
+ post:
+ parameters:
+ - description: 审核请求体(input 为字符串或字符串数组,单次至多 8 条;model 接受但忽略)
+ in: body
+ name: body
+ required: true
+ schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ModerationsRequest'
+ responses:
+ "200":
+ description: 审核结果(categories/category_scores 为 overall/blocklist/prompt_injection,pii
+ 为扩展字段)
+ schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.ModerationsResponse'
+ summary: 内容审核端点(OCI Guardrails)
+ tags:
+ - AI 网关
+ /ai/v1/rerank:
+ post:
+ parameters:
+ - description: 重排请求体(model/query/documents 必填,可选 top_n/return_documents)
+ in: body
+ name: body
+ required: true
+ schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RerankRequest'
+ responses:
+ "200":
+ description: 重排结果(results[].index 指向入参下标)
+ schema:
+ $ref: '#/definitions/oci-portal_internal_aiwire.RerankResponse'
+ summary: 文档重排端点(Cohere Rerank)
+ tags:
+ - AI 网关
/ai/v1/responses:
post:
parameters:
- - description: OpenAI responses 请求体(支持 stream;web_search/x_search 服务端工具仅非流式)
+ - description: OpenAI responses 请求体(支持 stream;服务端工具 web_search/x_search/code_interpreter/mcp
+ 含流式;未列字段原样透传上游)
in: body
name: body
required: true
schema:
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespRequest'
responses:
"200":
- description: OpenAI 兼容响应(流式为 SSE)
+ description: OpenAI 兼容响应(非流式;流式为 SSE);直通仅建模常用字段,未列字段原样返回
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_aiwire.RespResponse'
summary: OpenAI Responses 兼容端点
tags:
- AI 网关
@@ -668,8 +2758,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.aboutResponse'
security:
- BearerAuth: []
summary: 返回构建、运行时长与资源占用信息,「设置 · 关于」页展示
@@ -681,8 +2770,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiModelBlacklist'
security:
- BearerAuth: []
summary: 模型黑名单列表
@@ -700,8 +2788,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemResponse-oci-portal_internal_model_AiModelBlacklist'
security:
- BearerAuth: []
summary: 添加模型黑名单
@@ -729,8 +2816,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiChannel'
security:
- BearerAuth: []
summary: '---- 渠道 ----'
@@ -748,8 +2834,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.AiChannel'
security:
- BearerAuth: []
summary: 创建 AI 渠道
@@ -804,8 +2889,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.AiChannel'
security:
- BearerAuth: []
summary: 触发探测:服务可见性 + 模型同步 + 配额试调,返回更新后的渠道
@@ -823,8 +2907,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiModelCache'
security:
- BearerAuth: []
summary: 同步渠道模型缓存
@@ -836,8 +2919,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.pagedResponse-oci-portal_internal_model_AiCallLog'
security:
- BearerAuth: []
summary: 分页查询内容日志
@@ -849,8 +2931,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_model_AiKey'
security:
- BearerAuth: []
summary: '---- 密钥 ----'
@@ -866,10 +2947,9 @@ paths:
type: object
responses:
"201":
- description: Created
+ description: key 为明文密钥,仅本次返回
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.aiKeyCreateResponse'
security:
- BearerAuth: []
summary: 生成密钥
@@ -930,8 +3010,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.AiKey'
security:
- BearerAuth: []
summary: 设置密钥内容日志窗口
@@ -943,8 +3022,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.pagedResponse-oci-portal_internal_model_AiContentLog'
security:
- BearerAuth: []
summary: AI 调用日志列表
@@ -956,8 +3034,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_aiwire_Model'
security:
- BearerAuth: []
summary: '---- 聚合模型与调用日志 ----'
@@ -969,8 +3046,7 @@ paths:
"200":
description: username 与 passwordLoginDisabled
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.credentialsResponse'
security:
- BearerAuth: []
summary: 登录凭据摘要
@@ -990,9 +3066,7 @@ paths:
"401":
description: 当前密码错误
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.errorResponse'
security:
- BearerAuth: []
summary: 修改登录凭据
@@ -1004,8 +3078,7 @@ paths:
"200":
description: items
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_model_UserIdentity'
security:
- BearerAuth: []
summary: 已绑定外部身份
@@ -1025,9 +3098,7 @@ paths:
"409":
description: 最后一个身份不可解绑
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.errorResponse'
security:
- BearerAuth: []
summary: 解绑外部身份
@@ -1050,19 +3121,15 @@ paths:
"200":
description: token 与 expiresAt
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.tokenResponse'
"401":
description: 凭据错误
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.errorResponse'
"428":
description: 需要两步验证码(totpRequired=true)
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.totpRequiredResponse'
summary: 登录
tags:
- 认证
@@ -1092,9 +3159,7 @@ paths:
"200":
description: url
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.urlResponse'
summary: 外部登录授权跳转
tags:
- 认证
@@ -1128,8 +3193,7 @@ paths:
"200":
description: providers 与 passwordLoginDisabled
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.oauthProvidersResponse'
summary: 外部登录 provider 列表
tags:
- 认证
@@ -1148,9 +3212,7 @@ paths:
"409":
description: 未绑定外部身份
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.errorResponse'
security:
- BearerAuth: []
summary: 密码登录开关
@@ -1162,9 +3224,7 @@ paths:
"200":
description: 新 token 与 expiresAt
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.tokenResponse'
security:
- BearerAuth: []
summary: 撤销全部会话
@@ -1176,9 +3236,7 @@ paths:
"200":
description: enabled
schema:
- additionalProperties:
- type: boolean
- type: object
+ $ref: '#/definitions/internal_api.enabledResponse'
security:
- BearerAuth: []
summary: 两步验证状态
@@ -1224,15 +3282,11 @@ paths:
"200":
description: secret 与 otpauthUri
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.totpSetupResponse'
"409":
description: 已启用
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.errorResponse'
security:
- BearerAuth: []
summary: 发起两步验证设置
@@ -1288,8 +3342,7 @@ paths:
"200":
description: items 与 total
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.pagedResponse-oci-portal_internal_model_LogEvent'
security:
- BearerAuth: []
summary: 回传日志事件列表
@@ -1299,10 +3352,11 @@ paths:
get:
responses:
"200":
- description: items
+ description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.ConfigSummary'
+ type: array
security:
- BearerAuth: []
summary: 租户配置列表
@@ -1320,8 +3374,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.OciConfig'
security:
- BearerAuth: []
summary: 导入租户配置
@@ -1355,8 +3408,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.OciConfig'
security:
- BearerAuth: []
summary: 租户配置详情
@@ -1377,10 +3429,9 @@ paths:
type: object
responses:
"200":
- description: OK
+ description: config 与 changes 字段变更对照
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.configChangesResponse'
security:
- BearerAuth: []
summary: 更新租户配置
@@ -1406,8 +3457,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.AuditEventsView'
security:
- BearerAuth: []
summary: 批式懒加载查询租户 OCI 审计事件
@@ -1423,10 +3473,9 @@ paths:
type: integer
responses:
"200":
- description: OK
+ description: raw 为事件原文 JSON
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.rawDetailResponse'
security:
- BearerAuth: []
summary: 按 eventId 取回原始事件 JSON:缓存命中秒开,
@@ -1444,8 +3493,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ type: string
+ type: array
security:
- BearerAuth: []
summary: 可用域列表
@@ -1484,8 +3534,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.BootVolume'
+ type: array
security:
- BearerAuth: []
summary: 引导卷列表
@@ -1528,8 +3579,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.BootVolume'
security:
- BearerAuth: []
summary: 引导卷详情
@@ -1557,8 +3607,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.BootVolume'
security:
- BearerAuth: []
summary: 更新引导卷
@@ -1576,8 +3625,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.Compartment'
+ type: array
security:
- BearerAuth: []
summary: 返回筛选器用区间列表:未开多区间支持返回空数组
@@ -1595,8 +3645,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.RegionSubscriptionView'
+ type: array
security:
- BearerAuth: []
summary: 返回筛选器用区域列表:未开多区域支持只含默认区域
@@ -1614,8 +3665,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.Compartment'
+ type: array
security:
- BearerAuth: []
summary: 列出租户下全部 ACTIVE compartment
@@ -1654,8 +3706,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.CostItem'
+ type: array
security:
- BearerAuth: []
summary: 配置成本快照
@@ -1673,8 +3726,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.IdentityDomain'
+ type: array
security:
- BearerAuth: []
summary: 租户身份域列表
@@ -1696,8 +3750,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.IdentityProviderInfo'
+ type: array
security:
- BearerAuth: []
summary: 身份提供商列表
@@ -1724,8 +3779,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.IdentityProviderInfo'
security:
- BearerAuth: []
summary: 创建身份提供商(SAML)
@@ -1783,8 +3837,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.IdentityProviderInfo'
security:
- BearerAuth: []
summary: 激活身份提供商
@@ -1806,8 +3859,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.IdentitySettingInfo'
security:
- BearerAuth: []
summary: 身份域设置
@@ -1834,8 +3886,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.IdentitySettingInfo'
security:
- BearerAuth: []
summary: 更新身份域设置
@@ -1853,8 +3904,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.Image'
+ type: array
security:
- BearerAuth: []
summary: 镜像列表
@@ -1877,8 +3929,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Image'
security:
- BearerAuth: []
summary: 镜像详情
@@ -1896,8 +3947,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.Instance'
+ type: array
security:
- BearerAuth: []
summary: 实例列表
@@ -1918,10 +3970,9 @@ paths:
$ref: '#/definitions/internal_api.createInstanceRequest'
responses:
"201":
- description: Created
+ description: 部分成功仍 201,errors 为逐台失败信息
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.createInstancesResponse'
security:
- BearerAuth: []
summary: 创建实例
@@ -1964,8 +4015,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Instance'
security:
- BearerAuth: []
summary: 实例详情
@@ -1993,8 +4043,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Instance'
security:
- BearerAuth: []
summary: 更新实例
@@ -2023,8 +4072,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Instance'
security:
- BearerAuth: []
summary: 实例电源操作(启停/重启)
@@ -2047,8 +4095,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.BootVolumeAttachment'
+ type: array
security:
- BearerAuth: []
summary: 引导卷附件列表
@@ -2076,8 +4125,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.BootVolumeAttachment'
security:
- BearerAuth: []
summary: 附加引导卷
@@ -2106,8 +4154,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.publicIpResponse'
security:
- BearerAuth: []
summary: '---- 实例 IP ----'
@@ -2130,8 +4177,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.ConsoleConnection'
+ type: array
security:
- BearerAuth: []
summary: 实例控制台连接列表
@@ -2159,8 +4207,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.ConsoleConnection'
security:
- BearerAuth: []
summary: 创建实例控制台连接
@@ -2186,11 +4233,10 @@ paths:
schema:
type: object
responses:
- "200":
- description: sessionId 与 wsPath
+ "201":
+ description: sessionId 与 type
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.webConsoleSessionResponse'
security:
- BearerAuth: []
summary: 创建网页控制台会话
@@ -2239,8 +4285,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.ipv6AddressResponse'
security:
- BearerAuth: []
summary: 实例添加 IPv6 地址
@@ -2269,8 +4314,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.BootVolumeAttachment'
security:
- BearerAuth: []
summary: 更换实例引导卷
@@ -2293,8 +4337,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.InstanceTraffic'
security:
- BearerAuth: []
summary: '---- 流量与成本 ----'
@@ -2317,8 +4360,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.Vnic'
+ type: array
security:
- BearerAuth: []
summary: 实例 VNIC 列表
@@ -2346,8 +4390,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Vnic'
security:
- BearerAuth: []
summary: 附加 VNIC
@@ -2370,8 +4413,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.VolumeAttachment'
+ type: array
security:
- BearerAuth: []
summary: 卷附件列表
@@ -2399,8 +4443,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.VolumeAttachment'
security:
- BearerAuth: []
summary: 附加块存储卷
@@ -2418,8 +4461,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.LimitValue'
+ type: array
security:
- BearerAuth: []
summary: 服务限额查询
@@ -2437,8 +4481,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.LimitService'
+ type: array
security:
- BearerAuth: []
summary: 限额服务列表
@@ -2471,8 +4516,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.RelayView'
security:
- BearerAuth: []
summary: 查询 OCI 侧链路状态与关键事件清单
@@ -2489,8 +4533,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.RelayView'
security:
- BearerAuth: []
summary: 一键建立回传链路
@@ -2523,8 +4566,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.logWebhookStatusResponse'
security:
- BearerAuth: []
summary: 查询配置的回调地址
@@ -2541,8 +4583,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.LogWebhookInfo'
security:
- BearerAuth: []
summary: 生成
@@ -2564,8 +4605,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.NotificationRecipients'
security:
- BearerAuth: []
summary: '---- 域通知收件人与密码策略 ----'
@@ -2592,8 +4632,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.NotificationRecipients'
security:
- BearerAuth: []
summary: 更新通知收件人
@@ -2615,8 +4654,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.PasswordPolicyInfo'
+ type: array
security:
- BearerAuth: []
summary: 密码策略列表
@@ -2649,8 +4689,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.PasswordPolicyInfo'
security:
- BearerAuth: []
summary: 更新密码策略
@@ -2668,8 +4707,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.RegionSubscriptionView'
+ type: array
security:
- BearerAuth: []
summary: 区域订阅列表
@@ -2692,8 +4732,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_service.RegionSubscriptionView'
+ type: array
security:
- BearerAuth: []
summary: 订阅新区域
@@ -2713,10 +4754,9 @@ paths:
type: string
responses:
"200":
- description: OK
+ description: SAML 元数据 XML(附件下载)
schema:
- additionalProperties: true
- type: object
+ type: file
security:
- BearerAuth: []
summary: 下载 SAML 元数据
@@ -2734,8 +4774,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.SecurityList'
+ type: array
security:
- BearerAuth: []
summary: 安全列表清单
@@ -2758,8 +4799,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.SecurityList'
security:
- BearerAuth: []
summary: 创建安全列表
@@ -2802,8 +4842,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.SecurityList'
security:
- BearerAuth: []
summary: 安全列表详情
@@ -2831,8 +4870,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.SecurityList'
security:
- BearerAuth: []
summary: 更新安全列表
@@ -2850,8 +4888,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.ComputeShape'
+ type: array
security:
- BearerAuth: []
summary: 实例形状列表
@@ -2879,8 +4918,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.SignOnRuleInfo'
security:
- BearerAuth: []
summary: 创建 MFA 豁免规则
@@ -2927,8 +4965,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.SignOnRuleInfo'
+ type: array
security:
- BearerAuth: []
summary: 单点登录规则列表
@@ -2946,8 +4985,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.Subnet'
+ type: array
security:
- BearerAuth: []
summary: 子网列表
@@ -2970,8 +5010,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Subnet'
security:
- BearerAuth: []
summary: 创建子网
@@ -3014,8 +5053,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Subnet'
security:
- BearerAuth: []
summary: 子网详情
@@ -3043,8 +5081,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.Subnet'
security:
- BearerAuth: []
summary: 更新子网
@@ -3062,8 +5099,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.SubscriptionInfo'
+ type: array
security:
- BearerAuth: []
summary: 订阅列表
@@ -3086,8 +5124,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.SubscriptionDetail'
security:
- BearerAuth: []
summary: 订阅详情
@@ -3109,8 +5146,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.TenantUser'
+ type: array
security:
- BearerAuth: []
summary: 租户 IAM 用户列表
@@ -3137,8 +5175,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.TenantUser'
security:
- BearerAuth: []
summary: 创建租户 IAM 用户
@@ -3189,8 +5226,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.TenantUserDetail'
security:
- BearerAuth: []
summary: 租户用户详情
@@ -3222,8 +5258,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.TenantUser'
security:
- BearerAuth: []
summary: 更新租户 IAM 用户
@@ -3246,8 +5281,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.deletedApiKeysResponse'
security:
- BearerAuth: []
summary: 清除用户全部 API Key
@@ -3274,8 +5308,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.deletedTotpResponse'
security:
- BearerAuth: []
summary: 清除用户 MFA 设备
@@ -3300,10 +5333,9 @@ paths:
type: string
responses:
"200":
- description: OK
+ description: 一次性明文密码
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.passwordResponse'
security:
- BearerAuth: []
summary: 重置租户用户密码
@@ -3321,8 +5353,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.VCN'
+ type: array
security:
- BearerAuth: []
summary: VCN 列表
@@ -3345,8 +5378,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.VCN'
security:
- BearerAuth: []
summary: 创建 VCN
@@ -3389,8 +5421,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.VCN'
security:
- BearerAuth: []
summary: VCN 详情
@@ -3418,8 +5449,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_oci.VCN'
security:
- BearerAuth: []
summary: 更新 VCN
@@ -3448,8 +5478,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.ipv6StepsResponse'
security:
- BearerAuth: []
summary: VCN 启用 IPv6
@@ -3465,10 +5494,9 @@ paths:
type: integer
responses:
"200":
- description: OK
+ description: config 与 changes 字段变更对照
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.configChangesResponse'
security:
- BearerAuth: []
summary: 验证配置连通性并刷新画像
@@ -3518,8 +5546,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.addressResponse'
security:
- BearerAuth: []
summary: 为指定 VNIC 添加 IPv6
@@ -3558,8 +5585,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.BlockVolume'
+ type: array
security:
- BearerAuth: []
summary: 块存储卷列表
@@ -3571,8 +5599,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.Overview'
security:
- BearerAuth: []
summary: 返回总览页聚合数据
@@ -3584,8 +5611,7 @@ paths:
"200":
description: items
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_service_ProxyView'
security:
- BearerAuth: []
summary: 代理列表
@@ -3603,8 +5629,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.ProxyView'
security:
- BearerAuth: []
summary: 创建代理
@@ -3643,8 +5668,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.ProxyView'
security:
- BearerAuth: []
summary: 更新代理
@@ -3662,8 +5686,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.ProxyView'
security:
- BearerAuth: []
summary: 手动重测代理出口地区,同步返回最新视图
@@ -3687,8 +5710,7 @@ paths:
"200":
description: usedBy
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.usedByResponse'
security:
- BearerAuth: []
summary: 设置代理关联的租户全集
@@ -3707,8 +5729,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.ImportResult'
security:
- BearerAuth: []
summary: 批量导入代理
@@ -3720,8 +5741,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_oci.RegionInfo'
+ type: array
security:
- BearerAuth: []
summary: 返回本地维护的完整区域表
@@ -3733,8 +5755,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView'
security:
- BearerAuth: []
summary: 返回全部通知渠道的脱敏视图
@@ -3758,8 +5779,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyChannelView'
security:
- BearerAuth: []
summary: 保存单渠道配置并返回全渠道最新视图
@@ -3787,8 +5807,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.NotifyEventsView'
security:
- BearerAuth: []
summary: 返回全部通知事件开关
@@ -3806,8 +5825,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.NotifyEventsView'
security:
- BearerAuth: []
summary: 全量保存五个事件开关并返回最新值
@@ -3819,8 +5837,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.itemsResponse-oci-portal_internal_service_NotifyTemplateView'
security:
- BearerAuth: []
summary: 返回全部通知模板
@@ -3906,8 +5923,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.SecuritySettings'
security:
- BearerAuth: []
summary: 返回安全设置
@@ -3925,8 +5941,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.SecuritySettings'
security:
- BearerAuth: []
summary: 保存安全设置并返回最新值
@@ -3938,8 +5953,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.TaskSettingsView'
security:
- BearerAuth: []
summary: 返回任务行为设置
@@ -3957,8 +5971,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.TaskSettingsView'
security:
- BearerAuth: []
summary: 保存任务行为设置并返回最新值
@@ -3970,8 +5983,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.TelegramView'
security:
- BearerAuth: []
summary: 返回脱敏后的 Telegram 配置,绝不回 token 明文
@@ -3989,8 +6001,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_service.TelegramView'
security:
- BearerAuth: []
summary: 保存配置并返回最新脱敏视图
@@ -4012,8 +6023,7 @@ paths:
"200":
description: items 与 total
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.pagedResponse-oci-portal_internal_model_SystemLog'
security:
- BearerAuth: []
summary: 系统操作日志列表
@@ -4026,8 +6036,7 @@ paths:
description: OK
schema:
items:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.Task'
type: array
security:
- BearerAuth: []
@@ -4046,8 +6055,7 @@ paths:
"201":
description: Created
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.Task'
security:
- BearerAuth: []
summary: 创建任务
@@ -4080,8 +6088,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.Task'
security:
- BearerAuth: []
summary: 任务详情
@@ -4104,8 +6111,7 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/oci-portal_internal_model.Task'
security:
- BearerAuth: []
summary: 更新任务
@@ -4123,8 +6129,9 @@ paths:
"200":
description: OK
schema:
- additionalProperties: true
- type: object
+ items:
+ $ref: '#/definitions/oci-portal_internal_model.TaskLog'
+ type: array
security:
- BearerAuth: []
summary: 任务执行日志
@@ -4142,13 +6149,11 @@ paths:
"202":
description: Accepted
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.triggerResponse'
"409":
description: 任务正在执行中
schema:
- additionalProperties: true
- type: object
+ $ref: '#/definitions/internal_api.errorResponse'
security:
- BearerAuth: []
summary: 立即执行任务(异步触发,结果经任务日志轮询获取)
@@ -4174,9 +6179,7 @@ paths:
"403":
description: 时间戳超窗或证书源非 Oracle 域
schema:
- additionalProperties:
- type: string
- type: object
+ $ref: '#/definitions/internal_api.errorResponse'
"404":
description: secret 无效(不暴露端点存在性)
summary: OCI 日志回传入口(ONS HTTPS 订阅投递)
diff --git a/internal/aiwire/anyjson.go b/internal/aiwire/anyjson.go
new file mode 100644
index 0000000..f5ae4b6
--- /dev/null
+++ b/internal/aiwire/anyjson.go
@@ -0,0 +1,5 @@
+package aiwire
+
+// AnyJSON 仅供 swagger 文档渲染:经 .swaggo 全局替换,代表任意 JSON 值
+// (json.RawMessage 与 string/数组联合类型),运行时代码不使用。
+type AnyJSON struct{}
diff --git a/internal/aiwire/moderations.go b/internal/aiwire/moderations.go
new file mode 100644
index 0000000..7d35cce
--- /dev/null
+++ b/internal/aiwire/moderations.go
@@ -0,0 +1,45 @@
+package aiwire
+
+import "encoding/json"
+
+// ModerationsRequest 是 /ai/v1/moderations 请求体;input 兼容 OpenAI 的
+// string 与 []string 两种形态,model 字段接受但忽略(上游为服务级 API)。
+type ModerationsRequest struct {
+ Model string `json:"model,omitempty"`
+ Input json.RawMessage `json:"input"`
+}
+
+// ModerationPii 是一处 PII 命中(OCI 扩展,OpenAI 协议无对应物)。
+type ModerationPii struct {
+ Text string `json:"text"`
+ Label string `json:"label"`
+ Score float64 `json:"score"`
+ Offset int `json:"offset"`
+ Length int `json:"length"`
+}
+
+// ModerationResult 是一条输入的审核结果:categories / category_scores 用
+// OCI 原生维度(overall / blocklist / prompt_injection),pii 为扩展字段。
+type ModerationResult struct {
+ Flagged bool `json:"flagged"`
+ Categories map[string]bool `json:"categories"`
+ CategoryScores map[string]float64 `json:"category_scores"`
+ Pii []ModerationPii `json:"pii,omitempty"`
+}
+
+// ModerationsResponse 是 /ai/v1/moderations 响应体(OpenAI moderations 外壳)。
+type ModerationsResponse struct {
+ ID string `json:"id"`
+ Model string `json:"model"`
+ Results []ModerationResult `json:"results"`
+}
+
+// SpeechRequest 描述 /ai/v1/audio/speech 请求体的已知字段(文档用途)。
+// 直通端点实际按原样透传,未列字段与 xAI 专属参数(如 output_format)同样保留。
+type SpeechRequest struct {
+ Model string `json:"model"`
+ Input string `json:"input"`
+ Voice string `json:"voice,omitempty"`
+ ResponseFormat string `json:"response_format,omitempty"`
+ Language string `json:"language,omitempty"`
+}
diff --git a/internal/aiwire/rerank.go b/internal/aiwire/rerank.go
new file mode 100644
index 0000000..c5f87eb
--- /dev/null
+++ b/internal/aiwire/rerank.go
@@ -0,0 +1,28 @@
+package aiwire
+
+// RerankRequest 是 /ai/v1/rerank 请求体(Jina / Cohere 通行风格)。
+type RerankRequest struct {
+ Model string `json:"model"`
+ Query string `json:"query"`
+ Documents []string `json:"documents"`
+ TopN *int `json:"top_n,omitempty"`
+ ReturnDocuments *bool `json:"return_documents,omitempty"`
+}
+
+// RerankDocument 包装原文,仅在 return_documents 时返回。
+type RerankDocument struct {
+ Text string `json:"text"`
+}
+
+// RerankResult 是一条重排结果:index 指向请求 documents 下标。
+type RerankResult struct {
+ Index int `json:"index"`
+ RelevanceScore float64 `json:"relevance_score"`
+ Document *RerankDocument `json:"document,omitempty"`
+}
+
+// RerankResponse 是 /ai/v1/rerank 响应体。
+type RerankResponse struct {
+ Model string `json:"model"`
+ Results []RerankResult `json:"results"`
+}
diff --git a/internal/aiwire/responses.go b/internal/aiwire/responses.go
index f735a24..f4b1e5c 100644
--- a/internal/aiwire/responses.go
+++ b/internal/aiwire/responses.go
@@ -184,3 +184,16 @@ type RespError struct {
type RespIncomplete struct {
Reason string `json:"reason"`
}
+
+// RespResponse 描述 /ai/v1/responses 非流式响应的常用顶层字段(文档用途)。
+// 直通端点原样返回上游 JSON,未列字段(reasoning、incomplete_details 等)同样保留。
+type RespResponse struct {
+ ID string `json:"id"`
+ Object string `json:"object"`
+ CreatedAt int64 `json:"created_at"`
+ Status string `json:"status"`
+ Model string `json:"model"`
+ Output json.RawMessage `json:"output"`
+ Usage *RespUsage `json:"usage,omitempty"`
+ Error *RespError `json:"error,omitempty"`
+}
diff --git a/internal/api/about.go b/internal/api/about.go
index 4941924..0e6cabe 100644
--- a/internal/api/about.go
+++ b/internal/api/about.go
@@ -30,7 +30,7 @@ func SetAboutRuntime(dbDriver, dbPath string) {
//
// @Summary 返回构建、运行时长与资源占用信息,「设置 · 关于」页展示
// @Tags 设置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} aboutResponse
// @Security BearerAuth
// @Router /api/v1/about [get]
func about(c *gin.Context) {
diff --git a/internal/api/aiadmin.go b/internal/api/aiadmin.go
index 19c8e05..0c87489 100644
--- a/internal/api/aiadmin.go
+++ b/internal/api/aiadmin.go
@@ -6,6 +6,9 @@ import (
"github.com/gin-gonic/gin"
+ _ "oci-portal/internal/aiwire" // swagger 注解引用
+ _ "oci-portal/internal/model" // swagger 注解引用
+
"oci-portal/internal/service"
)
@@ -18,7 +21,7 @@ type aiAdminHandler struct {
// @Summary ---- 密钥 ----
// @Tags AI 管理
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[model.AiKey]
// @Security BearerAuth
// @Router /api/v1/ai-keys [get]
func (h *aiAdminHandler) listKeys(c *gin.Context) {
@@ -35,7 +38,7 @@ func (h *aiAdminHandler) listKeys(c *gin.Context) {
// @Summary 生成密钥
// @Tags AI 管理
// @Param body body object true "请求体(见接口说明)"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} aiKeyCreateResponse "key 为明文密钥,仅本次返回"
// @Security BearerAuth
// @Router /api/v1/ai-keys [post]
func (h *aiAdminHandler) createKey(c *gin.Context) {
@@ -110,7 +113,7 @@ func (h *aiAdminHandler) deleteKey(c *gin.Context) {
// @Tags AI 管理
// @Param id path int true "配置 ID"
// @Param body body object true "请求体(见接口说明)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} model.AiKey
// @Security BearerAuth
// @Router /api/v1/ai-keys/{id}/content-log [put]
func (h *aiAdminHandler) updateKeyContentLog(c *gin.Context) {
@@ -137,7 +140,7 @@ func (h *aiAdminHandler) updateKeyContentLog(c *gin.Context) {
//
// @Summary 分页查询内容日志
// @Tags AI 管理
-// @Success 200 {object} map[string]any
+// @Success 200 {object} pagedResponse[model.AiCallLog]
// @Security BearerAuth
// @Router /api/v1/ai-content-logs [get]
func (h *aiAdminHandler) listContentLogs(c *gin.Context) {
@@ -157,7 +160,7 @@ func (h *aiAdminHandler) listContentLogs(c *gin.Context) {
// @Summary ---- 渠道 ----
// @Tags AI 管理
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[model.AiChannel]
// @Security BearerAuth
// @Router /api/v1/ai-channels [get]
func (h *aiAdminHandler) listChannels(c *gin.Context) {
@@ -172,7 +175,7 @@ func (h *aiAdminHandler) listChannels(c *gin.Context) {
// @Summary 创建 AI 渠道
// @Tags AI 管理
// @Param body body service.ChannelInput true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} model.AiChannel
// @Security BearerAuth
// @Router /api/v1/ai-channels [post]
func (h *aiAdminHandler) createChannel(c *gin.Context) {
@@ -236,7 +239,7 @@ func (h *aiAdminHandler) deleteChannel(c *gin.Context) {
// @Summary 触发探测:服务可见性 + 模型同步 + 配额试调,返回更新后的渠道
// @Tags AI 管理
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} model.AiChannel
// @Security BearerAuth
// @Router /api/v1/ai-channels/{id}/probe [post]
func (h *aiAdminHandler) probeChannel(c *gin.Context) {
@@ -255,7 +258,7 @@ func (h *aiAdminHandler) probeChannel(c *gin.Context) {
// @Summary 同步渠道模型缓存
// @Tags AI 管理
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[model.AiModelCache]
// @Security BearerAuth
// @Router /api/v1/ai-channels/{id}/sync-models [post]
func (h *aiAdminHandler) syncChannelModels(c *gin.Context) {
@@ -275,7 +278,7 @@ func (h *aiAdminHandler) syncChannelModels(c *gin.Context) {
// @Summary ---- 聚合模型与调用日志 ----
// @Tags AI 管理
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[aiwire.Model]
// @Security BearerAuth
// @Router /api/v1/ai-models [get]
func (h *aiAdminHandler) gatewayModels(c *gin.Context) {
@@ -291,7 +294,7 @@ func (h *aiAdminHandler) gatewayModels(c *gin.Context) {
// @Summary 模型黑名单列表
// @Tags AI 管理
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[model.AiModelBlacklist]
// @Security BearerAuth
// @Router /api/v1/ai-blacklist [get]
func (h *aiAdminHandler) listBlacklist(c *gin.Context) {
@@ -308,7 +311,7 @@ func (h *aiAdminHandler) listBlacklist(c *gin.Context) {
// @Summary 添加模型黑名单
// @Tags AI 管理
// @Param body body object true "请求体:{name: 模型名}"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} itemResponse[model.AiModelBlacklist]
// @Security BearerAuth
// @Router /api/v1/ai-blacklist [post]
func (h *aiAdminHandler) addBlacklist(c *gin.Context) {
@@ -347,7 +350,7 @@ func (h *aiAdminHandler) removeBlacklist(c *gin.Context) {
// @Summary AI 调用日志列表
// @Tags AI 管理
-// @Success 200 {object} map[string]any
+// @Success 200 {object} pagedResponse[model.AiContentLog]
// @Security BearerAuth
// @Router /api/v1/ai-logs [get]
func (h *aiAdminHandler) listLogs(c *gin.Context) {
diff --git a/internal/api/aigateway.go b/internal/api/aigateway.go
index 5859550..ceb385d 100644
--- a/internal/api/aigateway.go
+++ b/internal/api/aigateway.go
@@ -165,8 +165,8 @@ func fillUsage(entry *model.AiCallLog, u *aiwire.Usage) {
//
// @Summary OpenAI 兼容向量嵌入
// @Tags AI 网关
-// @Param body body object true "OpenAI embeddings 请求体"
-// @Success 200 {object} map[string]any "OpenAI 兼容响应"
+// @Param body body aiwire.EmbeddingsRequest true "OpenAI embeddings 请求体"
+// @Success 200 {object} aiwire.EmbeddingsResponse "OpenAI 兼容响应"
// @Router /ai/v1/embeddings [post]
func (h *aiGatewayHandler) embeddings(c *gin.Context) {
var req aiwire.EmbeddingsRequest
@@ -218,8 +218,8 @@ const anthDefaultMaxTokens = 8192
//
// @Summary Anthropic Messages 兼容端点
// @Tags AI 网关
-// @Param body body object true "Anthropic messages 请求体(支持 stream;经 OCI OpenAI 兼容面直通;max_tokens 可缺省,默认 8192)"
-// @Success 200 {object} map[string]any "Anthropic 兼容响应(流式为 SSE)"
+// @Param body body aiwire.MessagesRequest true "Anthropic messages 请求体(支持 stream;经 OCI OpenAI 兼容面直通;max_tokens 可缺省,默认 8192)"
+// @Success 200 {object} aiwire.MessagesResponse "Anthropic 兼容响应(非流式;流式为 SSE 事件序列)"
// @Router /ai/v1/messages [post]
func (h *aiGatewayHandler) messages(c *gin.Context) {
var req aiwire.MessagesRequest
@@ -381,8 +381,8 @@ func writeAnthEvents(c *gin.Context, events []service.AnthEvent) {
//
// @Summary OpenAI Chat Completions 兼容端点
// @Tags AI 网关
-// @Param body body object true "OpenAI chat/completions 请求体(支持 stream;经 Responses 转换直通)"
-// @Success 200 {object} map[string]any "OpenAI 兼容响应(流式为 SSE,末尾 data: [DONE])"
+// @Param body body aiwire.ChatRequest true "OpenAI chat/completions 请求体(支持 stream;经 Responses 转换直通)"
+// @Success 200 {object} aiwire.ChatResponse "OpenAI 兼容响应(非流式;流式为 SSE,末尾 data: [DONE])"
// @Router /ai/v1/chat/completions [post]
func (h *aiGatewayHandler) chatCompletions(c *gin.Context) {
var req aiwire.ChatRequest
@@ -528,7 +528,7 @@ func writeChatChunks(c *gin.Context, chunks []aiwire.ChatChunk) {
//
// @Summary 可用模型列表
// @Tags AI 网关
-// @Success 200 {object} map[string]any "OpenAI 兼容 models 列表"
+// @Success 200 {object} aiwire.ModelList "OpenAI 兼容 models 列表"
// @Router /ai/v1/models [get]
func (h *aiGatewayHandler) listModels(c *gin.Context) {
list, err := h.gw.GatewayModels(c.Request.Context(), keyGroup(c))
@@ -552,8 +552,8 @@ func (h *aiGatewayHandler) listModels(c *gin.Context) {
//
// @Summary OpenAI Responses 兼容端点
// @Tags AI 网关
-// @Param body body object true "OpenAI responses 请求体(支持 stream;web_search/x_search 服务端工具仅非流式)"
-// @Success 200 {object} map[string]any "OpenAI 兼容响应(流式为 SSE)"
+// @Param body body aiwire.RespRequest true "OpenAI responses 请求体(支持 stream;服务端工具 web_search/x_search/code_interpreter/mcp 含流式;未列字段原样透传上游)"
+// @Success 200 {object} aiwire.RespResponse "OpenAI 兼容响应(非流式;流式为 SSE);直通仅建模常用字段,未列字段原样返回"
// @Router /ai/v1/responses [post]
func (h *aiGatewayHandler) responses(c *gin.Context) {
raw, err := c.GetRawData()
diff --git a/internal/api/aigateway_extras.go b/internal/api/aigateway_extras.go
new file mode 100644
index 0000000..51130ef
--- /dev/null
+++ b/internal/api/aigateway_extras.go
@@ -0,0 +1,119 @@
+package api
+
+import (
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/gin-gonic/gin"
+
+ "oci-portal/internal/aiwire"
+ "oci-portal/internal/service"
+)
+
+// audioSpeech 是 OpenAI /ai/v1/audio/speech 端点(TTS,直通兼容面)。
+//
+// @Summary OpenAI Audio Speech 兼容端点(文本转语音)
+// @Tags AI 网关
+// @Param body body aiwire.SpeechRequest true "OpenAI audio speech 请求体(model/input 必填,voice 见 xAI Grok Voice 列表,language 缺省 auto;未列字段原样透传)"
+// @Success 200 {file} binary "音频字节(Content-Type 透传上游,默认 audio/mpeg)"
+// @Router /ai/v1/audio/speech [post]
+func (h *aiGatewayHandler) audioSpeech(c *gin.Context) {
+ raw, err := c.GetRawData()
+ if err != nil {
+ aiError(c, http.StatusBadRequest, "invalid_request_error", err.Error())
+ return
+ }
+ modelName, body, err := service.SpeechBodyNormalize(raw)
+ if err != nil {
+ aiError(c, http.StatusBadRequest, "invalid_request_error", err.Error())
+ return
+ }
+ if !checkKeyModel(c, modelName) {
+ return
+ }
+ start := time.Now()
+ audio, contentType, meta, err := h.gw.Speech(c.Request.Context(), modelName, body, keyGroup(c))
+ entry := h.logEntry(c, "speech", modelName, false, meta, start)
+ if err != nil {
+ upstreamError(c, err)
+ entry.ErrMsg = err.Error()
+ h.logFailure(c, entry, string(raw))
+ return
+ }
+ entry.Status = http.StatusOK
+ callID := h.gw.LogCall(entry)
+ h.maybeLogContent(c, callID, "speech", modelName, false, string(raw), nil)
+ if contentType == "" {
+ contentType = "audio/mpeg"
+ }
+ c.Data(http.StatusOK, contentType, audio)
+}
+
+// rerank 是 /ai/v1/rerank 端点(Jina / Cohere 风格文档重排)。
+//
+// @Summary 文档重排端点(Cohere Rerank)
+// @Tags AI 网关
+// @Param body body aiwire.RerankRequest true "重排请求体(model/query/documents 必填,可选 top_n/return_documents)"
+// @Success 200 {object} aiwire.RerankResponse "重排结果(results[].index 指向入参下标)"
+// @Router /ai/v1/rerank [post]
+func (h *aiGatewayHandler) rerank(c *gin.Context) {
+ var req aiwire.RerankRequest
+ if err := c.ShouldBindJSON(&req); err != nil {
+ aiError(c, http.StatusBadRequest, "invalid_request_error", err.Error())
+ return
+ }
+ if strings.TrimSpace(req.Model) == "" || strings.TrimSpace(req.Query) == "" || len(req.Documents) == 0 {
+ aiError(c, http.StatusBadRequest, "invalid_request_error", "model、query 与 documents 不能为空")
+ return
+ }
+ if !checkKeyModel(c, req.Model) {
+ return
+ }
+ start := time.Now()
+ resp, meta, err := h.gw.Rerank(c.Request.Context(), req, keyGroup(c))
+ entry := h.logEntry(c, "rerank", req.Model, false, meta, start)
+ if err != nil {
+ upstreamError(c, err)
+ entry.ErrMsg = err.Error()
+ h.logFailure(c, entry, req)
+ return
+ }
+ entry.Status = http.StatusOK
+ callID := h.gw.LogCall(entry)
+ h.maybeLogContent(c, callID, "rerank", req.Model, false, req, resp)
+ c.JSON(http.StatusOK, resp)
+}
+
+// moderations 是 /ai/v1/moderations 端点(OpenAI 外壳映射 OCI Guardrails)。
+//
+// @Summary 内容审核端点(OCI Guardrails)
+// @Tags AI 网关
+// @Param body body aiwire.ModerationsRequest true "审核请求体(input 为字符串或字符串数组,单次至多 8 条;model 接受但忽略)"
+// @Success 200 {object} aiwire.ModerationsResponse "审核结果(categories/category_scores 为 overall/blocklist/prompt_injection,pii 为扩展字段)"
+// @Router /ai/v1/moderations [post]
+func (h *aiGatewayHandler) moderations(c *gin.Context) {
+ var req aiwire.ModerationsRequest
+ if err := c.ShouldBindJSON(&req); err != nil {
+ aiError(c, http.StatusBadRequest, "invalid_request_error", err.Error())
+ return
+ }
+ inputs, err := service.ModerationInputs(req.Input)
+ if err != nil {
+ aiError(c, http.StatusBadRequest, "invalid_request_error", err.Error())
+ return
+ }
+ start := time.Now()
+ resp, meta, err := h.gw.Moderations(c.Request.Context(), aiRandID("modr_"), inputs, keyGroup(c))
+ entry := h.logEntry(c, "moderations", "oci-guardrails", false, meta, start)
+ if err != nil {
+ upstreamError(c, err)
+ entry.ErrMsg = err.Error()
+ h.logFailure(c, entry, req)
+ return
+ }
+ entry.Status = http.StatusOK
+ callID := h.gw.LogCall(entry)
+ h.maybeLogContent(c, callID, "moderations", "oci-guardrails", false, req, resp)
+ c.JSON(http.StatusOK, resp)
+}
diff --git a/internal/api/aigateway_test.go b/internal/api/aigateway_test.go
index 081662c..ff6a8f1 100644
--- a/internal/api/aigateway_test.go
+++ b/internal/api/aigateway_test.go
@@ -95,6 +95,14 @@ func TestAiGatewayKeyModelRestrict(t *testing.T) {
{"chat completions 不支持内容块拒绝", "open-key-12345", "/ai/v1/chat/completions",
`{"model":"ghost-model","messages":[{"role":"user","content":[{"type":"input_audio"}]}]}`,
400, []string{"invalid_request_error"}},
+ {"audio speech 白名单外拦截", "limited-key-1234", "/ai/v1/audio/speech",
+ `{"model":"meta.llama-3.3-70b-instruct","input":"你好"}`, 404, deny},
+ {"rerank 白名单外拦截", "limited-key-1234", "/ai/v1/rerank",
+ `{"model":"meta.llama-3.3-70b-instruct","query":"q","documents":["d"]}`, 404, deny},
+ {"rerank 缺 documents 拒绝", "open-key-12345", "/ai/v1/rerank",
+ `{"model":"ghost-model","query":"q"}`, 400, []string{"invalid_request_error"}},
+ {"moderations 空 input 拒绝", "open-key-12345", "/ai/v1/moderations",
+ `{"input":[]}`, 400, []string{"invalid_request_error"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
diff --git a/internal/api/attachment.go b/internal/api/attachment.go
index 150ed94..b59e730 100644
--- a/internal/api/attachment.go
+++ b/internal/api/attachment.go
@@ -15,7 +15,7 @@ import (
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body object true "请求体(见接口说明)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} publicIpResponse
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/change-public-ip [post]
func (h *ociConfigHandler) changePublicIP(c *gin.Context) {
@@ -40,7 +40,7 @@ func (h *ociConfigHandler) changePublicIP(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body object true "请求体(见接口说明)"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} ipv6AddressResponse
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/ipv6-addresses [post]
func (h *ociConfigHandler) addInstanceIpv6(c *gin.Context) {
@@ -92,7 +92,7 @@ type attachVnicRequest struct {
// @Tags 计算
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.Vnic
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/vnics [get]
func (h *ociConfigHandler) listInstanceVnics(c *gin.Context) {
@@ -113,7 +113,7 @@ func (h *ociConfigHandler) listInstanceVnics(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body attachVnicRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.Vnic
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/vnics [post]
func (h *ociConfigHandler) attachVnic(c *gin.Context) {
@@ -160,7 +160,7 @@ func (h *ociConfigHandler) detachVnic(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param vnicId path string true "vnicId"
// @Param body body object true "请求体(见接口说明)"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} addressResponse
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/vnics/{vnicId}/ipv6-addresses [post]
func (h *ociConfigHandler) addVnicIpv6(c *gin.Context) {
@@ -195,7 +195,7 @@ type attachBootVolumeRequest struct {
// @Tags 存储
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.BootVolumeAttachment
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/boot-volume-attachments [get]
func (h *ociConfigHandler) listBootVolumeAttachments(c *gin.Context) {
@@ -216,7 +216,7 @@ func (h *ociConfigHandler) listBootVolumeAttachments(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body attachBootVolumeRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.BootVolumeAttachment
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/boot-volume-attachments [post]
func (h *ociConfigHandler) attachBootVolume(c *gin.Context) {
@@ -242,7 +242,7 @@ func (h *ociConfigHandler) attachBootVolume(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body attachBootVolumeRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.BootVolumeAttachment
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/replace-boot-volume [post]
func (h *ociConfigHandler) replaceBootVolume(c *gin.Context) {
@@ -293,7 +293,7 @@ type attachVolumeRequest struct {
// @Summary 块存储卷列表
// @Tags 存储
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.BlockVolume
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/volumes [get]
func (h *ociConfigHandler) listBlockVolumes(c *gin.Context) {
@@ -313,7 +313,7 @@ func (h *ociConfigHandler) listBlockVolumes(c *gin.Context) {
// @Tags 存储
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.VolumeAttachment
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/volume-attachments [get]
func (h *ociConfigHandler) listVolumeAttachments(c *gin.Context) {
@@ -334,7 +334,7 @@ func (h *ociConfigHandler) listVolumeAttachments(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body attachVolumeRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.VolumeAttachment
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/volume-attachments [post]
func (h *ociConfigHandler) attachVolume(c *gin.Context) {
diff --git a/internal/api/auth.go b/internal/api/auth.go
index 5372215..57ad755 100644
--- a/internal/api/auth.go
+++ b/internal/api/auth.go
@@ -32,9 +32,9 @@ type loginRequest struct {
// @Accept json
// @Produce json
// @Param body body loginRequest true "登录凭据"
-// @Success 200 {object} map[string]any "token 与 expiresAt"
-// @Failure 401 {object} map[string]string "凭据错误"
-// @Failure 428 {object} map[string]any "需要两步验证码(totpRequired=true)"
+// @Success 200 {object} tokenResponse "token 与 expiresAt"
+// @Failure 401 {object} errorResponse "凭据错误"
+// @Failure 428 {object} totpRequiredResponse "需要两步验证码(totpRequired=true)"
// @Router /api/v1/auth/login [post]
func (h *authHandler) login(c *gin.Context) {
var req loginRequest
diff --git a/internal/api/authx.go b/internal/api/authx.go
index 4eaba3b..965c7b7 100644
--- a/internal/api/authx.go
+++ b/internal/api/authx.go
@@ -8,6 +8,8 @@ import (
"github.com/gin-gonic/gin"
+ _ "oci-portal/internal/model" // swagger 注解引用
+
"oci-portal/internal/service"
)
@@ -23,7 +25,7 @@ type authxHandler struct {
//
// @Summary 两步验证状态
// @Tags 认证
-// @Success 200 {object} map[string]bool "enabled"
+// @Success 200 {object} enabledResponse "enabled"
// @Security BearerAuth
// @Router /api/v1/auth/totp [get]
func (h *authxHandler) totpStatus(c *gin.Context) {
@@ -39,8 +41,8 @@ func (h *authxHandler) totpStatus(c *gin.Context) {
//
// @Summary 发起两步验证设置
// @Tags 认证
-// @Success 200 {object} map[string]string "secret 与 otpauthUri"
-// @Failure 409 {object} map[string]string "已启用"
+// @Success 200 {object} totpSetupResponse "secret 与 otpauthUri"
+// @Failure 409 {object} errorResponse "已启用"
// @Security BearerAuth
// @Router /api/v1/auth/totp/setup [post]
func (h *authxHandler) totpSetup(c *gin.Context) {
@@ -128,7 +130,7 @@ func (h *authxHandler) respondFreshToken(c *gin.Context) {
//
// @Summary 撤销全部会话
// @Tags 认证
-// @Success 200 {object} map[string]string "新 token 与 expiresAt"
+// @Success 200 {object} tokenResponse "新 token 与 expiresAt"
// @Security BearerAuth
// @Router /api/v1/auth/revoke-sessions [post]
func (h *authxHandler) revokeSessions(c *gin.Context) {
@@ -146,7 +148,7 @@ func (h *authxHandler) revokeSessions(c *gin.Context) {
//
// @Summary 登录凭据摘要
// @Tags 认证
-// @Success 200 {object} map[string]any "username 与 passwordLoginDisabled"
+// @Success 200 {object} credentialsResponse "username 与 passwordLoginDisabled"
// @Security BearerAuth
// @Router /api/v1/auth/credentials [get]
func (h *authxHandler) getCredentials(c *gin.Context) {
@@ -167,7 +169,7 @@ func (h *authxHandler) getCredentials(c *gin.Context) {
// @Tags 认证
// @Param body body service.UpdateCredentialsInput true "新凭据(当前密码必验)"
// @Success 204 "已更新,请重新登录"
-// @Failure 401 {object} map[string]string "当前密码错误"
+// @Failure 401 {object} errorResponse "当前密码错误"
// @Security BearerAuth
// @Router /api/v1/auth/credentials [put]
func (h *authxHandler) updateCredentials(c *gin.Context) {
@@ -199,7 +201,7 @@ func (h *authxHandler) updateCredentials(c *gin.Context) {
// @Tags 认证
// @Param body body object true "{disabled: bool}"
// @Success 204 "已保存"
-// @Failure 409 {object} map[string]string "未绑定外部身份"
+// @Failure 409 {object} errorResponse "未绑定外部身份"
// @Security BearerAuth
// @Router /api/v1/auth/password-login [put]
func (h *authxHandler) updatePasswordLogin(c *gin.Context) {
@@ -230,7 +232,7 @@ func (h *authxHandler) updatePasswordLogin(c *gin.Context) {
//
// @Summary 外部登录 provider 列表
// @Tags 认证
-// @Success 200 {object} map[string]any "providers 与 passwordLoginDisabled"
+// @Success 200 {object} oauthProvidersResponse "providers 与 passwordLoginDisabled"
// @Router /api/v1/auth/oauth/providers [get]
func (h *authxHandler) oauthProviders(c *gin.Context) {
providers := h.oauth.Providers(c.Request.Context())
@@ -247,7 +249,7 @@ func (h *authxHandler) oauthProviders(c *gin.Context) {
// @Tags 认证
// @Param provider path string true "oidc / github"
// @Param mode query string false "bind=绑定当前账号(需 Bearer),缺省登录"
-// @Success 200 {object} map[string]string "url"
+// @Success 200 {object} urlResponse "url"
// @Router /api/v1/auth/oauth/{provider}/authorize [get]
func (h *authxHandler) oauthAuthorize(c *gin.Context) {
provider := c.Param("provider")
@@ -333,7 +335,7 @@ func oauthErrText(err error) string {
//
// @Summary 已绑定外部身份
// @Tags 认证
-// @Success 200 {object} map[string]any "items"
+// @Success 200 {object} itemsResponse[model.UserIdentity] "items"
// @Security BearerAuth
// @Router /api/v1/auth/identities [get]
func (h *authxHandler) identities(c *gin.Context) {
@@ -351,7 +353,7 @@ func (h *authxHandler) identities(c *gin.Context) {
// @Tags 认证
// @Param id path int true "身份 ID"
// @Success 204 "已解绑"
-// @Failure 409 {object} map[string]string "最后一个身份不可解绑"
+// @Failure 409 {object} errorResponse "最后一个身份不可解绑"
// @Security BearerAuth
// @Router /api/v1/auth/identities/{id} [delete]
func (h *authxHandler) unbindIdentity(c *gin.Context) {
diff --git a/internal/api/console.go b/internal/api/console.go
index 454ebdd..c93491a 100644
--- a/internal/api/console.go
+++ b/internal/api/console.go
@@ -4,6 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
+
+ _ "oci-portal/internal/oci" // swagger 注解引用
)
// ---- 控制台连接(VNC / 串口) ----
@@ -18,7 +20,7 @@ type createConsoleConnectionRequest struct {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body createConsoleConnectionRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.ConsoleConnection
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/console-connections [post]
func (h *ociConfigHandler) createConsoleConnection(c *gin.Context) {
@@ -43,7 +45,7 @@ func (h *ociConfigHandler) createConsoleConnection(c *gin.Context) {
// @Tags 计算
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.ConsoleConnection
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/console-connections [get]
func (h *ociConfigHandler) listConsoleConnections(c *gin.Context) {
diff --git a/internal/api/federation.go b/internal/api/federation.go
index 6871862..99690bc 100644
--- a/internal/api/federation.go
+++ b/internal/api/federation.go
@@ -41,7 +41,7 @@ func boolOr(v *bool, def bool) bool {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.IdentityProviderInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/identity-providers [get]
func (h *ociConfigHandler) listIdentityProviders(c *gin.Context) {
@@ -62,7 +62,7 @@ func (h *ociConfigHandler) listIdentityProviders(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param body body createIdpRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.IdentityProviderInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/identity-providers [post]
func (h *ociConfigHandler) createIdentityProvider(c *gin.Context) {
@@ -102,7 +102,7 @@ func (h *ociConfigHandler) createIdentityProvider(c *gin.Context) {
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param idpId path string true "idpId"
// @Param body body object true "请求体(见接口说明)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.IdentityProviderInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/identity-providers/{idpId}/activate [post]
func (h *ociConfigHandler) activateIdentityProvider(c *gin.Context) {
@@ -149,7 +149,7 @@ func (h *ociConfigHandler) deleteIdentityProvider(c *gin.Context) {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
-// @Success 200 {object} map[string]any
+// @Success 200 {file} file "SAML 元数据 XML(附件下载)"
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/saml-metadata [get]
func (h *ociConfigHandler) downloadSamlMetadata(c *gin.Context) {
@@ -170,7 +170,7 @@ func (h *ociConfigHandler) downloadSamlMetadata(c *gin.Context) {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.SignOnRuleInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/sign-on-rules [get]
func (h *ociConfigHandler) listSignOnRules(c *gin.Context) {
@@ -191,7 +191,7 @@ func (h *ociConfigHandler) listSignOnRules(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param body body object true "请求体(见接口说明)"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.SignOnRuleInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/sign-on-exemptions [post]
func (h *ociConfigHandler) createMfaExemption(c *gin.Context) {
diff --git a/internal/api/instance.go b/internal/api/instance.go
index e3e8b45..d11334e 100644
--- a/internal/api/instance.go
+++ b/internal/api/instance.go
@@ -11,7 +11,7 @@ import (
// @Summary 可用域列表
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} string
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/availability-domains [get]
func (h *ociConfigHandler) availabilityDomains(c *gin.Context) {
@@ -67,7 +67,7 @@ type instanceActionRequest struct {
// @Summary 实例列表
// @Tags 计算
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.Instance
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances [get]
func (h *ociConfigHandler) listInstances(c *gin.Context) {
@@ -87,7 +87,7 @@ func (h *ociConfigHandler) listInstances(c *gin.Context) {
// @Tags 计算
// @Param id path int true "配置 ID"
// @Param body body createInstanceRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} createInstancesResponse "部分成功仍 201,errors 为逐台失败信息"
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances [post]
func (h *ociConfigHandler) createInstance(c *gin.Context) {
@@ -147,7 +147,7 @@ func (h *ociConfigHandler) createInstance(c *gin.Context) {
// @Tags 计算
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.Instance
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId} [get]
func (h *ociConfigHandler) getInstance(c *gin.Context) {
@@ -168,7 +168,7 @@ func (h *ociConfigHandler) getInstance(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body updateInstanceRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.Instance
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId} [put]
func (h *ociConfigHandler) updateInstance(c *gin.Context) {
@@ -220,7 +220,7 @@ func (h *ociConfigHandler) terminateInstance(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
// @Param body body instanceActionRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.Instance
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/action [post]
func (h *ociConfigHandler) instanceAction(c *gin.Context) {
@@ -253,7 +253,7 @@ type updateBootVolumeRequest struct {
// @Summary 引导卷列表
// @Tags 存储
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.BootVolume
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/boot-volumes [get]
func (h *ociConfigHandler) listBootVolumes(c *gin.Context) {
@@ -273,7 +273,7 @@ func (h *ociConfigHandler) listBootVolumes(c *gin.Context) {
// @Tags 存储
// @Param id path int true "配置 ID"
// @Param bootVolumeId path string true "bootVolumeId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.BootVolume
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/boot-volumes/{bootVolumeId} [get]
func (h *ociConfigHandler) getBootVolume(c *gin.Context) {
@@ -294,7 +294,7 @@ func (h *ociConfigHandler) getBootVolume(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param bootVolumeId path string true "bootVolumeId"
// @Param body body updateBootVolumeRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.BootVolume
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/boot-volumes/{bootVolumeId} [put]
func (h *ociConfigHandler) updateBootVolume(c *gin.Context) {
diff --git a/internal/api/logevent.go b/internal/api/logevent.go
index 98ebf8d..0d34a4e 100644
--- a/internal/api/logevent.go
+++ b/internal/api/logevent.go
@@ -7,6 +7,8 @@ import (
"github.com/gin-gonic/gin"
+ _ "oci-portal/internal/model" // swagger 注解引用
+
"oci-portal/internal/service"
)
@@ -20,7 +22,7 @@ type logEventHandler struct {
// @Summary 查询配置的回调地址
// @Tags 任务与日志回传
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} logWebhookStatusResponse
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/log-webhook [get]
func (h *logEventHandler) getWebhook(c *gin.Context) {
@@ -45,7 +47,7 @@ func (h *logEventHandler) getWebhook(c *gin.Context) {
// @Summary 生成
// @Tags 任务与日志回传
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.LogWebhookInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/log-webhook [post]
func (h *logEventHandler) ensureWebhook(c *gin.Context) {
@@ -87,7 +89,7 @@ func (h *logEventHandler) revokeWebhook(c *gin.Context) {
// @Tags 任务与日志回传
// @Param configId query int false "按配置过滤"
// @Param q query string false "关键字"
-// @Success 200 {object} map[string]any "items 与 total"
+// @Success 200 {object} pagedResponse[model.LogEvent] "items 与 total"
// @Security BearerAuth
// @Router /api/v1/log-events [get]
func (h *logEventHandler) list(c *gin.Context) {
@@ -111,7 +113,7 @@ func (h *logEventHandler) list(c *gin.Context) {
// @Summary 查询 OCI 侧链路状态与关键事件清单
// @Tags 任务与日志回传
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.RelayView
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/log-relay [get]
func (h *logEventHandler) getRelay(c *gin.Context) {
@@ -132,7 +134,7 @@ func (h *logEventHandler) getRelay(c *gin.Context) {
// @Summary 一键建立回传链路
// @Tags 任务与日志回传
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.RelayView
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/log-relay [post]
func (h *logEventHandler) setupRelay(c *gin.Context) {
diff --git a/internal/api/network.go b/internal/api/network.go
index 5ad3b68..03058d9 100644
--- a/internal/api/network.go
+++ b/internal/api/network.go
@@ -11,7 +11,7 @@ import (
// @Summary 实例形状列表
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.ComputeShape
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/shapes [get]
func (h *ociConfigHandler) shapes(c *gin.Context) {
@@ -30,7 +30,7 @@ func (h *ociConfigHandler) shapes(c *gin.Context) {
// @Summary 镜像列表
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.Image
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/images [get]
func (h *ociConfigHandler) images(c *gin.Context) {
@@ -54,7 +54,7 @@ func (h *ociConfigHandler) images(c *gin.Context) {
// @Tags 租户配置
// @Param id path int true "配置 ID"
// @Param imageId path string true "imageId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.Image
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/images/{imageId} [get]
func (h *ociConfigHandler) getImage(c *gin.Context) {
@@ -89,7 +89,7 @@ type renameRequest struct {
// @Summary VCN 列表
// @Tags 网络
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.VCN
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/vcns [get]
func (h *ociConfigHandler) listVCNs(c *gin.Context) {
@@ -109,7 +109,7 @@ func (h *ociConfigHandler) listVCNs(c *gin.Context) {
// @Tags 网络
// @Param id path int true "配置 ID"
// @Param body body createVCNRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.VCN
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/vcns [post]
func (h *ociConfigHandler) createVCN(c *gin.Context) {
@@ -141,7 +141,7 @@ func (h *ociConfigHandler) createVCN(c *gin.Context) {
// @Tags 网络
// @Param id path int true "配置 ID"
// @Param vcnId path string true "vcnId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.VCN
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/vcns/{vcnId} [get]
func (h *ociConfigHandler) getVCN(c *gin.Context) {
@@ -162,7 +162,7 @@ func (h *ociConfigHandler) getVCN(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param vcnId path string true "vcnId"
// @Param body body renameRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.VCN
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/vcns/{vcnId} [put]
func (h *ociConfigHandler) updateVCN(c *gin.Context) {
@@ -211,7 +211,7 @@ type enableIPv6Request struct {
// @Param id path int true "配置 ID"
// @Param vcnId path string true "vcnId"
// @Param body body enableIPv6Request true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} ipv6StepsResponse
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/vcns/{vcnId}/enable-ipv6 [post]
func (h *ociConfigHandler) enableVCNIPv6(c *gin.Context) {
@@ -247,7 +247,7 @@ type createSubnetRequest struct {
// @Summary 子网列表
// @Tags 网络
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.Subnet
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/subnets [get]
func (h *ociConfigHandler) listSubnets(c *gin.Context) {
@@ -267,7 +267,7 @@ func (h *ociConfigHandler) listSubnets(c *gin.Context) {
// @Tags 网络
// @Param id path int true "配置 ID"
// @Param body body createSubnetRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.Subnet
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/subnets [post]
func (h *ociConfigHandler) createSubnet(c *gin.Context) {
@@ -300,7 +300,7 @@ func (h *ociConfigHandler) createSubnet(c *gin.Context) {
// @Tags 网络
// @Param id path int true "配置 ID"
// @Param subnetId path string true "subnetId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.Subnet
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/subnets/{subnetId} [get]
func (h *ociConfigHandler) getSubnet(c *gin.Context) {
@@ -321,7 +321,7 @@ func (h *ociConfigHandler) getSubnet(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param subnetId path string true "subnetId"
// @Param body body renameRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.Subnet
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/subnets/{subnetId} [put]
func (h *ociConfigHandler) updateSubnet(c *gin.Context) {
@@ -381,7 +381,7 @@ type updateSecurityListRequest struct {
// @Summary 安全列表清单
// @Tags 网络
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.SecurityList
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/security-lists [get]
func (h *ociConfigHandler) listSecurityLists(c *gin.Context) {
@@ -401,7 +401,7 @@ func (h *ociConfigHandler) listSecurityLists(c *gin.Context) {
// @Tags 网络
// @Param id path int true "配置 ID"
// @Param body body createSecurityListRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.SecurityList
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/security-lists [post]
func (h *ociConfigHandler) createSecurityList(c *gin.Context) {
@@ -432,7 +432,7 @@ func (h *ociConfigHandler) createSecurityList(c *gin.Context) {
// @Tags 网络
// @Param id path int true "配置 ID"
// @Param securityListId path string true "securityListId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.SecurityList
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/security-lists/{securityListId} [get]
func (h *ociConfigHandler) getSecurityList(c *gin.Context) {
@@ -453,7 +453,7 @@ func (h *ociConfigHandler) getSecurityList(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param securityListId path string true "securityListId"
// @Param body body updateSecurityListRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.SecurityList
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/security-lists/{securityListId} [put]
func (h *ociConfigHandler) updateSecurityList(c *gin.Context) {
diff --git a/internal/api/ociconfig.go b/internal/api/ociconfig.go
index 2aa38b6..0ad180c 100644
--- a/internal/api/ociconfig.go
+++ b/internal/api/ociconfig.go
@@ -9,8 +9,10 @@ import (
"strconv"
"github.com/gin-gonic/gin"
+
"github.com/oracle/oci-go-sdk/v65/common"
"gorm.io/gorm"
+ _ "oci-portal/internal/model" // swagger 注解引用
"oci-portal/internal/oci"
"oci-portal/internal/service"
@@ -39,7 +41,7 @@ type importRequest struct {
// @Summary 导入租户配置
// @Tags 租户配置
// @Param body body importRequest true "API Key 配置(私钥密文落库)"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} model.OciConfig
// @Security BearerAuth
// @Router /api/v1/oci-configs [post]
func (h *ociConfigHandler) create(c *gin.Context) {
@@ -71,7 +73,7 @@ func (h *ociConfigHandler) create(c *gin.Context) {
// @Summary 租户配置列表
// @Tags 租户配置
-// @Success 200 {object} map[string]any "items"
+// @Success 200 {array} service.ConfigSummary
// @Security BearerAuth
// @Router /api/v1/oci-configs [get]
func (h *ociConfigHandler) list(c *gin.Context) {
@@ -86,7 +88,7 @@ func (h *ociConfigHandler) list(c *gin.Context) {
// @Summary 租户配置详情
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} model.OciConfig
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id} [get]
func (h *ociConfigHandler) get(c *gin.Context) {
@@ -105,7 +107,7 @@ func (h *ociConfigHandler) get(c *gin.Context) {
// @Summary 验证配置连通性并刷新画像
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} configChangesResponse "config 与 changes 字段变更对照"
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/verify [post]
func (h *ociConfigHandler) verify(c *gin.Context) {
@@ -139,7 +141,7 @@ type updateConfigRequest struct {
// @Tags 租户配置
// @Param id path int true "配置 ID"
// @Param body body object true "可更新字段(别名/分组/代理/多区域开关等)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} configChangesResponse "config 与 changes 字段变更对照"
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id} [put]
func (h *ociConfigHandler) update(c *gin.Context) {
@@ -194,7 +196,7 @@ func (h *ociConfigHandler) remove(c *gin.Context) {
// @Summary 列出租户下全部 ACTIVE compartment
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.Compartment
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/compartments [get]
func (h *ociConfigHandler) compartments(c *gin.Context) {
@@ -216,7 +218,7 @@ func (h *ociConfigHandler) compartments(c *gin.Context) {
// @Summary 返回筛选器用区域列表:未开多区域支持只含默认区域
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} service.RegionSubscriptionView
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/cached-regions [get]
func (h *ociConfigHandler) cachedRegions(c *gin.Context) {
@@ -237,7 +239,7 @@ func (h *ociConfigHandler) cachedRegions(c *gin.Context) {
// @Summary 返回筛选器用区间列表:未开多区间支持返回空数组
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.Compartment
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/cached-compartments [get]
func (h *ociConfigHandler) cachedCompartments(c *gin.Context) {
diff --git a/internal/api/overview.go b/internal/api/overview.go
index e0bf49b..86b3524 100644
--- a/internal/api/overview.go
+++ b/internal/api/overview.go
@@ -4,13 +4,15 @@ import (
"net/http"
"github.com/gin-gonic/gin"
+
+ _ "oci-portal/internal/service" // swagger 注解引用
)
// overview 返回总览页聚合数据(本地快照,不发云端请求)。
//
// @Summary 返回总览页聚合数据
// @Tags 租户配置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.Overview
// @Security BearerAuth
// @Router /api/v1/overview [get]
func (h *ociConfigHandler) overview(c *gin.Context) {
diff --git a/internal/api/proxy.go b/internal/api/proxy.go
index be8b64b..d59c4f0 100644
--- a/internal/api/proxy.go
+++ b/internal/api/proxy.go
@@ -18,7 +18,7 @@ type proxyHandler struct {
//
// @Summary 代理列表
// @Tags 设置
-// @Success 200 {object} map[string]any "items"
+// @Success 200 {object} itemsResponse[service.ProxyView] "items"
// @Security BearerAuth
// @Router /api/v1/proxies [get]
func (h *proxyHandler) list(c *gin.Context) {
@@ -35,7 +35,7 @@ func (h *proxyHandler) list(c *gin.Context) {
// @Summary 创建代理
// @Tags 设置
// @Param body body service.ProxyInput true "代理配置(密码只写不回)"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} service.ProxyView
// @Security BearerAuth
// @Router /api/v1/proxies [post]
func (h *proxyHandler) create(c *gin.Context) {
@@ -58,7 +58,7 @@ func (h *proxyHandler) create(c *gin.Context) {
// @Tags 设置
// @Param id path int true "代理 ID"
// @Param body body service.ProxyInput true "代理配置(密码缺省沿用)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.ProxyView
// @Security BearerAuth
// @Router /api/v1/proxies/{id} [put]
func (h *proxyHandler) update(c *gin.Context) {
@@ -104,7 +104,7 @@ func (h *proxyHandler) remove(c *gin.Context) {
// @Summary 批量导入代理
// @Tags 设置
// @Param body body object true "请求体(见接口说明)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.ImportResult
// @Security BearerAuth
// @Router /api/v1/proxies/import [post]
func (h *proxyHandler) importBatch(c *gin.Context) {
@@ -128,7 +128,7 @@ func (h *proxyHandler) importBatch(c *gin.Context) {
// @Summary 手动重测代理出口地区,同步返回最新视图
// @Tags 设置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.ProxyView
// @Security BearerAuth
// @Router /api/v1/proxies/{id}/probe [post]
func (h *proxyHandler) probe(c *gin.Context) {
@@ -150,7 +150,7 @@ func (h *proxyHandler) probe(c *gin.Context) {
// @Tags 设置
// @Param id path int true "代理 ID"
// @Param body body object true "请求体 {\"ociConfigIds\": [1,2]}"
-// @Success 200 {object} map[string]any "usedBy"
+// @Success 200 {object} usedByResponse "usedBy"
// @Security BearerAuth
// @Router /api/v1/proxies/{id}/tenants [put]
func (h *proxyHandler) setTenants(c *gin.Context) {
diff --git a/internal/api/region.go b/internal/api/region.go
index 5d746ff..09942ec 100644
--- a/internal/api/region.go
+++ b/internal/api/region.go
@@ -6,6 +6,8 @@ import (
"github.com/gin-gonic/gin"
+ _ "oci-portal/internal/service" // swagger 注解引用
+
"oci-portal/internal/oci"
)
@@ -13,7 +15,7 @@ import (
//
// @Summary 返回本地维护的完整区域表
// @Tags 租户配置
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.RegionInfo
// @Security BearerAuth
// @Router /api/v1/regions [get]
func listRegions(c *gin.Context) {
@@ -28,7 +30,7 @@ func listRegions(c *gin.Context) {
// @Summary 区域订阅列表
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} service.RegionSubscriptionView
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/region-subscriptions [get]
func (h *ociConfigHandler) regionSubscriptions(c *gin.Context) {
@@ -52,7 +54,7 @@ type subscribeRegionRequest struct {
// @Tags 租户配置
// @Param id path int true "配置 ID"
// @Param body body subscribeRegionRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} service.RegionSubscriptionView
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/region-subscriptions [post]
func (h *ociConfigHandler) subscribeRegion(c *gin.Context) {
@@ -76,7 +78,7 @@ func (h *ociConfigHandler) subscribeRegion(c *gin.Context) {
// @Summary 服务限额查询
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.LimitValue
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/limits [get]
func (h *ociConfigHandler) limits(c *gin.Context) {
diff --git a/internal/api/routes_ai.go b/internal/api/routes_ai.go
index 9538497..f311d79 100644
--- a/internal/api/routes_ai.go
+++ b/internal/api/routes_ai.go
@@ -15,6 +15,9 @@ func registerAiGateway(r *gin.Engine, aiGateway *service.AiGatewayService) {
ai.POST("/responses", aih.responses)
ai.POST("/messages", aih.messages)
ai.POST("/embeddings", aih.embeddings)
+ ai.POST("/audio/speech", aih.audioSpeech)
+ ai.POST("/rerank", aih.rerank)
+ ai.POST("/moderations", aih.moderations)
ai.GET("/models", aih.listModels)
}
diff --git a/internal/api/settings.go b/internal/api/settings.go
index c3852c9..1452fae 100644
--- a/internal/api/settings.go
+++ b/internal/api/settings.go
@@ -19,7 +19,7 @@ type settingsHandler struct {
//
// @Summary 返回脱敏后的 Telegram 配置,绝不回 token 明文
// @Tags 设置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.TelegramView
// @Security BearerAuth
// @Router /api/v1/settings/telegram [get]
func (h *settingsHandler) getTelegram(c *gin.Context) {
@@ -44,7 +44,7 @@ type updateTelegramRequest struct {
// @Summary 保存配置并返回最新脱敏视图
// @Tags 设置
// @Param body body updateTelegramRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.TelegramView
// @Security BearerAuth
// @Router /api/v1/settings/telegram [put]
func (h *settingsHandler) updateTelegram(c *gin.Context) {
@@ -84,7 +84,7 @@ func (h *settingsHandler) testTelegram(c *gin.Context) {
//
// @Summary 返回全部通知渠道的脱敏视图
// @Tags 设置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[service.NotifyChannelView]
// @Security BearerAuth
// @Router /api/v1/settings/notify-channels [get]
func (h *settingsHandler) listNotifyChannels(c *gin.Context) {
@@ -119,7 +119,7 @@ type updateNotifyChannelRequest struct {
// @Tags 设置
// @Param type path string true "渠道类型(webhook/ntfy/bark/smtp)"
// @Param body body updateNotifyChannelRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[service.NotifyChannelView]
// @Security BearerAuth
// @Router /api/v1/settings/notify-channels/{type} [put]
func (h *settingsHandler) updateNotifyChannel(c *gin.Context) {
@@ -160,7 +160,7 @@ func (h *settingsHandler) testNotifyChannel(c *gin.Context) {
//
// @Summary 返回全部通知事件开关
// @Tags 设置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.NotifyEventsView
// @Security BearerAuth
// @Router /api/v1/settings/notify-events [get]
func (h *settingsHandler) getNotifyEvents(c *gin.Context) {
@@ -178,7 +178,7 @@ func (h *settingsHandler) getNotifyEvents(c *gin.Context) {
// @Summary 全量保存五个事件开关并返回最新值
// @Tags 设置
// @Param body body service.NotifyEventsView true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.NotifyEventsView
// @Security BearerAuth
// @Router /api/v1/settings/notify-events [put]
func (h *settingsHandler) updateNotifyEvents(c *gin.Context) {
@@ -198,7 +198,7 @@ func (h *settingsHandler) updateNotifyEvents(c *gin.Context) {
//
// @Summary 返回全部通知模板
// @Tags 设置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} itemsResponse[service.NotifyTemplateView]
// @Security BearerAuth
// @Router /api/v1/settings/notify-templates [get]
func (h *settingsHandler) listNotifyTemplates(c *gin.Context) {
@@ -263,7 +263,7 @@ func (h *settingsHandler) testNotifyTemplate(c *gin.Context) {
//
// @Summary 返回任务行为设置
// @Tags 设置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.TaskSettingsView
// @Security BearerAuth
// @Router /api/v1/settings/task [get]
func (h *settingsHandler) getTaskSettings(c *gin.Context) {
@@ -280,7 +280,7 @@ func (h *settingsHandler) getTaskSettings(c *gin.Context) {
// @Summary 保存任务行为设置并返回最新值
// @Tags 设置
// @Param body body service.TaskSettingsView true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.TaskSettingsView
// @Security BearerAuth
// @Router /api/v1/settings/task [put]
func (h *settingsHandler) updateTaskSettings(c *gin.Context) {
@@ -304,7 +304,7 @@ func (h *settingsHandler) updateTaskSettings(c *gin.Context) {
//
// @Summary 返回安全设置
// @Tags 设置
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.SecuritySettings
// @Security BearerAuth
// @Router /api/v1/settings/security [get]
func (h *settingsHandler) getSecurity(c *gin.Context) {
@@ -321,7 +321,7 @@ func (h *settingsHandler) getSecurity(c *gin.Context) {
// @Summary 保存安全设置并返回最新值
// @Tags 设置
// @Param body body service.SecuritySettings true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.SecuritySettings
// @Security BearerAuth
// @Router /api/v1/settings/security [put]
func (h *settingsHandler) updateSecurity(c *gin.Context) {
diff --git a/internal/api/subscription.go b/internal/api/subscription.go
index 197f1a3..31b16d2 100644
--- a/internal/api/subscription.go
+++ b/internal/api/subscription.go
@@ -4,12 +4,14 @@ import (
"net/http"
"github.com/gin-gonic/gin"
+
+ _ "oci-portal/internal/oci" // swagger 注解引用
)
// @Summary 订阅列表
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.SubscriptionInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/subscriptions [get]
func (h *ociConfigHandler) subscriptions(c *gin.Context) {
@@ -29,7 +31,7 @@ func (h *ociConfigHandler) subscriptions(c *gin.Context) {
// @Tags 租户配置
// @Param id path int true "配置 ID"
// @Param subscriptionId path string true "subscriptionId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.SubscriptionDetail
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/subscriptions/{subscriptionId} [get]
func (h *ociConfigHandler) subscriptionDetail(c *gin.Context) {
@@ -48,7 +50,7 @@ func (h *ociConfigHandler) subscriptionDetail(c *gin.Context) {
// @Summary 限额服务列表
// @Tags 租户配置
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.LimitService
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/limits/services [get]
func (h *ociConfigHandler) limitServices(c *gin.Context) {
diff --git a/internal/api/swagger_resp.go b/internal/api/swagger_resp.go
new file mode 100644
index 0000000..3730161
--- /dev/null
+++ b/internal/api/swagger_resp.go
@@ -0,0 +1,176 @@
+package api
+
+import (
+ "encoding/json"
+ "time"
+
+ "oci-portal/internal/model"
+ "oci-portal/internal/oci"
+ "oci-portal/internal/service"
+)
+
+// 本文件的类型仅供 swagger 文档渲染(@Success/@Failure 注解引用),
+// 运行时代码不使用;字段与各 handler 返回的 gin.H 外壳保持一致。
+
+// errorResponse 是统一错误响应外壳。
+type errorResponse struct {
+ Error string `json:"error"`
+}
+
+// itemsResponse 是 {"items": [...]} 列表外壳。
+type itemsResponse[T any] struct {
+ Items []T `json:"items"`
+}
+
+// pagedResponse 是 {"items": [...], "total": n} 分页外壳。
+type pagedResponse[T any] struct {
+ Items []T `json:"items"`
+ Total int64 `json:"total"`
+}
+
+// itemResponse 是 {"item": {...}} 单项外壳。
+type itemResponse[T any] struct {
+ Item T `json:"item"`
+}
+
+// triggerResponse 是任务触发受理响应。
+type triggerResponse struct {
+ Triggered bool `json:"triggered"`
+}
+
+// tokenResponse 是登录 / 换发令牌响应。
+type tokenResponse struct {
+ Token string `json:"token"`
+ ExpiresAt time.Time `json:"expiresAt"`
+}
+
+// totpRequiredResponse 是密码通过但需两步验证码的 428 响应。
+type totpRequiredResponse struct {
+ Error string `json:"error"`
+ TotpRequired bool `json:"totpRequired"`
+}
+
+// enabledResponse 是布尔开关查询响应。
+type enabledResponse struct {
+ Enabled bool `json:"enabled"`
+}
+
+// totpSetupResponse 是 TOTP 初始化响应。
+type totpSetupResponse struct {
+ Secret string `json:"secret"`
+ OtpauthUri string `json:"otpauthUri"`
+}
+
+// credentialsResponse 是当前登录账号信息。
+type credentialsResponse struct {
+ Username string `json:"username"`
+ PasswordLoginDisabled bool `json:"passwordLoginDisabled"`
+}
+
+// oauthProvidersResponse 是外部登录 provider 列表。
+type oauthProvidersResponse struct {
+ Providers []service.ProviderInfo `json:"providers"`
+ PasswordLoginDisabled bool `json:"passwordLoginDisabled"`
+}
+
+// urlResponse 是跳转地址响应。
+type urlResponse struct {
+ URL string `json:"url"`
+}
+
+// aboutResponse 是「设置 · 关于」页构建与运行信息。
+type aboutResponse struct {
+ Version string `json:"version"`
+ BuildTime string `json:"buildTime"`
+ GoVersion string `json:"goVersion"`
+ Platform string `json:"platform"`
+ StartedAt string `json:"startedAt"`
+ UptimeSeconds int64 `json:"uptimeSeconds"`
+ Resources aboutResources `json:"resources"`
+}
+
+// aboutResources 是进程资源占用快照。
+type aboutResources struct {
+ CpuAvgPercent float64 `json:"cpuAvgPercent"`
+ NumCpu int `json:"numCpu"`
+ Goroutines int `json:"goroutines"`
+ MemHeapBytes uint64 `json:"memHeapBytes"`
+ MemSysBytes uint64 `json:"memSysBytes"`
+ DbEngine string `json:"dbEngine"`
+ DbBytes int64 `json:"dbBytes"`
+}
+
+// publicIpResponse 是换绑公网 IP 结果。
+type publicIpResponse struct {
+ PublicIp string `json:"publicIp"`
+}
+
+// ipv6AddressResponse 是实例新增 IPv6 结果。
+type ipv6AddressResponse struct {
+ Ipv6Address string `json:"ipv6Address"`
+}
+
+// addressResponse 是 VNIC 新增 IPv6 结果。
+type addressResponse struct {
+ Address string `json:"address"`
+}
+
+// ipv6StepsResponse 是 VCN 开启 IPv6 的分步结果。
+type ipv6StepsResponse struct {
+ Steps []oci.IPv6Step `json:"steps"`
+}
+
+// configChangesResponse 是租户配置校验 / 更新结果(config 与字段变更对照)。
+type configChangesResponse struct {
+ Config *model.OciConfig `json:"config"`
+ Changes service.Changes `json:"changes"`
+}
+
+// aiKeyCreateResponse 是 AI 密钥创建结果;key 为明文,仅本次返回。
+type aiKeyCreateResponse struct {
+ Key string `json:"key"`
+ Item model.AiKey `json:"item"`
+}
+
+// usedByResponse 是代理关联租户结果(关联数)。
+type usedByResponse struct {
+ UsedBy int64 `json:"usedBy"`
+}
+
+// rawDetailResponse 是审计事件原文响应。
+type rawDetailResponse struct {
+ Raw json.RawMessage `json:"raw"`
+}
+
+// passwordResponse 是租户用户重置密码结果(一次性明文)。
+type passwordResponse struct {
+ Password string `json:"password"`
+}
+
+// deletedTotpResponse 是清除 MFA 设备结果。
+type deletedTotpResponse struct {
+ DeletedTotpDevices int `json:"deletedTotpDevices"`
+}
+
+// deletedApiKeysResponse 是清理用户 API Key 结果。
+type deletedApiKeysResponse struct {
+ DeletedApiKeys int `json:"deletedApiKeys"`
+}
+
+// createInstancesResponse 是批量创建实例结果;部分成功仍 201,errors 为逐台失败信息。
+type createInstancesResponse struct {
+ Instances []oci.Instance `json:"instances"`
+ Errors []string `json:"errors"`
+}
+
+// logWebhookStatusResponse 是日志回传 webhook 状态。
+type logWebhookStatusResponse struct {
+ Exists bool `json:"exists"`
+ Webhook *service.LogWebhookInfo `json:"webhook,omitempty"`
+}
+
+// webConsoleSessionResponse 是网页控制台会话创建结果。
+type webConsoleSessionResponse struct {
+ SessionId string `json:"sessionId"`
+ Type string `json:"type"`
+}
diff --git a/internal/api/systemlog.go b/internal/api/systemlog.go
index 3b804f6..7787f5f 100644
--- a/internal/api/systemlog.go
+++ b/internal/api/systemlog.go
@@ -6,6 +6,7 @@ import (
"github.com/gin-gonic/gin"
+ _ "oci-portal/internal/model" // swagger 注解引用
"oci-portal/internal/service"
)
@@ -18,7 +19,7 @@ type systemLogHandler struct {
//
// @Summary 系统操作日志列表
// @Tags 设置
-// @Success 200 {object} map[string]any "items 与 total"
+// @Success 200 {object} pagedResponse[model.SystemLog] "items 与 total"
// @Security BearerAuth
// @Router /api/v1/system-logs [get]
func (h *systemLogHandler) list(c *gin.Context) {
diff --git a/internal/api/task.go b/internal/api/task.go
index 599e265..f74e138 100644
--- a/internal/api/task.go
+++ b/internal/api/task.go
@@ -8,6 +8,7 @@ import (
"github.com/gin-gonic/gin"
+ _ "oci-portal/internal/model" // swagger 注解引用
"oci-portal/internal/service"
)
@@ -33,7 +34,7 @@ type updateTaskRequest struct {
// @Summary 创建任务
// @Tags 任务与日志回传
// @Param body body createTaskRequest true "任务定义(类型/cron/payload)"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} model.Task
// @Security BearerAuth
// @Router /api/v1/tasks [post]
func (h *taskHandler) create(c *gin.Context) {
@@ -57,7 +58,7 @@ func (h *taskHandler) create(c *gin.Context) {
// @Summary 任务列表
// @Tags 任务与日志回传
-// @Success 200 {array} map[string]any
+// @Success 200 {array} model.Task
// @Security BearerAuth
// @Router /api/v1/tasks [get]
func (h *taskHandler) list(c *gin.Context) {
@@ -72,7 +73,7 @@ func (h *taskHandler) list(c *gin.Context) {
// @Summary 任务详情
// @Tags 任务与日志回传
// @Param id path int true "任务 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} model.Task
// @Security BearerAuth
// @Router /api/v1/tasks/{id} [get]
func (h *taskHandler) get(c *gin.Context) {
@@ -92,7 +93,7 @@ func (h *taskHandler) get(c *gin.Context) {
// @Tags 任务与日志回传
// @Param id path int true "任务 ID"
// @Param body body updateTaskRequest true "可更新字段"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} model.Task
// @Security BearerAuth
// @Router /api/v1/tasks/{id} [put]
func (h *taskHandler) update(c *gin.Context) {
@@ -139,7 +140,7 @@ func (h *taskHandler) remove(c *gin.Context) {
// @Summary 任务执行日志
// @Tags 任务与日志回传
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} model.TaskLog
// @Security BearerAuth
// @Router /api/v1/tasks/{id}/logs [get]
func (h *taskHandler) logs(c *gin.Context) {
@@ -159,8 +160,8 @@ func (h *taskHandler) logs(c *gin.Context) {
// @Summary 立即执行任务(异步触发,结果经任务日志轮询获取)
// @Tags 任务与日志回传
// @Param id path int true "配置 ID"
-// @Success 202 {object} map[string]any
-// @Failure 409 {object} map[string]any "任务正在执行中"
+// @Success 202 {object} triggerResponse
+// @Failure 409 {object} errorResponse "任务正在执行中"
// @Security BearerAuth
// @Router /api/v1/tasks/{id}/run [post]
func (h *taskHandler) run(c *gin.Context) {
diff --git a/internal/api/tenant.go b/internal/api/tenant.go
index 56fd9e7..9d2c9f7 100644
--- a/internal/api/tenant.go
+++ b/internal/api/tenant.go
@@ -18,7 +18,7 @@ import (
// @Tags 计算
// @Param id path int true "配置 ID"
// @Param instanceId path string true "instanceId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.InstanceTraffic
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/traffic [get]
func (h *ociConfigHandler) instanceTraffic(c *gin.Context) {
@@ -38,7 +38,7 @@ func (h *ociConfigHandler) instanceTraffic(c *gin.Context) {
// @Summary 配置成本快照
// @Tags 成本
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.CostItem
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/costs [get]
func (h *ociConfigHandler) costs(c *gin.Context) {
@@ -75,7 +75,7 @@ func (h *ociConfigHandler) costs(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param cursor query string false "续查游标(上次响应原样带回)"
// @Param limit query int false "单批目标条数,缺省 100,上限 200"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} service.AuditEventsView
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/audit-events [get]
func (h *ociConfigHandler) getAuditEvents(c *gin.Context) {
@@ -103,7 +103,7 @@ func (h *ociConfigHandler) getAuditEvents(c *gin.Context) {
// @Summary 按 eventId 取回原始事件 JSON:缓存命中秒开,
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} rawDetailResponse "raw 为事件原文 JSON"
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/audit-events/detail [get]
func (h *ociConfigHandler) getAuditEventDetail(c *gin.Context) {
@@ -145,7 +145,7 @@ type createTenantUserRequest struct {
// @Summary 租户身份域列表
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.IdentityDomain
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/domains [get]
func (h *ociConfigHandler) listIdentityDomains(c *gin.Context) {
@@ -165,7 +165,7 @@ func (h *ociConfigHandler) listIdentityDomains(c *gin.Context) {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.TenantUser
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/users [get]
func (h *ociConfigHandler) listTenantUsers(c *gin.Context) {
@@ -186,7 +186,7 @@ func (h *ociConfigHandler) listTenantUsers(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param userId path string true "userId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.TenantUserDetail
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/users/{userId} [get]
func (h *ociConfigHandler) getTenantUserDetail(c *gin.Context) {
@@ -207,7 +207,7 @@ func (h *ociConfigHandler) getTenantUserDetail(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param body body createTenantUserRequest true "请求体"
-// @Success 201 {object} map[string]any
+// @Success 201 {object} oci.TenantUser
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/users [post]
func (h *ociConfigHandler) createTenantUser(c *gin.Context) {
@@ -253,7 +253,7 @@ type updateTenantUserRequest struct {
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param userId path string true "userId"
// @Param body body updateTenantUserRequest true "请求体"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.TenantUser
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/users/{userId} [put]
func (h *ociConfigHandler) updateTenantUser(c *gin.Context) {
@@ -306,7 +306,7 @@ func (h *ociConfigHandler) deleteTenantUser(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param userId path string true "userId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} passwordResponse "一次性明文密码"
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/users/{userId}/reset-password [post]
func (h *ociConfigHandler) resetTenantUserPassword(c *gin.Context) {
@@ -327,7 +327,7 @@ func (h *ociConfigHandler) resetTenantUserPassword(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param userId path string true "userId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} deletedTotpResponse
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/users/{userId}/mfa-devices [delete]
func (h *ociConfigHandler) deleteTenantUserMfa(c *gin.Context) {
@@ -347,7 +347,7 @@ func (h *ociConfigHandler) deleteTenantUserMfa(c *gin.Context) {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param userId path string true "userId"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} deletedApiKeysResponse
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/users/{userId}/api-keys [delete]
func (h *ociConfigHandler) deleteTenantUserApiKeys(c *gin.Context) {
@@ -370,7 +370,7 @@ func (h *ociConfigHandler) deleteTenantUserApiKeys(c *gin.Context) {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.NotificationRecipients
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/notification-recipients [get]
func (h *ociConfigHandler) getNotificationRecipients(c *gin.Context) {
@@ -391,7 +391,7 @@ func (h *ociConfigHandler) getNotificationRecipients(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param body body object true "请求体(见接口说明)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.NotificationRecipients
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/notification-recipients [put]
func (h *ociConfigHandler) updateNotificationRecipients(c *gin.Context) {
@@ -418,7 +418,7 @@ func (h *ociConfigHandler) updateNotificationRecipients(c *gin.Context) {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
-// @Success 200 {object} map[string]any
+// @Success 200 {array} oci.PasswordPolicyInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/password-policies [get]
func (h *ociConfigHandler) listPasswordPolicies(c *gin.Context) {
@@ -440,7 +440,7 @@ func (h *ociConfigHandler) listPasswordPolicies(c *gin.Context) {
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param policyId path string true "policyId"
// @Param body body object true "请求体(见接口说明)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.PasswordPolicyInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/password-policies/{policyId} [put]
func (h *ociConfigHandler) updatePasswordPolicy(c *gin.Context) {
@@ -473,7 +473,7 @@ func (h *ociConfigHandler) updatePasswordPolicy(c *gin.Context) {
// @Tags 租户 IAM
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.IdentitySettingInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/identity-settings [get]
func (h *ociConfigHandler) getIdentitySetting(c *gin.Context) {
@@ -494,7 +494,7 @@ func (h *ociConfigHandler) getIdentitySetting(c *gin.Context) {
// @Param id path int true "配置 ID"
// @Param domainId query string false "身份域 OCID(缺省 Default 域)"
// @Param body body object true "请求体(见接口说明)"
-// @Success 200 {object} map[string]any
+// @Success 200 {object} oci.IdentitySettingInfo
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/identity-settings [put]
func (h *ociConfigHandler) updateIdentitySetting(c *gin.Context) {
diff --git a/internal/api/webconsole.go b/internal/api/webconsole.go
index 270d337..9b4fde7 100644
--- a/internal/api/webconsole.go
+++ b/internal/api/webconsole.go
@@ -29,7 +29,7 @@ type createConsoleSessionRequest struct {
// @Param id path int true "配置 ID"
// @Param instanceId path string true "实例 OCID"
// @Param body body object true "{type: serial|vnc}"
-// @Success 200 {object} map[string]any "sessionId 与 wsPath"
+// @Success 201 {object} webConsoleSessionResponse "sessionId 与 type"
// @Security BearerAuth
// @Router /api/v1/oci-configs/{id}/instances/{instanceId}/console-sessions [post]
func (h *consoleHandler) create(c *gin.Context) {
diff --git a/internal/api/webhook.go b/internal/api/webhook.go
index 06e2223..f1f0c10 100644
--- a/internal/api/webhook.go
+++ b/internal/api/webhook.go
@@ -53,7 +53,7 @@ type webhookHandler struct {
// @Param secret path string true "面板生成的回传密钥(鉴权凭据)"
// @Param body body object true "ONS 消息原文(SubscriptionConfirmation / Notification)"
// @Success 200 "已受理"
-// @Failure 403 {object} map[string]string "时间戳超窗或证书源非 Oracle 域"
+// @Failure 403 {object} errorResponse "时间戳超窗或证书源非 Oracle 域"
// @Failure 404 "secret 无效(不暴露端点存在性)"
// @Router /api/v1/webhooks/oci-logs/{secret} [post]
func (h *webhookHandler) handle(c *gin.Context) {
diff --git a/internal/model/models.go b/internal/model/models.go
index e7cd491..ad3c6f5 100644
--- a/internal/model/models.go
+++ b/internal/model/models.go
@@ -273,7 +273,7 @@ type AiChannel struct {
}
// AiModelCache 是渠道区域的可用模型缓存(整渠道覆盖式同步)。
-// Capability 为 CHAT / EMBEDDING;存量空串视为 CHAT(加列前只同步对话模型)。
+// Capability 为 CHAT / EMBEDDING / RERANK / TTS;存量空串视为 CHAT(加列前只同步对话模型)。
type AiModelCache struct {
ID uint `gorm:"primaryKey" json:"-"`
ChannelID uint `gorm:"index" json:"channelId"`
diff --git a/internal/oci/client.go b/internal/oci/client.go
index f559b58..7be374a 100644
--- a/internal/oci/client.go
+++ b/internal/oci/client.go
@@ -106,6 +106,12 @@ type Client interface {
GenAiCompatResponses(ctx context.Context, cred Credentials, region string, body []byte) ([]byte, error)
// GenAiCompatResponsesStream 流式直通 /actions/v1/responses,建立成功返回 SSE body。
GenAiCompatResponsesStream(ctx context.Context, cred Credentials, region string, body []byte) (io.ReadCloser, error)
+ // GenAiCompatSpeech 直通 OpenAI Audio Speech 请求体到 /openai/v1/audio/speech,返回音频与 Content-Type。
+ GenAiCompatSpeech(ctx context.Context, cred Credentials, region string, body []byte) ([]byte, string, error)
+ // GenAiRerank 文档重排,返回按相关度排序的下标与得分。
+ GenAiRerank(ctx context.Context, cred Credentials, region, modelOcid, query string, documents []string, topN *int) ([]RerankRank, error)
+ // GenAiApplyGuardrails 对单条文本执行内容审核 / PII / 提示注入检测。
+ GenAiApplyGuardrails(ctx context.Context, cred Credentials, region, text string) (*GuardrailsOutcome, error)
// 控制台连接:创建(VNC/串口连接串)、列出、删除。
CreateConsoleConnection(ctx context.Context, cred Credentials, region, instanceID, sshPublicKey string) (ConsoleConnection, error)
ListConsoleConnections(ctx context.Context, cred Credentials, region, instanceID string) ([]ConsoleConnection, error)
diff --git a/internal/oci/genai.go b/internal/oci/genai.go
index 7bab6a2..d79bf60 100644
--- a/internal/oci/genai.go
+++ b/internal/oci/genai.go
@@ -131,6 +131,11 @@ func modelCapability(m generativeai.ModelSummary) string {
return "CHAT"
case generativeai.ModelCapabilityTextEmbeddings:
capability = "EMBEDDING"
+ case generativeai.ModelCapabilityTextRerank:
+ capability = "RERANK"
+ case generativeai.ModelCapabilityEnum("TEXT_TO_AUDIO"):
+ // SDK v65.120 尚无该枚举常量,按原始字符串匹配(xai.grok-tts)
+ capability = "TTS"
}
}
return capability
diff --git a/internal/oci/genai_guard.go b/internal/oci/genai_guard.go
new file mode 100644
index 0000000..53a2550
--- /dev/null
+++ b/internal/oci/genai_guard.go
@@ -0,0 +1,127 @@
+package oci
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/oracle/oci-go-sdk/v65/common"
+ "github.com/oracle/oci-go-sdk/v65/generativeaiinference"
+)
+
+// RerankRank 是重排结果的一项:index 指向入参 documents 下标。
+type RerankRank struct {
+ Index int
+ Score float64
+}
+
+// GuardrailCategory 是内容审核分类得分(OVERALL / BLOCKLIST)。
+type GuardrailCategory struct {
+ Name string
+ Score float64
+}
+
+// GuardrailPiiHit 是一处 PII 命中(片段原文与位置)。
+type GuardrailPiiHit struct {
+ Text string
+ Label string
+ Score float64
+ Offset int
+ Length int
+}
+
+// GuardrailsOutcome 汇总 ApplyGuardrails 三能力结果。
+type GuardrailsOutcome struct {
+ Categories []GuardrailCategory
+ Pii []GuardrailPiiHit
+ PromptInjectionScore *float64
+}
+
+// GenAiRerank 实现 Client:文档重排(on-demand serving),返回按相关度排序的下标与得分。
+func (c *RealClient) GenAiRerank(ctx context.Context, cred Credentials, region, modelOcid, query string, documents []string, topN *int) ([]RerankRank, error) {
+ ic, err := c.genAiInferenceClient(cred, region)
+ if err != nil {
+ return nil, err
+ }
+ resp, err := ic.RerankText(ctx, generativeaiinference.RerankTextRequest{
+ RerankTextDetails: generativeaiinference.RerankTextDetails{
+ CompartmentId: &cred.TenancyOCID,
+ ServingMode: generativeaiinference.OnDemandServingMode{ModelId: &modelOcid},
+ Input: &query,
+ Documents: documents,
+ TopN: topN,
+ },
+ })
+ if err != nil {
+ return nil, fmt.Errorf("genai rerank: %w", err)
+ }
+ ranks := make([]RerankRank, 0, len(resp.DocumentRanks))
+ for _, r := range resp.DocumentRanks {
+ if r.Index == nil || r.RelevanceScore == nil {
+ continue
+ }
+ ranks = append(ranks, RerankRank{Index: *r.Index, Score: *r.RelevanceScore})
+ }
+ return ranks, nil
+}
+
+// GenAiApplyGuardrails 实现 Client:对单条文本执行内容审核 / PII / 提示注入三检测。
+func (c *RealClient) GenAiApplyGuardrails(ctx context.Context, cred Credentials, region, text string) (*GuardrailsOutcome, error) {
+ ic, err := c.genAiInferenceClient(cred, region)
+ if err != nil {
+ return nil, err
+ }
+ resp, err := ic.ApplyGuardrails(ctx, generativeaiinference.ApplyGuardrailsRequest{
+ ApplyGuardrailsDetails: generativeaiinference.ApplyGuardrailsDetails{
+ CompartmentId: &cred.TenancyOCID,
+ Input: generativeaiinference.GuardrailsTextInput{Content: common.String(text)},
+ GuardrailConfigs: &generativeaiinference.GuardrailConfigs{
+ ContentModerationConfig: &generativeaiinference.ContentModerationConfiguration{Categories: []string{"OVERALL"}},
+ PersonallyIdentifiableInformationConfig: &generativeaiinference.PersonallyIdentifiableInformationConfiguration{Types: []string{}},
+ PromptInjectionConfig: &generativeaiinference.PromptInjectionConfiguration{},
+ },
+ },
+ })
+ if err != nil {
+ return nil, fmt.Errorf("genai guardrails: %w", err)
+ }
+ return guardrailsOutcome(resp.Results), nil
+}
+
+// guardrailsOutcome 把 SDK 结果换算为 IR;空段置空切片,得分缺失跳过。
+func guardrailsOutcome(r *generativeaiinference.GuardrailsResults) *GuardrailsOutcome {
+ out := &GuardrailsOutcome{}
+ if r == nil {
+ return out
+ }
+ if r.ContentModeration != nil {
+ for _, cat := range r.ContentModeration.Categories {
+ if cat.Name == nil || cat.Score == nil {
+ continue
+ }
+ out.Categories = append(out.Categories, GuardrailCategory{Name: *cat.Name, Score: *cat.Score})
+ }
+ }
+ for _, hit := range r.PersonallyIdentifiableInformation {
+ h := GuardrailPiiHit{}
+ if hit.Text != nil {
+ h.Text = *hit.Text
+ }
+ if hit.Label != nil {
+ h.Label = *hit.Label
+ }
+ if hit.Score != nil {
+ h.Score = *hit.Score
+ }
+ if hit.Offset != nil {
+ h.Offset = *hit.Offset
+ }
+ if hit.Length != nil {
+ h.Length = *hit.Length
+ }
+ out.Pii = append(out.Pii, h)
+ }
+ if r.PromptInjection != nil && r.PromptInjection.Score != nil {
+ out.PromptInjectionScore = r.PromptInjection.Score
+ }
+ return out
+}
diff --git a/internal/oci/genai_responses.go b/internal/oci/genai_responses.go
index a1e9516..36eecb1 100644
--- a/internal/oci/genai_responses.go
+++ b/internal/oci/genai_responses.go
@@ -14,9 +14,9 @@ import (
const compatResponsesLimit = int64(8 << 20)
// GenAiCompatResponses 实现 Client:把 OpenAI Responses 请求体直通到 OCI
-// `/20231130/actions/v1/responses`(IAM 签名)。该端点实测可执行 xAI 服务端工具
-// (web_search / x_search),但不在 Oracle 文档化工具白名单内,行为可能随服务
-// 版本、模型或区域变化;调用方须自行校验并改写请求体(store/stream)。
+// `/20231130/actions/v1/responses`(IAM 签名)。xAI 服务端工具(web_search /
+// x_search / code_interpreter)与 mcp 已被 Oracle 文档正式支持,工具参数与限制
+// 遵循 xAI 规格;调用方须自行校验并改写请求体(store/stream)。
func (c *RealClient) GenAiCompatResponses(ctx context.Context, cred Credentials, region string, body []byte) ([]byte, error) {
ic, err := c.genAiInferenceClient(cred, region)
if err != nil {
diff --git a/internal/oci/genai_speech.go b/internal/oci/genai_speech.go
new file mode 100644
index 0000000..8d258d7
--- /dev/null
+++ b/internal/oci/genai_speech.go
@@ -0,0 +1,44 @@
+package oci
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "net/http"
+
+ "github.com/oracle/oci-go-sdk/v65/common"
+)
+
+// compatSpeechLimit 限制 TTS 音频响应体大小(长文本 mp3 给足余量)。
+const compatSpeechLimit = int64(64 << 20)
+
+// GenAiCompatSpeech 实现 Client:把 OpenAI Audio Speech 请求体直通到 OCI
+// 兼容面 `/openai/v1/audio/speech`(IAM 签名,BasePath 置空——该面与
+// /20231130/actions 面并存,实测仅前者承载 TTS)。返回音频字节与 Content-Type。
+func (c *RealClient) GenAiCompatSpeech(ctx context.Context, cred Credentials, region string, body []byte) ([]byte, string, error) {
+ ic, err := c.genAiInferenceClient(cred, region)
+ if err != nil {
+ return nil, "", err
+ }
+ client := ic.BaseClient
+ common.UpdateEndpointTemplateForOptions(&client)
+ common.SetMissingTemplateParams(&client)
+ client.BasePath = ""
+ request, err := http.NewRequestWithContext(ctx, http.MethodPost, "/openai/v1/audio/speech", bytes.NewReader(body))
+ if err != nil {
+ return nil, "", fmt.Errorf("build compat speech request: %w", err)
+ }
+ request.Header.Set("Content-Type", "application/json")
+ request.Header.Set("opc-compartment-id", cred.TenancyOCID)
+ response, err := client.Call(ctx, request)
+ if err != nil {
+ return nil, "", err
+ }
+ defer response.Body.Close()
+ payload, err := io.ReadAll(io.LimitReader(response.Body, compatSpeechLimit))
+ if err != nil {
+ return nil, "", fmt.Errorf("read compat speech body: %w", err)
+ }
+ return payload, response.Header.Get("Content-Type"), nil
+}
diff --git a/internal/service/aigateway_extras.go b/internal/service/aigateway_extras.go
new file mode 100644
index 0000000..6f6efa8
--- /dev/null
+++ b/internal/service/aigateway_extras.go
@@ -0,0 +1,248 @@
+package service
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "strings"
+ "time"
+
+ "oci-portal/internal/aiwire"
+ "oci-portal/internal/model"
+ "oci-portal/internal/oci"
+)
+
+// moderationsMaxInputs 限制单次审核条数,防止批量滥用拖垮渠道配额。
+const moderationsMaxInputs = 8
+
+// SpeechBodyNormalize 校验并规范化 TTS 请求体:model / input 必填;
+// xAI 上游把 language 当必填(实测缺失返回 422),缺省注入 "auto"。
+// 其余字段(voice / response_format / extra_body 平铺项)原样保留。
+func SpeechBodyNormalize(raw []byte) (string, []byte, error) {
+ dec := json.NewDecoder(strings.NewReader(string(raw)))
+ dec.UseNumber()
+ var body map[string]any
+ if err := dec.Decode(&body); err != nil {
+ return "", nil, fmt.Errorf("解析请求体: %w", err)
+ }
+ modelName, _ := body["model"].(string)
+ input, _ := body["input"].(string)
+ if strings.TrimSpace(modelName) == "" || strings.TrimSpace(input) == "" {
+ return "", nil, fmt.Errorf("model 与 input 不能为空")
+ }
+ if lang, ok := body["language"].(string); !ok || strings.TrimSpace(lang) == "" {
+ body["language"] = "auto"
+ }
+ out, err := json.Marshal(body)
+ if err != nil {
+ return "", nil, fmt.Errorf("重组请求体: %w", err)
+ }
+ return modelName, out, nil
+}
+
+// Speech 编排 TTS 调用:按 TTS 能力选渠道,可重试错误换渠道(上限 3 次)。
+func (s *AiGatewayService) Speech(ctx context.Context, modelName string, body []byte, group string) ([]byte, string, ChatMeta, error) {
+ meta := ChatMeta{}
+ excluded := map[uint]bool{}
+ var lastErr error
+ for attempt := 0; attempt < 3; attempt++ {
+ cand, err := s.pick(ctx, modelName, group, "TTS", excluded)
+ if err != nil {
+ return nil, "", meta, firstErr(lastErr, err)
+ }
+ meta.ChannelID, meta.ChannelName = cand.ch.ID, cand.ch.Name
+ cred, err := s.configs.credentialsByID(ctx, cand.ch.OciConfigID)
+ if err != nil {
+ return nil, "", meta, err
+ }
+ audio, contentType, err := s.client.GenAiCompatSpeech(ctx, cred, cand.ch.Region, body)
+ if err == nil {
+ s.markSuccess(ctx, cand.ch.ID)
+ return audio, contentType, meta, nil
+ }
+ if done := s.retryStep(ctx, cand.ch.ID, err, excluded, &meta, &lastErr); done {
+ return nil, "", meta, err
+ }
+ }
+ return nil, "", meta, lastErr
+}
+
+// Rerank 编排文档重排:按 RERANK 能力选渠道,装配 Jina 风格响应。
+func (s *AiGatewayService) Rerank(ctx context.Context, req aiwire.RerankRequest, group string) (*aiwire.RerankResponse, ChatMeta, error) {
+ meta := ChatMeta{}
+ excluded := map[uint]bool{}
+ var lastErr error
+ for attempt := 0; attempt < 3; attempt++ {
+ cand, err := s.pick(ctx, req.Model, group, "RERANK", excluded)
+ if err != nil {
+ return nil, meta, firstErr(lastErr, err)
+ }
+ meta.ChannelID, meta.ChannelName = cand.ch.ID, cand.ch.Name
+ cred, err := s.configs.credentialsByID(ctx, cand.ch.OciConfigID)
+ if err != nil {
+ return nil, meta, err
+ }
+ ranks, err := s.client.GenAiRerank(ctx, cred, cand.ch.Region, cand.modelOcid, req.Query, req.Documents, req.TopN)
+ if err == nil {
+ s.markSuccess(ctx, cand.ch.ID)
+ return rerankResponse(req, ranks), meta, nil
+ }
+ if done := s.retryStep(ctx, cand.ch.ID, err, excluded, &meta, &lastErr); done {
+ return nil, meta, err
+ }
+ }
+ return nil, meta, lastErr
+}
+
+// retryStep 统一处理换渠道重试:不可重试返回 true 终止,可重试记罚并排除渠道。
+func (s *AiGatewayService) retryStep(ctx context.Context, chID uint, err error, excluded map[uint]bool, meta *ChatMeta, lastErr *error) bool {
+ retry, penalize := switchable(err)
+ if !retry {
+ return true
+ }
+ if penalize {
+ s.markFailure(ctx, chID)
+ }
+ excluded[chID] = true
+ meta.Retries++
+ *lastErr = err
+ return false
+}
+
+// rerankResponse 把上游排序结果装配为对外响应;return_documents 时回填原文。
+func rerankResponse(req aiwire.RerankRequest, ranks []oci.RerankRank) *aiwire.RerankResponse {
+ out := &aiwire.RerankResponse{Model: req.Model, Results: make([]aiwire.RerankResult, 0, len(ranks))}
+ withDoc := req.ReturnDocuments != nil && *req.ReturnDocuments
+ for _, r := range ranks {
+ if r.Index < 0 || r.Index >= len(req.Documents) {
+ continue
+ }
+ item := aiwire.RerankResult{Index: r.Index, RelevanceScore: r.Score}
+ if withDoc {
+ item.Document = &aiwire.RerankDocument{Text: req.Documents[r.Index]}
+ }
+ out.Results = append(out.Results, item)
+ }
+ return out
+}
+
+// ModerationInputs 解析 moderations 的 input 字段:string 或 []string,
+// 条数与空值校验(上限 moderationsMaxInputs)。
+func ModerationInputs(raw json.RawMessage) ([]string, error) {
+ var single string
+ if err := json.Unmarshal(raw, &single); err == nil {
+ if strings.TrimSpace(single) == "" {
+ return nil, fmt.Errorf("input 不能为空")
+ }
+ return []string{single}, nil
+ }
+ var many []string
+ if err := json.Unmarshal(raw, &many); err != nil {
+ return nil, fmt.Errorf("input 需为字符串或字符串数组")
+ }
+ if len(many) == 0 || len(many) > moderationsMaxInputs {
+ return nil, fmt.Errorf("input 条数需在 1~%d 之间", moderationsMaxInputs)
+ }
+ for _, item := range many {
+ if strings.TrimSpace(item) == "" {
+ return nil, fmt.Errorf("input 含空条目")
+ }
+ }
+ return many, nil
+}
+
+// Moderations 编排内容审核:guardrails 为服务级 API 无模型维度,
+// 按分组选启用渠道(整批同渠道),可重试错误换渠道(上限 3 次)。
+func (s *AiGatewayService) Moderations(ctx context.Context, id string, inputs []string, group string) (*aiwire.ModerationsResponse, ChatMeta, error) {
+ meta := ChatMeta{}
+ excluded := map[uint]bool{}
+ var lastErr error
+ for attempt := 0; attempt < 3; attempt++ {
+ ch, err := s.pickGuardChannel(ctx, group, excluded)
+ if err != nil {
+ return nil, meta, firstErr(lastErr, err)
+ }
+ meta.ChannelID, meta.ChannelName = ch.ID, ch.Name
+ resp, err := s.moderateOnce(ctx, ch, id, inputs)
+ if err == nil {
+ s.markSuccess(ctx, ch.ID)
+ return resp, meta, nil
+ }
+ if done := s.retryStep(ctx, ch.ID, err, excluded, &meta, &lastErr); done {
+ return nil, meta, err
+ }
+ }
+ return nil, meta, lastErr
+}
+
+// pickGuardChannel 按分组挑一个启用且未熔断的渠道(权重加成,不查模型缓存)。
+func (s *AiGatewayService) pickGuardChannel(ctx context.Context, group string, excluded map[uint]bool) (model.AiChannel, error) {
+ q := s.db.WithContext(ctx).Where("enabled = ?", true)
+ if group != "" {
+ q = q.Where("channel_group = ?", group)
+ }
+ var channels []model.AiChannel
+ if err := q.Find(&channels).Error; err != nil {
+ return model.AiChannel{}, err
+ }
+ now := time.Now()
+ avail := channels[:0]
+ for _, ch := range channels {
+ if excluded[ch.ID] || (ch.DisabledUntil != nil && ch.DisabledUntil.After(now)) {
+ continue
+ }
+ avail = append(avail, ch)
+ }
+ if len(avail) == 0 {
+ return model.AiChannel{}, ErrAiNoChannel
+ }
+ return weightedPick(topPriority(avail)), nil
+}
+
+// moderateOnce 在单渠道上逐条审核并装配 OpenAI moderations 外壳。
+func (s *AiGatewayService) moderateOnce(ctx context.Context, ch model.AiChannel, id string, inputs []string) (*aiwire.ModerationsResponse, error) {
+ cred, err := s.configs.credentialsByID(ctx, ch.OciConfigID)
+ if err != nil {
+ return nil, err
+ }
+ out := &aiwire.ModerationsResponse{ID: id, Model: "oci-guardrails",
+ Results: make([]aiwire.ModerationResult, 0, len(inputs))}
+ for _, text := range inputs {
+ outcome, err := s.client.GenAiApplyGuardrails(ctx, cred, ch.Region, text)
+ if err != nil {
+ return nil, err
+ }
+ out.Results = append(out.Results, moderationResult(outcome))
+ }
+ return out, nil
+}
+
+// moderationFlagThreshold 是判定违规的得分阈值(上游 CM / PI 为二值得分)。
+const moderationFlagThreshold = 0.5
+
+// moderationResult 把 guardrails 结果映射为 OpenAI moderations 条目:
+// flagged 由内容审核与提示注入判定,PII 命中只作扩展信息不参与 flagged。
+func moderationResult(outcome *oci.GuardrailsOutcome) aiwire.ModerationResult {
+ res := aiwire.ModerationResult{Categories: map[string]bool{}, CategoryScores: map[string]float64{}}
+ for _, cat := range outcome.Categories {
+ key := strings.ToLower(cat.Name)
+ res.Categories[key] = cat.Score >= moderationFlagThreshold
+ res.CategoryScores[key] = cat.Score
+ if res.Categories[key] {
+ res.Flagged = true
+ }
+ }
+ if outcome.PromptInjectionScore != nil {
+ hit := *outcome.PromptInjectionScore >= moderationFlagThreshold
+ res.Categories["prompt_injection"] = hit
+ res.CategoryScores["prompt_injection"] = *outcome.PromptInjectionScore
+ if hit {
+ res.Flagged = true
+ }
+ }
+ for _, p := range outcome.Pii {
+ res.Pii = append(res.Pii, aiwire.ModerationPii{Text: p.Text, Label: p.Label,
+ Score: p.Score, Offset: p.Offset, Length: p.Length})
+ }
+ return res
+}
diff --git a/internal/service/aigateway_extras_test.go b/internal/service/aigateway_extras_test.go
new file mode 100644
index 0000000..5818956
--- /dev/null
+++ b/internal/service/aigateway_extras_test.go
@@ -0,0 +1,164 @@
+package service
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "strings"
+ "testing"
+ "time"
+
+ "oci-portal/internal/aiwire"
+ "oci-portal/internal/model"
+ "oci-portal/internal/oci"
+)
+
+// TestSpeechBodyNormalize 断言 TTS 请求体校验与 language 缺省注入。
+func TestSpeechBodyNormalize(t *testing.T) {
+ tests := []struct {
+ name string
+ raw string
+ wantErr bool
+ wantLang string
+ }{
+ {"缺 model 拒绝", `{"input":"你好"}`, true, ""},
+ {"缺 input 拒绝", `{"model":"xai.grok-tts"}`, true, ""},
+ {"language 缺省注入 auto", `{"model":"xai.grok-tts","input":"你好","voice":"ara"}`, false, "auto"},
+ {"language 已有保留", `{"model":"xai.grok-tts","input":"你好","language":"zh"}`, false, "zh"},
+ {"非 JSON 拒绝", ``, true, ""},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ modelName, body, err := SpeechBodyNormalize([]byte(tt.raw))
+ if (err != nil) != tt.wantErr {
+ t.Fatalf("err = %v, wantErr %v", err, tt.wantErr)
+ }
+ if err != nil {
+ return
+ }
+ var out map[string]any
+ _ = json.Unmarshal(body, &out)
+ if modelName != "xai.grok-tts" || out["language"] != tt.wantLang {
+ t.Fatalf("model=%s language=%v, want %s", modelName, out["language"], tt.wantLang)
+ }
+ })
+ }
+}
+
+// TestModerationInputs 断言 input 的 string / []string 解析与边界校验。
+func TestModerationInputs(t *testing.T) {
+ tests := []struct {
+ name string
+ raw string
+ wantN int
+ wantErr bool
+ }{
+ {"单字符串", `"hello"`, 1, false},
+ {"数组", `["a","b"]`, 2, false},
+ {"空字符串拒绝", `""`, 0, true},
+ {"空数组拒绝", `[]`, 0, true},
+ {"含空条目拒绝", `["a",""]`, 0, true},
+ {"超上限拒绝", `["1","2","3","4","5","6","7","8","9"]`, 0, true},
+ {"非法类型拒绝", `{"x":1}`, 0, true},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := ModerationInputs(json.RawMessage(tt.raw))
+ if (err != nil) != tt.wantErr || len(got) != tt.wantN {
+ t.Fatalf("got %v (err=%v), want n=%d wantErr=%v", got, err, tt.wantN, tt.wantErr)
+ }
+ })
+ }
+}
+
+// TestModerationResultMapping 断言 guardrails 结果到 OpenAI 外壳的映射与 flagged 判定。
+func TestModerationResultMapping(t *testing.T) {
+ one := 1.0
+ zero := 0.0
+ tests := []struct {
+ name string
+ outcome oci.GuardrailsOutcome
+ wantFlagged bool
+ wantPii int
+ }{
+ {"内容审核命中", oci.GuardrailsOutcome{Categories: []oci.GuardrailCategory{{Name: "OVERALL", Score: 1}}}, true, 0},
+ {"提示注入命中", oci.GuardrailsOutcome{PromptInjectionScore: &one}, true, 0},
+ {"仅 PII 不 flag", oci.GuardrailsOutcome{Categories: []oci.GuardrailCategory{{Name: "OVERALL", Score: 0}},
+ PromptInjectionScore: &zero, Pii: []oci.GuardrailPiiHit{{Text: "Jane", Label: "PERSON", Score: 0.99}}}, false, 1},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ res := moderationResult(&tt.outcome)
+ if res.Flagged != tt.wantFlagged || len(res.Pii) != tt.wantPii {
+ t.Fatalf("res = %+v, want flagged=%v pii=%d", res, tt.wantFlagged, tt.wantPii)
+ }
+ })
+ }
+}
+
+// TestAiRerank 断言重排编排:能力路由、top_n 透传、return_documents 回填与越界防御。
+func TestAiRerank(t *testing.T) {
+ client := &gatewayStubClient{
+ fakeClient: &fakeClient{tenancy: oci.TenancyInfo{Name: "t"}},
+ rerankRanks: []oci.RerankRank{{Index: 1, Score: 0.9}, {Index: 0, Score: 0.4}, {Index: 9, Score: 0.1}},
+ }
+ gw, svc := newTestGateway(t, client)
+ cfg := importAliveConfig(t, svc)
+ ch := seedChannel(t, gw, cfg.ID, "us-chicago-1", 1, 1)
+ gw.db.Create(&model.AiModelCache{ChannelID: ch.ID, ModelOcid: "ocid1..rr", Name: "cohere.rerank-v4.0-fast",
+ Vendor: "cohere", Capability: "RERANK", SyncedAt: time.Now()})
+ ctx := context.Background()
+ yes := true
+ req := aiwire.RerankRequest{Model: "cohere.rerank-v4.0-fast", Query: "q", Documents: []string{"d0", "d1"}, ReturnDocuments: &yes}
+ resp, _, err := gw.Rerank(ctx, req, "")
+ if err != nil || len(resp.Results) != 2 {
+ t.Fatalf("Rerank = %+v, %v(越界 index 应被丢弃)", resp, err)
+ }
+ if resp.Results[0].Index != 1 || resp.Results[0].Document == nil || resp.Results[0].Document.Text != "d1" {
+ t.Fatalf("results[0] = %+v", resp.Results[0])
+ }
+ // 对话模型名打 rerank:能力不匹配 → 未知模型
+ if _, _, err := gw.Rerank(ctx, aiwire.RerankRequest{Model: "meta.llama-3.3-70b-instruct", Query: "q", Documents: []string{"d"}}, ""); !errors.Is(err, ErrAiUnknownModel) {
+ t.Errorf("chat 模型走 rerank err = %v, want ErrAiUnknownModel", err)
+ }
+}
+
+// TestAiSpeech 断言 TTS 编排走 TTS 能力路由并透传音频与 Content-Type。
+func TestAiSpeech(t *testing.T) {
+ client := &gatewayStubClient{
+ fakeClient: &fakeClient{tenancy: oci.TenancyInfo{Name: "t"}},
+ speechAudio: []byte{0xFF, 0xF3}, speechCT: "audio/mpeg",
+ }
+ gw, svc := newTestGateway(t, client)
+ cfg := importAliveConfig(t, svc)
+ ch := seedChannel(t, gw, cfg.ID, "us-chicago-1", 1, 1)
+ gw.db.Create(&model.AiModelCache{ChannelID: ch.ID, ModelOcid: "ocid1..tts", Name: "xai.grok-tts",
+ Vendor: "xai", Capability: "TTS", SyncedAt: time.Now()})
+ audio, ct, _, err := gw.Speech(context.Background(), "xai.grok-tts", []byte(`{"model":"xai.grok-tts","input":"你好","language":"auto"}`), "")
+ if err != nil || ct != "audio/mpeg" || len(audio) != 2 {
+ t.Fatalf("Speech = %d bytes, ct=%s, %v", len(audio), ct, err)
+ }
+}
+
+// TestAiModerations 断言审核编排:无模型维度按分组选渠道,多条输入逐条聚合。
+func TestAiModerations(t *testing.T) {
+ one := 1.0
+ client := &gatewayStubClient{
+ fakeClient: &fakeClient{tenancy: oci.TenancyInfo{Name: "t"}},
+ guardOutcome: &oci.GuardrailsOutcome{Categories: []oci.GuardrailCategory{{Name: "OVERALL", Score: 1}}, PromptInjectionScore: &one},
+ }
+ gw, svc := newTestGateway(t, client)
+ cfg := importAliveConfig(t, svc)
+ seedChannel(t, gw, cfg.ID, "us-chicago-1", 1, 1)
+ resp, meta, err := gw.Moderations(context.Background(), "modr_test", []string{"a", "b"}, "")
+ if err != nil || len(resp.Results) != 2 || !resp.Results[0].Flagged || resp.ID != "modr_test" {
+ t.Fatalf("Moderations = %+v, meta=%+v, %v", resp, meta, err)
+ }
+ if !strings.Contains(resp.Model, "guardrails") {
+ t.Errorf("model = %s", resp.Model)
+ }
+ // 分组不匹配 → 无可用渠道
+ if _, _, err := gw.Moderations(context.Background(), "modr_x", []string{"a"}, "ghost-group"); !errors.Is(err, ErrAiNoChannel) {
+ t.Errorf("ghost 分组 err = %v, want ErrAiNoChannel", err)
+ }
+}
diff --git a/internal/service/aigateway_test.go b/internal/service/aigateway_test.go
index 8e90d4d..5b48f39 100644
--- a/internal/service/aigateway_test.go
+++ b/internal/service/aigateway_test.go
@@ -61,6 +61,26 @@ type gatewayStubClient struct {
passErrs []error
passCalls int
passRegions []string
+
+ speechAudio []byte
+ speechCT string
+ speechErr error
+ rerankRanks []oci.RerankRank
+ rerankErr error
+ guardOutcome *oci.GuardrailsOutcome
+ guardErr error
+}
+
+func (f *gatewayStubClient) GenAiCompatSpeech(ctx context.Context, cred oci.Credentials, region string, body []byte) ([]byte, string, error) {
+ return f.speechAudio, f.speechCT, f.speechErr
+}
+
+func (f *gatewayStubClient) GenAiRerank(ctx context.Context, cred oci.Credentials, region, modelOcid, query string, documents []string, topN *int) ([]oci.RerankRank, error) {
+ return f.rerankRanks, f.rerankErr
+}
+
+func (f *gatewayStubClient) GenAiApplyGuardrails(ctx context.Context, cred oci.Credentials, region, text string) (*oci.GuardrailsOutcome, error) {
+ return f.guardOutcome, f.guardErr
}
func (f *gatewayStubClient) GenAiCompatResponses(ctx context.Context, cred oci.Credentials, region string, body []byte) ([]byte, error) {
diff --git a/internal/service/airesponses.go b/internal/service/airesponses.go
index d4ed5ea..d4825bc 100644
--- a/internal/service/airesponses.go
+++ b/internal/service/airesponses.go
@@ -22,34 +22,21 @@ func respRejectStateful(req aiwire.RespRequest) error {
return nil
}
-// RespServerTools 报告工具列表是否含 xAI 服务端工具(web_search / x_search)。
-func RespServerTools(tools []aiwire.RespTool) bool {
- for _, t := range tools {
- if t.Type == "web_search" || t.Type == "x_search" {
- return true
- }
- }
- return false
-}
-
// RespPassthroughValidate 校验直通请求:模型必填,有状态特性不支持,工具类型
-// 只放行 function 与已实测的 web_search / x_search;流式仅在含服务端工具时拒绝
-// (工具流式事件形态未实测,不放开)。
+// 只放行 function 与 Oracle 文档化的服务端工具(web_search / x_search /
+// code_interpreter / mcp)。
func RespPassthroughValidate(req aiwire.RespRequest) error {
if strings.TrimSpace(req.Model) == "" {
return fmt.Errorf("model 不能为空")
}
- if req.Stream && RespServerTools(req.Tools) {
- return fmt.Errorf("服务端工具暂不支持流式:请去掉 stream 或改用 function 工具")
- }
if err := respRejectStateful(req); err != nil {
return err
}
for _, t := range req.Tools {
switch t.Type {
- case "function", "web_search", "x_search":
+ case "function", "web_search", "x_search", "code_interpreter", "mcp":
default:
- return fmt.Errorf("不支持的工具类型 %q:服务端工具仅支持 web_search / x_search", t.Type)
+ return fmt.Errorf("不支持的工具类型 %q:服务端工具仅支持 web_search / x_search / code_interpreter / mcp", t.Type)
}
}
return nil
diff --git a/internal/service/airesponses_test.go b/internal/service/airesponses_test.go
index 33acfc2..6553f26 100644
--- a/internal/service/airesponses_test.go
+++ b/internal/service/airesponses_test.go
@@ -24,27 +24,6 @@ func deref(p *int) int {
return *p
}
-func TestRespServerTools(t *testing.T) {
- tests := []struct {
- name string
- tools []aiwire.RespTool
- want bool
- }{
- {"web_search", []aiwire.RespTool{{Type: "web_search"}}, true},
- {"x_search混用", []aiwire.RespTool{{Type: "function", Name: "f"}, {Type: "x_search"}}, true},
- {"仅function", []aiwire.RespTool{{Type: "function", Name: "f"}}, false},
- {"空", nil, false},
- {"其他类型", []aiwire.RespTool{{Type: "code_interpreter"}}, false},
- }
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- if got := RespServerTools(test.tools); got != test.want {
- t.Fatalf("got %v, want %v", got, test.want)
- }
- })
- }
-}
-
func TestRespPassthroughValidate(t *testing.T) {
prev := "resp_1"
bg := true
@@ -56,12 +35,14 @@ func TestRespPassthroughValidate(t *testing.T) {
{"合法", aiwire.RespRequest{Model: "m", Tools: []aiwire.RespTool{{Type: "web_search"}}}, false},
{"混用function", aiwire.RespRequest{Model: "m", Tools: []aiwire.RespTool{{Type: "web_search"}, {Type: "function", Name: "f"}}}, false},
{"缺model", aiwire.RespRequest{Tools: []aiwire.RespTool{{Type: "web_search"}}}, true},
- {"工具加流式拒绝", aiwire.RespRequest{Model: "m", Stream: true, Tools: []aiwire.RespTool{{Type: "web_search"}}}, true},
+ {"服务端工具流式放行", aiwire.RespRequest{Model: "m", Stream: true, Tools: []aiwire.RespTool{{Type: "web_search"}}}, false},
{"无工具流式放行", aiwire.RespRequest{Model: "m", Stream: true}, false},
{"function工具流式放行", aiwire.RespRequest{Model: "m", Stream: true, Tools: []aiwire.RespTool{{Type: "function", Name: "f"}}}, false},
+ {"code_interpreter放行", aiwire.RespRequest{Model: "m", Tools: []aiwire.RespTool{{Type: "code_interpreter"}}}, false},
+ {"mcp流式放行", aiwire.RespRequest{Model: "m", Stream: true, Tools: []aiwire.RespTool{{Type: "mcp"}}}, false},
{"有状态拒绝", aiwire.RespRequest{Model: "m", PreviousResponseID: prev}, true},
{"background拒绝", aiwire.RespRequest{Model: "m", Background: &bg}, true},
- {"未知工具拒绝", aiwire.RespRequest{Model: "m", Tools: []aiwire.RespTool{{Type: "web_search"}, {Type: "mcp"}}}, true},
+ {"未知工具拒绝", aiwire.RespRequest{Model: "m", Tools: []aiwire.RespTool{{Type: "web_search"}, {Type: "file_search"}}}, true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {