Files
ttstd-infinite-canvas/backend/internal/handler/openapi.yaml
ddCat 6892732b06 feat(agent): Agent 工作台 - 计划插话记忆、统一模型选择器并修复摘要与视频入库
将计划清单、运行中插话和个人记忆接入云端 Agent;全站模型选择器统一为左右二级菜单。画布摘要按预算截断不再整轮拒绝,首页视频未知宽高可入库。README 补充贡献者 morrow。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 20:21:25 +08:00

811 lines
24 KiB
YAML
Raw 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: resources
- name: tasks
- name: assets
- name: agent
- name: admin
paths:
/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/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 轮次
responses:
"200":
description: 信封 data.run
"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/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/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/{id}/file:
get:
tags: [resources]
summary: 读取资源二进制(非 JSON 信封)
parameters:
- in: path
name: id
required: true
schema: { type: string }
responses:
"200":
description: 文件流
"401":
$ref: "#/components/responses/Error"
"404":
$ref: "#/components/responses/Error"
/tasks:
post:
tags: [tasks]
summary: 创建生成任务
responses:
"200":
$ref: "#/components/responses/Envelope"
"400":
$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"
components:
parameters:
AgentRunID:
name: id
in: path
required: true
schema:
type: string
securitySchemes:
sessionCookie:
type: apiKey
in: cookie
name: open_ai_canvas_session
schemas:
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
- failed_precondition
- quota_exceeded
- rate_limited
- unavailable
- timeout
- internal
- bad_gateway
- model_capability_not_supported
- model_price_not_configured
- model_route_unavailable
- provider_request_failed
- model_catalog_mismatch
- invalid_model_selection
responses:
Envelope:
description: 业务成功信封
content:
application/json:
schema:
$ref: "#/components/schemas/Envelope"
Error:
description: 业务失败信封
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"