Files

1966 lines
71 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.0.3
info:
title: 影策 HTTP API
version: "1.0.0"
description: |
路径前缀是 `/api`。前后端一起发布,不按路径做 API 版本。
业务 JSON 信封为 `{ code, data, msg, reason }`。`code === 0` 表示成功;失败时 HTTP status 与
`code` 都表达失败。`code` 默认等于 HTTP 状态;同一状态下的细分原因使用 `status*100+n`
(例如 40301 配额、42901 限流)。机器判断请用 `reason`,不要解析 `msg`。
TypeScript 调用面仍是 `web/src/services/api` 的 `http` 模块,不从本规范生成客户端。
servers:
- url: /api
security:
- sessionCookie: []
tags:
- name: meta
- name: auth
- name: projects
- name: canvas
- name: resources
- name: tasks
- name: assets
- name: models
- name: agent
- name: admin
- name: skills
- name: workbench
paths:
/admin/login-logs:
get:
tags: [admin]
summary: 管理员分页查询用户登录登出日志
description: 按时间倒序,保留用户快照;失败账号脱敏,无密码、验证码或会话凭据。
parameters:
- {in: query, name: keyword, schema: {type: string, maxLength: 160}, description: 用户名、昵称、脱敏账号或用户 ID}
- {in: query, name: event, schema: {type: string, enum: [login, logout]}}
- {in: query, name: method, schema: {type: string, enum: [password, email, sms, linuxdo, verification, unknown]}}
- {in: query, name: result, schema: {type: string, enum: [success, failed]}}
- {in: query, name: ip, schema: {type: string}, description: 精确匹配 IPv4 或 IPv6}
- {in: query, name: from, schema: {type: string, format: date-time}, description: 包含开始时刻,RFC3339}
- {in: query, name: to, schema: {type: string, format: date-time}, description: 包含结束时刻,RFC3339}
- {in: query, name: page, schema: {type: integer, minimum: 1, default: 1}}
- {in: query, name: pageSize, schema: {type: integer, minimum: 1, default: 20}}
responses:
"200":
description: 成功信封 data={logs,total,page,pageSize}
content:
application/json:
schema:
type: object
properties:
code: {type: integer, enum: [0]}
msg: {type: string}
data:
type: object
properties:
logs: {type: array, items: {$ref: "#/components/schemas/LoginLog"}}
total: {type: integer}
page: {type: integer}
pageSize: {type: integer}
"400": {$ref: "#/components/responses/Error"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
"500": {$ref: "#/components/responses/Error"}
/admin/login-logs/{id}:
get:
tags: [admin]
summary: 管理员读取单条登录日志详情
parameters:
- {in: path, name: id, required: true, schema: {type: string}}
responses:
"200":
description: 成功信封 data.log
content:
application/json:
schema:
type: object
properties:
code: {type: integer, enum: [0]}
msg: {type: string}
data:
type: object
properties:
log: {$ref: "#/components/schemas/LoginLog"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
"404": {$ref: "#/components/responses/Error"}
"500": {$ref: "#/components/responses/Error"}
/admin/settings/appearance/live2d:
post:
tags: [admin]
summary: 导入管理员 Live2D 模型草稿(不自动启用)
description: ZIP 最大 128 MiB,最多 256 条目;解压累计 384 MiB,单文件最大 128 MiB。只接受一个 Version 3 model3.json 及 ZIP 内 MOC3、PNG、JSON 引用。启用通过 PATCH /admin/settings/appearance 的 canvas 配置完成。
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required: [file]
properties:
file: {type: string, format: binary}
responses:
"200":
description: 成功信封 data.model 包含 resourceId 和服务端确认的 entry
content:
application/json:
schema:
type: object
properties:
code: {type: integer, enum: [0]}
msg: {type: string}
data:
type: object
properties:
model:
type: object
required: [resourceId, entry]
properties:
resourceId: {type: string}
entry: {type: string}
"400": {$ref: "#/components/responses/Error"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
"429": {$ref: "#/components/responses/Error"}
/admin/settings/appearance/live2d/{id}/{file}:
get:
tags: [admin]
summary: 读取模型草稿文件(管理员所有者或当前配置引用)
parameters:
- {in: path, name: id, required: true, schema: {type: string}}
- {in: path, name: file, required: true, description: ZIP 内相对路径,可包含多级目录, schema: {type: string}}
responses:
"200": {description: JSON、PNG 或 MOC3 文件,非 JSON 信封}
"400": {$ref: "#/components/responses/Error"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
/public/appearance/live2d/{id}/{file}:
get:
tags: [meta]
security: []
summary: 读取当前启用的 Live2D 模型文件
parameters:
- {in: path, name: id, required: true, schema: {type: string}}
- {in: path, name: file, required: true, description: ZIP 内相对路径,可包含多级目录, schema: {type: string}}
responses:
"200": {description: JSON、PNG 或 MOC3 文件,非 JSON 信封;停用后拒绝公开读取}
"400": {$ref: "#/components/responses/Error"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
/tools:
get:
tags: [canvas]
summary: 列出可见且启用的生成工具
parameters:
- {in: query, name: scope, schema: {type: string, enum: [public, favorites, custom], default: public}}
- {in: query, name: type, schema: {type: string, enum: [style, motion, nine_grid, effect]}}
- {in: query, name: tag, schema: {type: string}}
- {in: query, name: search, schema: {type: string}}
- {in: query, name: page, schema: {type: integer, minimum: 1, default: 1}}
- {in: query, name: pageSize, schema: {type: integer, minimum: 1, maximum: 80, default: 20}}
responses:
"200": {description: "标准信封 data 为 tools(摘要不含 prompt/extraInfo)、totalCount、page、pageSize、hasMore"}
"401": {description: 未登录}
post:
tags: [canvas]
summary: 创建当前用户的工具
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/ToolMutation'}
responses:
"200": {description: 标准信封 data 为完整工具}
"400": {description: 参数无效或预览资源不符合要求}
"401": {description: 未登录}
/skills/presets:
get:
tags: [canvas]
security: []
summary: 获取公开场景技能预设目录
responses:
"200":
description: 标准信封 data 为 presets 数组;预设只引用公开且启用的种子技能
"500": {$ref: "#/components/responses/Error"}
/skills:
get:
tags: [skills]
summary: 列出技能;在个人技能视图按技能库分类筛选
parameters:
- {in: query, name: scope, schema: {type: string, enum: [public, mine, created, favorites], default: public}}
- {in: query, name: libraryCategoryId, description: 用户技能库分类 ID,仅支持 mine 或 created 视图;与 libraryUncategorized 互斥, schema: {type: string}}
- {in: query, name: libraryUncategorized, description: 仅列出未归类技能,仅支持 mine 或 created 视图;与 libraryCategoryId 互斥, schema: {type: boolean}}
responses:
"200": {description: 标准信封 data 为技能列表及分页信息;categories 含共享分类 value、label 和技能广场公开技能 count}
"400": {$ref: "#/components/responses/Error"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
"404": {$ref: "#/components/responses/Error"}
/skills/library-categories:
get:
tags: [skills]
summary: 获取当前用户可见的技能库分类和数量
parameters:
- {in: query, name: scope, schema: {type: string, enum: [mine, created], default: mine}}
responses:
"200": {description: 标准信封 data 为 categories、totalCount、uncategorizedCount;分类含 id、name、scope、count}
"401": {$ref: "#/components/responses/Error"}
post:
tags: [skills]
summary: 创建个人或平台技能库分类
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [name]
properties:
name: {type: string, minLength: 1, maxLength: 64}
scope: {type: string, enum: [personal, platform], default: personal}
responses:
"200": {description: 标准信封 data.category 为新分类}
"400": {$ref: "#/components/responses/Error"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
/skills/library-categories/{id}:
parameters:
- {in: path, name: id, required: true, schema: {type: string}}
delete:
tags: [skills]
summary: 删除技能库分类并解除相关技能归类,不删除技能
responses:
"200": {description: "标准信封 data 为 {deleted: true}"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
"404": {$ref: "#/components/responses/Error"}
/skills/{id}/library-category:
parameters:
- {in: path, name: id, required: true, description: 技能 ID, schema: {type: string}}
patch:
tags: [skills]
summary: 为当前用户已加入或自建的技能设置/清除技能库分类
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [categoryId]
properties:
categoryId: {type: string, description: 个人分类或可见平台分类 ID;空字符串表示取消归类}
responses:
"200": {description: 标准信封 data.skill 为更新后的技能}
"400": {$ref: "#/components/responses/Error"}
"401": {$ref: "#/components/responses/Error"}
"403": {$ref: "#/components/responses/Error"}
"404": {$ref: "#/components/responses/Error"}
/tools/{id}:
parameters:
- {in: path, name: id, required: true, schema: {type: integer, format: int64, minimum: 1}}
get:
tags: [canvas]
summary: 查询可见且启用工具的完整详情
responses:
"200": {description: 标准信封 data 为完整工具,包含 prompt 和 extraInfo}
"404": {description: 工具不存在或不可见}
delete:
tags: [canvas]
summary: 删除自己的用户工具及关联收藏,不删除预览文件
responses:
"200": {description: "标准信封 data 为 {deleted: true}"}
"404": {description: 工具不存在或不能删除}
/tools/{id}/favorite:
parameters:
- {in: path, name: id, required: true, schema: {type: integer, format: int64, minimum: 1}}
post:
tags: [canvas]
summary: 幂等收藏可见工具
responses:
"200": {description: 标准信封 data 为完整工具和收藏状态}
"404": {description: 工具不存在或不可见}
delete:
tags: [canvas]
summary: 幂等取消收藏可见工具
responses:
"200": {description: 标准信封 data 为完整工具和收藏状态}
"404": {description: 工具不存在或不可见}
/model-catalog:
get:
tags: [models]
summary: 获取创作端模型目录
description: |
固定 source=system,channels 直接来自系统渠道下的模型列表,models 为空数组;不反查逻辑模型。
一级跨渠道按 displayName 分组,二级显示 channelLabel;模型请求仍使用 channelId + modelKey 定位。
channelLabel 是后台渠道模型创建和更新时配置的渠道展示名,去除首尾空白后最多 80 字,空字符串表示使用所属渠道名称。
description 是后台渠道模型创建和更新时填写的公开模型描述,去除首尾空白后最多 500 字;空字符串表示未填写。
displayName 和 icon 用于一级模型菜单,channelLabel 不参与路由、权限或计费。
渠道级 publicAlias 已废弃;成本配置和成本快照仅供管理端,不包含在本接口及用户报价中。
responses:
"200":
description: 当前启用的模型目录
content:
application/json:
schema:
type: object
properties:
code:
type: integer
enum: [0]
msg:
type: string
data:
type: object
required: [source, models, channels]
properties:
source:
type: string
enum: [system]
models:
type: array
items:
type: object
channels:
type: array
items:
type: object
properties:
id:
type: string
displayName:
type: string
models:
type: array
items:
type: object
properties:
modelKey:
type: string
displayName:
type: string
icon:
type: string
channelLabel:
type: string
maxLength: 80
default: ""
tags:
type: array
maxItems: 5
description: 后台模型创建及更新使用同名字段;文字去除首尾空白且不能重复,空数组清除标签,仅用于展示。
items:
type: object
required: [text, color]
properties:
text:
type: string
minLength: 1
maxLength: 12
color:
type: string
enum: [purple, blue, green, gold, orange, pink]
description:
type: string
maxLength: 500
default: ""
"401":
$ref: "#/components/responses/Error"
/model-catalog/quote:
post:
tags: [models]
summary: 按当前参数预估系统渠道模型费用
description: |
需要登录会话 Cookie。仅接受启用的系统渠道和模型,采用服务端能力默认值及价格档选择规则。
不创建任务或账单、不冻结或扣除积分,也不调用模型供应商。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [channelId, modelKey, intent]
properties:
channelId:
type: string
minLength: 1
modelKey:
type: string
minLength: 1
description: 系统渠道中配置的模型键
intent:
$ref: "#/components/schemas/ModelRequestIntent"
responses:
"200":
$ref: "#/components/responses/ModelQuote"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
/models/{id}/quote:
post:
tags: [models]
summary: 按当前参数预估前台模型费用
description: |
需要登录会话 Cookie。请求正文直接为创作意图,不使用 intent 外层包装。
服务端按前台模型能力、默认参数、供应线路和价格策略报价,不创建任务、账单或积分冻结。
parameters:
- in: path
name: id
required: true
schema: { type: string }
description: 前台逻辑模型 ID
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ModelRequestIntent"
responses:
"200":
$ref: "#/components/responses/ModelQuote"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
/canvas-projects/{id}:
parameters:
- in: path
name: id
required: true
schema: { type: string }
get:
tags: [canvas]
summary: 读取当前用户画布内容和 revision
responses:
"200":
description: 信封 data.project 包含完整画布及服务端 revision
"304":
description: If-None-Match 命中当前 revision,正文为空
"404":
description: 画布不存在或不属于当前用户
delete:
tags: [canvas]
summary: 显式删除当前用户画布
description: 删除后迟到的媒体回写和编辑操作不会重新创建画布;只有新的 create_canvas operation 可以显式创建同 ID 画布。
responses:
"200":
description: 画布已删除,信封 data.id 返回画布 ID
"401":
description: 未登录
"404":
description: 画布不存在或不属于当前用户
/canvas-projects/{id}/operations:
parameters:
- in: path
name: id
required: true
schema: { type: string }
patch:
tags: [canvas]
summary: 按对象或字段变更写入画布
description: |
请求只提交对象级或字段级 operations,不提交整批画布快照。
mutationId 是一次请求的幂等身份;响应丢失、断网、刷新或后台重试时必须复用同一个 mutationId 与原始 operations。
更新、删除和连接操作要求目标存在并通过对象基线校验;同一字段冲突不会覆盖远端修改。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [mutationId, operations]
properties:
mutationId:
type: string
minLength: 1
maxLength: 160
description: 一次写入请求的幂等身份
baseRevision:
type: integer
format: int64
minimum: 0
description: 生成 operations 时已确认的画布 revision,用于诊断和响应
operations:
type: array
minItems: 1
maxItems: 500
items:
type: object
required: [type]
additionalProperties: true
description: create_canvas、create_node、patch_node、remove_node、create_connection、update_connection、remove_connection 或 set_field
responses:
"200":
description: 信封 data.project 返回当前画布摘要,data.mutationId 返回原 mutationId
"400":
description: 请求、字段、对象基线或素材引用格式不合法
"401":
description: 未登录
"404":
description: 画布不存在或不属于当前用户,且请求未包含显式 create_canvas
"409":
description: 对象并发冲突或同一 mutationId 对应的请求摘要不同;原事务不会被覆盖
"428":
description: 缺少执行所需的对象基线
/public/welcome:
get:
tags: [meta]
security: []
summary: 读取欢迎页开放状态
responses:
"200":
description: 信封 data 仅包含 welcomeEnabled 布尔值,默认 true;Cache-Control 为 no-store
"500":
description: 配置读取失败
/agent/capabilities:
get:
tags: [agent]
summary: 读取云端 Agent 能力
responses:
"200":
description: 信封 data 包含 version、permissionModes、contextScopes、skills、writeTools、billing、maxHistoryPairs、maxSteps、maxHistoryBytes、capabilitySetVersion、capabilitySetHash、nodeTypes、tools;maxHistoryPairs 为跨轮保留的用户对话轮数,maxSteps 为 0 表示无固定模型调用上限,历史仍受 maxHistoryBytes 限制
/agent/skills/usage:
get:
tags: [agent]
summary: 读取当前用户技能的使用统计(由运行日志聚合,只读)
responses:
"200":
description: 信封 data 含 scannedRuns、searchCalls 与按启用次数降序的 skills;每个技能含 runsEnabled、searchHits、readCalls、readFailures、entryReads、cardReads 与 topCards(最多 5 条最热卡路径)。统计仅覆盖调用方本人最近的运行,且不含任何技能正文
"401":
description: 未登录
/agent/profile:
get:
tags: [agent]
summary: 读取生效的用户、项目、画布 Agent 偏好层
parameters:
- in: query
name: scope
schema:
type: string
enum: [user, project, canvas]
- in: query
name: projectId
schema:
type: string
- in: query
name: canvasId
schema:
type: string
responses:
"200":
description: 信封 data 为合并 revision、hash 和按 user/project/canvas 顺序排列的 layers;每层含独立数字 revision
"403":
description: 项目或画布不属于当前用户
patch:
tags: [agent]
summary: 使用单层 revision CAS 更新 Agent 偏好
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AgentProfileRequest"
responses:
"200":
description: 返回更新后的生效偏好视图
"409":
description: 偏好 revision 已变化,须重新读取后保存
/agent/memories:
get:
tags: [agent]
summary: 列出当前用户的 Agent 记忆
parameters:
- in: query
name: status
schema:
type: string
enum: [pending, approved, rejected]
- in: query
name: limit
schema:
type: integer
minimum: 1
maximum: 500
responses:
"200":
description: 信封 data.memories
"401":
$ref: "#/components/responses/Error"
post:
tags: [agent]
summary: 手动添加一条个人记忆(直接批准)
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [topic, category, situation]
properties:
topic: { type: string }
category: { type: string }
situation: { type: string }
lesson: { type: string }
source: { type: string }
steps:
type: array
items:
type: object
properties:
tool: { type: string }
action: { type: string }
note: { type: string }
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
/agent/memories/export:
get:
tags: [agent]
summary: 导出当前用户的 Agent 记忆
responses:
"200":
description: 信封 data 为 version/kind/exportedAt/memories
"401":
$ref: "#/components/responses/Error"
/agent/memories/import:
post:
tags: [agent]
summary: 导入 Agent 记忆 JSON
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
version: { type: integer }
kind: { type: string }
memories: { type: array }
responses:
"200":
description: 信封 data 含 imported、merged、skipped
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
/agent/memories/settings:
get:
tags: [agent]
summary: 读取当前用户的记忆压缩设置与最近一次压缩状态
responses:
"200":
description: 信封 data 含 compactInterval、模型字段、lastStatus、summary
"401":
$ref: "#/components/responses/Error"
patch:
tags: [agent]
summary: 更新记忆压缩周期和文本模型
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
compactInterval:
type: string
enum: [off, daily, weekly, monthly]
logicalModelId: { type: string }
channelId: { type: string }
channelModelKey: { type: string }
model: { type: string }
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
/agent/memories/compact:
post:
tags: [agent]
summary: 提交一次个人记忆压缩任务(走用户文本模型计费)
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
logicalModelId: { type: string }
channelId: { type: string }
channelModelKey: { type: string }
model: { type: string }
responses:
"200":
description: 信封 data 为压缩设置视图,lastStatus 为 queued
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
/agent/memories/{id}:
parameters:
- in: path
name: id
required: true
schema: { type: string }
patch:
tags: [agent]
summary: 更新一条属于当前用户的记忆
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
delete:
tags: [agent]
summary: 删除一条属于当前用户的记忆
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/agent/memories/{id}/decide:
post:
tags: [agent]
summary: 批准或拒绝一条属于当前用户的待审记忆
parameters:
- in: path
name: id
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [decision]
properties:
decision:
type: string
enum: [approve, reject]
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/agent/runs:
post:
tags: [agent]
summary: 创建一轮云端 Agent 任务
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CloudAgentRequest"
responses:
"200":
description: 信封 data.run,包含新一轮 id、canvasId、status、permissionMode、model 及时间
"400":
description: 参数、能力、模型或预算不符合要求,未创建任务
"409":
description: 幂等键已用于不同请求
/agent/runs/{id}:
parameters:
- $ref: "#/components/parameters/AgentRunID"
get:
tags: [agent]
summary: 读取当前用户的 Agent 轮次
description: data.run 只返回一页事件(默认最新 40 条)并带上 eventSeqBase、eventCount、latestSeq、eventsTruncated:eventSeqBase 是本次首条事件之前已入库的条数(不变量 events[i].seq == eventSeqBase + i + 1),latestSeq 可直接作为下次 sinceSeq,eventsTruncated 表示还有更早的记录未随本次返回。读取走 (run_id, sequence) 的 keyset 分页,不使用 offset;升级前把事件放在 state_json 里的轮次在事件表中没有行,读取回退到内存窗口。
parameters:
- in: query
name: sinceSeq
required: false
description: 只返回该事件序号之后的事件(非负整数,单次最多 500 条);追平或越界时返回空 events
schema: { type: integer, minimum: 0 }
- in: query
name: eventLimit
required: false
description: 单次返回的事件条数上限,1–500,默认为尾部窗口大小
schema: { type: integer, minimum: 1, maximum: 500 }
responses:
"200":
description: 信封 data.run(含 events 与 eventSeqBase / eventCount / latestSeq / eventsTruncated)
"400":
description: sinceSeq 或 eventLimit 不是整数或超出范围
"404":
description: 轮次不存在或不属于当前用户
/agent/runs/{id}/messages:
parameters:
- $ref: "#/components/parameters/AgentRunID"
post:
tags: [agent]
summary: 从服务端父轮历史创建新轮次
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CloudAgentRequest"
responses:
"200":
description: 信封 data.run(新的 ID)
"409":
description: 父轮仍在执行或幂等键冲突
/agent/runs/{id}/interjections:
parameters:
- $ref: "#/components/parameters/AgentRunID"
post:
tags: [agent]
summary: 向正在运行的 Agent 轮次插入一句话
description: 不新建轮次、不产生新的扣费身份。插话排进当前运行,在下一次模型调用前送达;运行已结束返回 409。
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [text, messageId]
properties:
text:
type: string
maxLength: 4000
messageId:
type: string
maxLength: 160
responses:
"200":
description: 信封 data.accepted 与 data.pending
"409":
description: 本轮已结束,应改为新一轮发送
/agent/runs/{id}/cancel:
parameters:
- $ref: "#/components/parameters/AgentRunID"
post:
tags: [agent]
summary: 取消当前用户的 Agent 轮次
responses:
"200":
description: 信封 data.accepted
/agent/runs/{id}/undo:
parameters:
- $ref: "#/components/parameters/AgentRunID"
post:
tags: [agent]
summary: 撤销当前 Agent 运行产生的最新画布变更
description: 仅撤销仍是最新快照、且未提交生成任务的画布变更;不会取消任务或退款。
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [expectedSnapshotHash]
properties:
stepId:
type: string
maxLength: 160
expectedSnapshotHash:
type: string
minLength: 64
maxLength: 64
pattern: '^[0-9a-fA-F]{64}$'
reason:
type: string
maxLength: 2000
responses:
"200":
description: 信封 data.accepted 与当前快照哈希
"400":
description: 请求无效、快照不可撤销或已提交任务不能撤销
"409":
description: 画布已发生后续变化、操作已处理或 stepId 不匹配
/agent/runs/{id}/approvals/{approvalId}/decision:
parameters:
- $ref: "#/components/parameters/AgentRunID"
- name: approvalId
in: path
required: true
schema:
type: string
post:
tags: [agent]
summary: 提交 Agent 工具审批决定
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [decision]
properties:
decision:
type: string
enum: [approve, reject]
reason:
type: string
maxLength: 2000
mediaSettings:
type: object
additionalProperties: false
description: 仅 approve 图片生成审批可传;替换本次模型、画幅和质量,重新强校验,不修改提示词、引用或目标。logicalModelId 与 channelId + channelModelKey 二选一。
required: [size, quality]
properties:
logicalModelId:
type: string
channelId:
type: string
channelModelKey:
type: string
size:
type: string
quality:
type: string
responses:
"200":
description: 信封 data.accepted
"409":
description: 审批不存在、已过期或决定冲突
/agent/runs/{id}/events:
parameters:
- $ref: "#/components/parameters/AgentRunID"
get:
tags: [agent]
summary: Agent 运行事件回放与持续订阅
parameters:
- name: after
in: query
schema:
type: integer
minimum: 0
- name: Last-Event-ID
in: header
schema:
type: integer
minimum: 0
responses:
"200":
description: 首次及 revision 变化时发送紧凑 run_snapshot;无变化时 heartbeat;agent_event.seq 为递增游标,cleanupPending 期间持续发送
content:
text/event-stream:
schema:
type: string
/openapi.yaml:
get:
tags: [meta]
security: []
summary: 本 OpenAPI 文档
responses:
"200":
description: OpenAPI 3.0 YAML
content:
application/yaml:
schema:
type: string
/admin/channels/{id}/duplicate:
post:
tags: [admin]
summary: 复制系统渠道
parameters:
- in: path
name: id
required: true
schema: { type: string }
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/admin/channels/{id}/models/batch-reprice:
post:
tags: [admin]
summary: 批量保存系统渠道模型最终销售价
description: |
仅管理员可用。接收浏览器计算或手工修改后的最终售价及原始价格版本,不在服务端重算。
前端按成本/(1−利润率)计算,支持0–6位积分小数四舍五入及重新计算。
必须提交所选模型全部已启用规格,不改变成本、规格启停或模型启停。
当前计费方式的价格字段必须完整且不能多余,价格为非负整数微积分,null无效。
缺少成本/售价配置、重复或失效 ID、越权、超限价格、过期版本或并发版本冲突均整批拒绝。
parameters:
- in: path
name: id
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [models]
properties:
models:
type: array
minItems: 1
maxItems: 100
items:
type: object
required: [modelId, priceVersion, priceTiers]
properties:
modelId: { type: string, minLength: 1 }
priceVersion: { type: integer, format: int64, minimum: 1 }
priceTiers:
type: array
minItems: 1
items:
type: object
required: [id, priceVersion, prices]
properties:
id: { type: string, minLength: 1 }
priceVersion: { type: integer, format: int64, minimum: 1 }
prices:
type: object
additionalProperties: false
description: 按次/秒仅unit字段;文本Token为输入、输出、缓存;视频Token仅输出。必须完整提交对应字段。
properties:
unitPriceMicrocredits: { type: integer, format: int64, minimum: 0, maximum: 9007199254740991 }
inputTokenPriceMicrocredits: { type: integer, format: int64, minimum: 0, maximum: 1000000000000 }
outputTokenPriceMicrocredits: { type: integer, format: int64, minimum: 0, maximum: 1000000000000 }
cachedTokenPriceMicrocredits: { type: integer, format: int64, minimum: 0, maximum: 1000000000000 }
example: { models: [{ modelId: MODEL001, priceVersion: 4, priceTiers: [{ id: TIER001, priceVersion: 8, prices: { unitPriceMicrocredits: 1370000 } }] }] }
responses:
"200":
description: 更新成功,data.updated 为更新的模型数量
content:
application/json:
schema:
type: object
properties:
code: { type: integer, enum: [0] }
msg: { type: string }
data:
type: object
properties:
updated: { type: integer }
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
/admin/agent-lessons:
get:
tags: [admin]
summary: 按用户筛选查看个人 Agent 记忆
parameters:
- in: query
name: status
schema:
type: string
enum: [pending, approved, rejected]
- in: query
name: userId
schema:
type: string
- in: query
name: keyword
schema:
type: string
- in: query
name: limit
schema:
type: integer
minimum: 1
maximum: 200
responses:
"200":
description: 信封 data.lessons 含解析后的 steps、authorUserId、authorUsername、authorDisplayName
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
/admin/agent-lessons/{id}:
delete:
tags: [admin]
summary: 删除一条用户的 Agent 记忆
parameters:
- in: path
name: id
required: true
schema: { type: string }
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/auth/profile:
get:
tags: [auth]
summary: 当前用户个人信息及安全能力
description: 返回 user、hasPassword、emailEnabled、linuxdoEnabled 和可选 reauthenticatedUntil;个人头像选择覆盖第三方头像。内部密码散列与头像版本字段不返回。
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
/auth/profile/avatar:
put:
tags: [auth]
summary: 保存当前用户头像
description: 真实 PNG/JPEG,最大 5 MiB、1600 万像素,居中裁剪并缩小到最大512像素PNG。响应 data.user 包含更新后的头像地址。
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required: [file]
properties:
file: { type: string, format: binary }
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"429":
$ref: "#/components/responses/Error"
delete:
tags: [auth]
summary: 使用系统默认头像
description: 清除本用户头像并保存 default 选择,后续第三方登录仍使用系统头像。返回 data.user。
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"429":
$ref: "#/components/responses/Error"
/auth/profile/avatar/default:
post:
tags: [auth]
summary: 选择系统头像
description: 保存选择并原子清除自定义图片,返回 data.user。系统头像由共享组件渲染;不接受客户端 URL 或任意图标标识。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [preset]
properties:
preset:
type: string
enum: [person, director, camera, cat, rabbit, robot, rocket, sparkles]
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"429":
$ref: "#/components/responses/Error"
/auth/profile/avatar/{userId}:
get:
tags: [auth]
summary: 读取当前账号头像 PNG
parameters:
- name: userId
in: path
required: true
schema: { type: string }
- name: v
in: query
schema: { type: string }
responses:
"200":
description: 仅当前用户可读,private no-store
content:
image/png:
schema: { type: string, format: binary }
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/auth/profile/password:
post:
tags: [auth]
summary: 修改或设置本地密码并撤销所有会话
description: 已有密码必须校验 currentPassword;纯第三方账号须在当前会话完成5分钟内的Linux.do重新授权核验。成功返回 data.changed=true 并清除会话 Cookie。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [newPassword]
properties:
currentPassword: { type: string, format: password }
newPassword:
type: string
format: password
minLength: 8
maxLength: 72
description: 至少8个Unicode字符,UTF-8字节长度不超过72
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"429":
$ref: "#/components/responses/Error"
/auth/profile/email-code:
post:
tags: [auth]
summary: 向新邮箱发送专用验证码
description: 验证当前密码或当前会话最近的Linux.do核验;新地址未被占用且不同于旧地址。返回 ticket、expiresIn=600、retryAfter=60;票据绑定用户/会话/凭据,仅profile_email用途有效。发送失败显式报错。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email]
properties:
email: { type: string, format: email }
currentPassword: { type: string, format: password }
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
"429":
$ref: "#/components/responses/Error"
"503":
$ref: "#/components/responses/Error"
/auth/profile/email:
post:
tags: [auth]
summary: 验证新邮箱并更新绑定
description: 原子校验邮箱唯一性、消费验证码、更新已验证邮箱并撤销全部会话;清除Cookie。返回changed=true及notificationStatus(sent/failed/not_needed),failed仅表示已更新后的原邮箱通知失败。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [ticket, emailCode]
properties:
ticket: { type: string }
emailCode: { type: string, pattern: "^[0-9]{6}$" }
currentPassword: { type: string, format: password }
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
"429":
$ref: "#/components/responses/Error"
/auth/profile/linuxdo/start:
get:
tags: [auth]
summary: 发起当前账号Linux.do身份重新核验
description: OAuth state绑定当前账号和当前会话,回调只接受原绑定subject;不创建账号或新登录会话。授权成功返回/settings?section=profile&reauth=success,失败返回reauth=error。
responses:
"302":
description: 跳转到第三方授权页面
headers:
Location:
schema: { type: string, format: uri }
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
"429":
$ref: "#/components/responses/Error"
/auth/session:
get:
tags: [auth]
summary: 当前登录会话
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
/auth/login:
post:
tags: [auth]
security: []
summary: 登录并设置会话 Cookie
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [username, password]
properties:
username: { type: string }
password: { type: string }
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
/projects:
get:
tags: [projects]
summary: 短剧项目列表
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
post:
tags: [projects]
summary: 创建短剧项目
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
/resources:
get:
tags: [resources]
summary: 当前用户资源列表
responses:
"200":
$ref: "#/components/responses/Envelope"
post:
tags: [resources]
summary: 上传资源文件
responses:
"200":
$ref: "#/components/responses/Envelope"
"403":
description: 配额用尽(code=40301, reason=quota_exceeded)
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
/resources/access:
post:
tags: [resources]
summary: 批量签发当前用户资源访问描述
description: 统一处理展示、下载、复制、浏览器字节处理和模型输入;客户端不能通过查询参数选择 direct/proxy。每项独立成功或失败。
requestBody:
required: true
content:
application/json:
schema:
type: array
minItems: 1
maxItems: 100
items:
type: object
required: [resourceId]
properties:
resourceId: {type: string}
purpose: {type: string, enum: [display, copy, download, browser-process, provider-input], default: display}
variant: {type: string, enum: [original, playback], default: original}
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
/resources/{id}/file:
get:
tags: [resources]
summary: 读取资源二进制(非 JSON 信封)
parameters:
- in: path
name: id
required: true
schema: { type: string }
- in: query
name: access
schema: { type: string, enum: ["1"] }
description: 仅返回统一访问描述,不返回文件正文。
- in: query
name: variant
schema: { type: string, enum: [original, playback], default: original }
- in: query
name: purpose
schema: { type: string, enum: [display, download, browser-process], default: display }
responses:
"200":
description: 文件流
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/workbench/tools:
get:
tags: [workbench]
summary: 获取当前用户可用的工作台工具
parameters:
- in: query
name: kind
required: true
schema: { type: string, enum: [image, video] }
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
/workbench/tasks:
get:
tags: [workbench]
summary: 查询当前用户的工作台任务
parameters:
- in: query
name: kind
required: true
schema: { type: string, enum: [image, video] }
- in: query
name: activeOnly
schema: { type: boolean, default: false }
- in: query
name: pageSize
schema: { type: integer, minimum: 1, maximum: 100, default: 50 }
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
post:
tags: [workbench]
summary: 创建工作台生成任务
description: 仅接受模型选择意图、资源 ID、提示词和允许的生成参数;toolId 可选,服务端校验开关、所选工具、资源、模型能力和账单,不接受客户端 providerConfig、密钥或上游 URL。
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [kind, prompt, model, modelChoice, parameters, references]
properties:
kind: { type: string, enum: [image, video] }
toolId: { type: string }
presetId: { type: string }
prompt: { type: string, minLength: 1, maxLength: 32000 }
model: { type: string }
logicalModelId: { type: string }
modelChoice:
type: object
additionalProperties: false
properties:
logicalModelId: { type: string }
modelName: { type: string }
workbench:
type: object
additionalProperties: false
properties:
kind: { type: string, enum: [image, video] }
toolId: { type: string }
presetId: { type: string }
parameters:
type: object
additionalProperties: false
properties:
size: { type: string }
quality: { type: string }
count: { type: integer, minimum: 1 }
videoSeconds: { type: integer, minimum: 1 }
ratio: { type: string }
resolution: { type: string }
generateAudio: { type: boolean }
watermark: { type: boolean }
references:
type: array
maxItems: 20
items:
type: object
additionalProperties: false
required: [resourceId, kind, role]
properties:
resourceId: { type: string }
kind: { type: string, enum: [image, video, audio] }
role: { type: string, enum: [reference, first_frame, last_frame] }
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"403":
$ref: "#/components/responses/Error"
/admin/workbench/tools:
get:
tags: [workbench, admin]
summary: 管理工作台工具目录
parameters:
- in: query
name: kind
schema: { type: string, enum: [image, video] }
responses:
"200":
$ref: "#/components/responses/Envelope"
"403":
$ref: "#/components/responses/Error"
/tasks:
post:
tags: [tasks]
summary: 创建生成任务
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
/tasks/{id}/recover-media:
post:
tags: [tasks]
summary: 按原任务 ID 重试作品保存,不重新生成或创建计费订单
description: 仅当前用户有恢复记录的保存失败任务可重入队;已在队列或运行中时幂等返回。每任务最多手动恢复三次,间隔至少一分钟。已取消、已退款或归属项目不可用时拒绝。
parameters:
- in: path
name: id
required: true
schema: { type: string }
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/tasks/{id}/text-events:
get:
tags: [tasks]
summary: 文本任务 SSE
parameters:
- in: path
name: id
required: true
schema: { type: string }
- in: query
name: after
schema: { type: integer }
description: 递增事件游标,不要用任务 ID
responses:
"200":
description: text/event-stream
/assets:
get:
tags: [assets]
summary: 用户素材库
responses:
"200":
$ref: "#/components/responses/Envelope"
/assets/batch-delete:
post:
tags: [assets]
summary: 批量彻底删除当前用户素材
description: 顶层 JSON 数组,一次请求、一个数据库事务。所有 ID 必须属于当前用户,不受任务、画布或历史引用阻塞;共享文件保留,其余通过 Outbox 异步清理,失败重试。任一素材不存在、越权或数据库写入失败时整批不删除。
requestBody:
required: true
content:
application/json:
schema:
type: array
minItems: 1
maxItems: 1000
items:
type: string
minLength: 1
example: ["asset-1", "asset-2"]
responses:
"200":
description: 成功信封,data.ids 返回本次请求的素材 ID 数组;物理文件清理由后台执行。
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/Envelope"
- type: object
properties:
data:
type: object
required: [ids]
properties:
ids:
type: array
items: { type: string }
"400":
$ref: "#/components/responses/Error"
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
"500":
$ref: "#/components/responses/Error"
/assets/{id}:
parameters:
- in: path
name: id
required: true
schema: { type: string }
delete:
tags: [assets]
summary: 彻底删除当前用户素材
description: 不依赖素材 archived 状态,也不受画布、任务、项目或历史快照引用阻塞;其他素材共享的物理对象仍保留。
responses:
"200":
$ref: "#/components/responses/Envelope"
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
components:
parameters:
AgentRunID:
name: id
in: path
required: true
schema:
type: string
securitySchemes:
sessionCookie:
type: apiKey
in: cookie
name: open_ai_canvas_session
schemas:
LoginLog:
type: object
properties:
id: {type: string}
userId: {type: string, nullable: true}
username: {type: string, description: 事件时用户名快照}
displayName: {type: string}
account: {type: string, description: 用户名或脱敏的尝试账号}
event: {type: string, enum: [login, logout]}
method: {type: string, enum: [password, email, sms, linuxdo, verification, unknown]}
source: {type: string, enum: [login, registration, logout]}
result: {type: string, enum: [success, failed]}
ip: {type: string}
userAgent: {type: string, maxLength: 512, description: 客户端自报信息,不作为身份判断依据}
sessionRef: {type: string, description: 会话 ID 的单向哈希,仅关联历史事件,不含 Token}
reason: {type: string}
message: {type: string}
createdAt: {type: string, format: date-time}
ToolMutation:
type: object
required: [type, label, prompt]
properties:
type: {type: string, enum: [style, motion, nine_grid, effect]}
label: {type: string, description: 名称最多 120 字节}
prompt: {type: string, description: 最多 8000 字节,不允许嵌套工具标签}
visibility: {type: string, enum: [private, public], default: private}
desc: {type: string}
tag: {type: string}
cover: {type: string, description: 本人已上传完成的资源 URL,仅限私有工具}
mediaUrl: {type: string, description: 本人已上传完成的资源 URL,仅限私有工具}
extraInfo: {type: array, items: {type: string}}
ratio: {type: string}
ModelRequestIntent:
type: object
required: [capability]
properties:
capability:
type: string
enum: [text, image, video, audio]
operation:
type: string
description: 可选生成操作,必须符合所选模型的能力合同
inputs:
type: object
description: 按素材类型统计的参考数量,如 image、video、audio;另受所选模型的数量上限约束
additionalProperties:
type: integer
minimum: 0
maximum: 128
options:
type: object
description: 当前创作规格;未指定的参数使用服务端默认值
additionalProperties: true
example:
vquality: 720p
size: "16:9"
videoSeconds: 5
videoGenerateAudio: true
LogicalModelQuote:
type: object
required: [logicalModelId, billingMode, quantity, amountMicrocredits, estimated]
properties:
logicalModelId:
type: string
description: 前台逻辑模型 ID;直接查询系统渠道模型时为空字符串
billingMode:
type: string
enum: [fixed_request, per_second, token]
quantity:
type: integer
format: int64
minimum: 1
description: 按次为 1,按秒为生成秒数,按 Token 为预留用量(视频含平台预留余量)
amountMicrocredits:
type: integer
format: int64
minimum: 0
description: 预估预留微积分,1000000 微积分等于 1 积分;明确配置的免费价格返回 0
estimated:
type: boolean
description: Token 计费为 true;优先有效上游 usage,视频无有效用量时按提交的公式快照结算,预留不构成费用上限
videoTokenEstimate:
$ref: "#/components/schemas/VideoTokenEstimate"
VideoTokenEstimate:
type: object
description: 仅视频 Token 报价返回;将火山公式用量和平台预留余量分开披露
required: [formulaTokens, reservedTokens, outputWidth, outputHeight, framesPerSecond, outputSeconds, referenceSeconds, referenceDurationEstimated, dimensionsEstimated, reservationMarginPercent]
properties:
formulaTokens:
type: integer
format: int64
minimum: 1
description: 按(参考视频总秒数 + 输出秒数)× 输出宽 × 输出高 × 帧率 / 1024 向上取整;上游最低计费用量可能更高
reservedTokens:
type: integer
format: int64
minimum: 1
description: 公式用量叠加平台预留余量后向上取整
outputWidth:
type: integer
format: int64
minimum: 1
outputHeight:
type: integer
format: int64
minimum: 1
framesPerSecond:
type: integer
format: int64
minimum: 1
outputSeconds:
type: integer
format: int64
minimum: 1
referenceSeconds:
type: number
format: double
minimum: 0
description: 计入公式的参考视频总秒数;报价仅有参考数量时采用预估时长
referenceDurationEstimated:
type: boolean
description: 参考时长未知、使用预估值时为 true
dimensionsEstimated:
type: boolean
description: 自适应画幅或上游型号无法确定,使用预估像素尺寸时为 true
reservationMarginPercent:
type: integer
format: int64
minimum: 0
description: 平台预留余量百分比,不属于火山官方计费公式
ModelQuoteEnvelope:
allOf:
- $ref: "#/components/schemas/Envelope"
- type: object
required: [data]
properties:
code:
type: integer
enum: [0]
data:
type: object
required: [quote]
properties:
quote:
$ref: "#/components/schemas/LogicalModelQuote"
AgentProfileRequest:
type: object
additionalProperties: false
required: [scope, content, revision]
properties:
scope:
type: string
enum: [user, project, canvas]
projectId:
type: string
canvasId:
type: string
content:
type: string
description: 常驻偏好文档,最多 12000 个 Unicode 字符;不能授权节点、工具、预算或绕过审批
revision:
type: integer
minimum: 0
description: 待更新层的数字 revision;首次创建为 0
CloudAgentRequest:
type: object
additionalProperties: false
required: [canvasId, prompt, permissionMode, contextScope, budget, idempotencyKey]
properties:
canvasId:
type: string
maxLength: 80
prompt:
type: string
description: 非空,最多 16000 字节
logicalModelId:
type: string
model:
type: string
channelId:
type: string
channelModelKey:
type: string
permissionMode:
type: string
enum: [read_only, request_approval, auto]
reasoningMode:
type: string
enum: [off, auto, deep]
description: 本轮推理策略;供应商是否支持由后端校验
profileRevision:
type: string
description: GET /agent/profile 的生效合并 revision;变化时拒绝创建新轮次
skillIds:
type: array
maxItems: 8
items:
type: string
contextScope:
type: array
maxItems: 1
items:
type: string
enum: [canvas]
budget:
type: object
additionalProperties: false
required: [maxCredits]
properties:
maxCredits:
type: number
minimum: 0
exclusiveMinimum: true
maximum: 1000000
maxGenerationTasks:
type: integer
minimum: 0
maximum: 8
maxVideoSeconds:
type: integer
minimum: 0
maximum: 120
idempotencyKey:
type: string
minLength: 8
maxLength: 128
Envelope:
type: object
required: [code, msg]
properties:
code:
type: integer
description: 0 成功;失败时默认等于 HTTP 状态,或 status*100+n 的细分码
data: {}
msg:
type: string
reason:
type: string
description: 仅失败时出现。稳定机器可读原因。
ErrorEnvelope:
allOf:
- $ref: "#/components/schemas/Envelope"
- type: object
properties:
code:
type: integer
enum: [400, 401, 403, 404, 409, 429, 500, 502, 503, 504, 40301, 40901, 42901]
data:
nullable: true
reason:
type: string
enum:
- invalid_argument
- unauthorized
- forbidden
- not_found
- conflict
- project_name_conflict
- failed_precondition
- quota_exceeded
- rate_limited
- unavailable
- timeout
- internal
- bad_gateway
- upstream_dns_failed
- model_capability_not_supported
- model_price_not_configured
- model_route_unavailable
- provider_request_failed
- model_catalog_mismatch
- invalid_model_selection
responses:
ModelQuote:
description: 当前参数对应的费用报价,位于信封 data.quote
content:
application/json:
schema:
$ref: "#/components/schemas/ModelQuoteEnvelope"
Envelope:
description: 业务成功信封
content:
application/json:
schema:
$ref: "#/components/schemas/Envelope"
Error:
description: 业务失败信封
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"