lili 938219d7a5 feat(studio): A11 切片三 M2 判意图入口 Java 侧(studio→aigc→worker)
两段式第一段的后端承接:用户原话进系统、判意图、返建议供前端确认(确认后才调 /modify 执行)。

契约先行:
- studio.yaml 新增 POST /app-api/studio/modify/plan + StudioModifyPlanReqVO/RespVO

studio(应用面):
- AppStudioController.planModify;StudioServiceImpl.planModify =
  validateCreator 白名单门(与既有 createDraft/generate/modify 一致)+ 归属校验防越权
  + 委托 aigc classifyModify + 异常/空兜底 unclear

aigc(worker 对接):
- AigcApi.classifyModify + AigcModifyProposalDTO
- WorkerClassifyClient:据 baseVersionId 反查 base 源(同 injectBaseSourceProject seam)
  → NO_PROXY JDK HttpClient POST worker /classify → best-effort 兜底 unclear+needsConfirm
- AigcApiImpl 软注入 ObjectProvider<WorkerClassifyClient>(executor 关闭时缺席→兜底,
  绝不因 Bean 缺席启动失败,镜像 WorkerDispatchClient);worker URL 尾段 /generate→/classify

测试:StudioServiceImpl 31/31 + WorkerClassifyClient 10/10 + AigcApiImpl 2/2,
本地 maven 独立复跑 43/43 绿、BUILD SUCCESS,既有 modify/generate/SAA 回归零破坏。
真连 worker 的判意图 e2e 待 M5(mini-desktop)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 01:22:24 -07:00

523 lines
34 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
# 契约 #1 API | 模块studiogame-module-studioWave3 创作主链路最小版)| ownerstudio 路
# 职责(架构 Doc B §71-76有状态创作工作台后端。编排「建草稿(委托 project createProject)→一句话生成(委托 aigc)
# →进度轮询→重生成→模板应用」。不跑 LLM委托 aigc、不持久化项目版本交 project、不做锁风裁决调 compliance
# 与 game-studio 前端仓区分:本契约是后端 studio 模块(错误码段 112game-studio 是产品端前端仓名,二者不同。
# 端:/app-api产品端 game-studio用户 Token前缀由 huijing 框架按 controller.app 包名自动添加。
# 错误码段studio = 1-112-***-***R4 治理新登记,本模块独占,禁与他模块重叠:
# 100 project/101 aigc/102 runtime/103 feed/104 telemetry/105 pay/106 trade/107 community/108 ip/109 compliance/110 biz/111 ad/112 studio
# 响应统一 Huijing CommonResult 信封:{ code, data, msg }code=0 成功。
# 编排链路MVP 轮询非 MQD4
# /template/list (透传 aigc 模板注册表) → /draft (调 project ProjectApi.createProject 拿 gameId upsert 会话)
# → /generate (调 aigc AigcApi.submitGenerate 落任务链回填 aigc_task_id) → /task/{id} (透传 aigc 进度轮询)
# → /task/{id}/regenerate (调 aigc AigcApi.retryTask 新建 retry_of 任务链)
# x-feign-contractsstudio 是调用方,依赖以下对方 -api seam本契约不对外暴露 Feign
# - project-api ProjectApi.createProject(creatorUserId, title, templateId) → gameId写类 RPC显式 creatorUserId归属校验在 project service
# - aigc-api AigcApi.submitGenerate / getTask / retryTask / getTemplateListWave3 新增 seam纯暴露层委托 AigcTaskService
# attachmentsR7StudioGenerateReqVO.attachments 本波仅持久化studio 侧落库),不透传 aigcaigc reqDTO 无 attachments 字段P1 再透传。
# 狠切留 seam 不实现P1rig/对白树/可视化批量资产图仅槽位表game_studio_asset+ 单步调度,不六路并发。
# ---------------------------------------------------------------------------
# 生命周期编排扩展(契约 C3 | 2026-06-17 固定架构+SAA studio execution §5.6/§12-⑥):
# 范式:游戏 = 长生命周期源项目LLM as 工作室)。新增 create/modify/extend 三生命周期操作additive不破现 draft/generate/regenerate 两步路)。
# - POST /create = draft+generate 一步式封装templateId 缺省 generic一句话直生免选模板对齐 generic 桥接 7534bdf9
# - POST /modify = 改源不改打包产物:在 baseVersion 源项目上改一处(换美术/调参/改关卡=确定性免 LLM改玩法=LLM 重生成单 behavior→ 重构建出新预览版;
# 不动 currentVersion、不自动入 feed仍走发布审核B1 链);失败=不建新版、base 不动。
# - POST /extend = additive 内容扩展(加关卡/机制/内容,不重写既有部件)→ 新预览版。
# 三者均委托 aigcjob 模型 mode/baseVersionId/modifyPatch/idempotency→ SAA 固定架构图产源项目 → 唯一确定性构建 → handleCallback 唯一写入路径落包;
# 产物均经 taskChain 轮询(复用 /task/{id}),完成后 versionId=新(预览)版。
# 关联冻结契约contracts/agent-loop/source-project.schema.json源项目工件、modifyPatchexecution §5.6)、六类 assetContext取代旧 attachmentsadditive
# x-feign-contracts新增 seamstudio 为调用方,本契约不对外暴露 Feign
# - aigc-api AigcApi.submitGenerate 扩 mode/baseVersionId/modifyPatch/idempotencyKey生命周期编排参数additive后端线落地
# - project-api ProjectApi 取 baseVersion 源项目引用 + 新预览版落库version 产物权威仍在 project源项目独立 game_source_project 表存 V18
# idempotency 语义create/modify/extend 共用):同 userId+operation+idempotencyKey 命中则返回既有 taskChain不重复触发生成缺省=不去重;建议 TTL 24h。
info:
title: 绘境AI studio 模块 API
version: 1.0.0
description: >-
创作主链路最小版("做得出"工作台)。创作者进工作坊建草稿(移交 project 建游戏拿 gameId→ 一句话生成(委托 aigc
轮询进度直至终态(透传 aigc→ 失败可重生成(委托 aigc retryTask。MVP 轮询非 MQ前端据此 vite-plugin-mock 自动生成 mock。
servers:
- url: http://localhost:48080
description: 本地Swagger/Knife4j http://localhost:48080/doc.html
paths:
# ===========================================================================
# 产品端 /app-api创作工作台用户 Token
# ===========================================================================
/app-api/studio/template/list:
get:
tags: [app-studio]
summary: 玩法模板列表(模板浏览/应用 P-TPL-01/03透传 aigc 模板注册表)
description: 透传 aigc 模板注册表T-AGC-03MVP 骨架返回空列表占位,待模板注册表接入。
responses:
'200':
description: 成功(玩法模板列表)
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioTemplateList' }
/app-api/studio/draft:
post:
tags: [app-studio]
summary: 建草稿(进工作坊 P-CRT-10 + 草稿移交 project P-TPL-03
description: >-
编排:服务端调 project ProjectApi.createProject(creatorUserId=当前登录用户, title, templateId) 建游戏拿 gameId
回写会话,再落会话(status=0 草稿)。attachments 仅持久化R7。createProject 是硬前置,返回空 gameId 视为移交失败。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioDraftCreateReqVO' }
responses:
'200':
description: 成功(新建会话,含回写的 gameId
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioSession' }
/app-api/studio/generate:
post:
tags: [app-studio]
summary: 一句话生成P-CRT-01委托 aigc 提交生成)
description: >-
编排:校验 session 归属 → 落任务链(status=1 生成中) → 委托 aigc AigcApi.submitGenerate(带 prompt/templateId/gameId/userId)
→ 回填 aigc_task_id → 立即返回任务链句柄,前端据 taskChainId 轮询。同步直写无 MQD4
attachments 仅持久化R7不入 aigc reqDTO。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioGenerateReqVO' }
responses:
'200':
description: 成功(任务链句柄,含 aigc_task_id
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' }
/app-api/studio/task/{id}:
get:
tags: [app-studio]
summary: 进度轮询P-CRT-12透传 aigc 进度/状态)
description: >-
编排:校验任务链归属 → 委托 aigc AigcApi.getTask 取进度/状态 → 映射链态
aigc succeeded → 链完成回填 version_id + 会话完成failed/timed_out → 链失败 + 会话失败;其余保持生成中仅回写 progress
parameters:
- { name: id, in: path, required: true, schema: { type: integer, format: int64 }, description: '创作任务链 IDtaskChainId' }
responses:
'200':
description: 成功(任务链最新态,完成后 versionId 非空)
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' }
/app-api/studio/task/{id}/regenerate:
post:
tags: [app-studio]
summary: 重生成迭代P-CRT-09委托 aigc retryTask
description: 编排:校验原任务链归属 → 委托 aigc AigcApi.retryTask 重提生成 → 新建一条任务链(retry_of=原 id)回填新 aigc_task_id。
parameters:
- { name: id, in: path, required: true, schema: { type: integer, format: int64 }, description: '原创作任务链 ID' }
responses:
'200':
description: 成功(新建的重试任务链句柄)
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' }
# ---------------------------------------------------------------------------
# 生命周期操作(契约 C3execution §5.6/§12-⑥additive不破现两步路
# ---------------------------------------------------------------------------
/app-api/studio/create:
post:
tags: [app-studio]
summary: 一步式创作C3draft+generate 封装P-CRT-01/10
description: >-
编排:建草稿(委托 project createProjecttemplateId 缺省 generic→ 立即委托 aigc submitGenerate → 落任务链(status=1)
→ 返回任务链句柄供前端轮询(复用 /task/{id})。一步式封装,不破现 draft+generate 两步路additive
六类 assetContext 透传生成上下文(取代旧 attachments
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioCreateReqVO' }
responses:
'200':
description: 成功(任务链句柄,含 aigc_task_id
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' }
/app-api/studio/modify:
post:
tags: [app-studio]
summary: 修改C3改源不改产物P-CRT-09 进阶)
description: >-
编排:取 baseVersion 源项目 → 应用 modifyPatchmode=deterministic 确定性编辑免 LLM / regenerate-module LLM 只重生成单 behavior
→ 唯一确定性构建出新预览版 → 落任务链供轮询。产物=新预览版(不动 currentVersion、不自动入 feed仍走发布审核
失败=不建新版、base 不动。modifyPatch 字段见 execution §5.6。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioModifyReqVO' }
responses:
'200':
description: 成功(新预览版任务链句柄,完成后 versionId=新预览版、baseVersionId=被改版本)
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' }
/app-api/studio/modify/plan:
post:
tags: [app-studio]
summary: 判意图A11 切片三 M2两段式调整回路第一段
description: >-
用户试玩后用自然语言提改("主角太暗""加快下落""做成赛车游戏")→ 本端点判意图:把原话 + base 源工程
喂便宜档 LLMworker /classify返回结构化建议改动 + 风险,供前端确认/编辑后再调已结构化的 /modify 执行(第二段)。
【判意图不执行、不建版本、不计费】——只判类别/落点/风险,不动 sourceProject、不落任务链。
编排:白名单可信边界 → base 版本归属校验(防越权判别人的游戏)→ 委托 aigc classifyModify据 baseVersionId 反查 base 源 →
同步 POST worker /classify→ 映射建议改动返回。
【best-effort 非阻断】base 源反查空 / worker 不可达 / 超时 / 非 200 → 返兜底 {category:unclear, needsConfirm:true},绝不 500、绝不静默判成可执行改动。
【确认门】needsConfirm=true危险/大改/改玩法/意图不明/判意图不可用)时,前端必须让用户确认或编辑后才可调 /modify
只有「低风险 + 确定性改asset/config/level」才 needsConfirm=false。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioModifyPlanReqVO' }
responses:
'200':
description: 成功(建议改动 + 风险 + 是否需确认;判意图不可用时返兜底 unclear
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioModifyPlan' }
/app-api/studio/extend:
post:
tags: [app-studio]
summary: 扩展C3additive 内容扩展)
description: >-
编排:在 baseVersion 源项目上做 additive 内容扩展(加关卡/机制/内容)→ 重构建出新预览版 → 落任务链供轮询。
语义=additive不重写既有部件产物处置同 modify新预览版、不动 currentVersion、走发布审核
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioExtendReqVO' }
responses:
'200':
description: 成功(新预览版任务链句柄)
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioTaskChain' }
# ===========================================================================
# 素材库 R-MATU6 | 六类素材 浏览/选用/登记additive
# 上传归属裁定plan-002字节落共享文件服务huijing-module-infra 的 POST /infra/file/uploadAppFileController
# studio 不拥有/不代理字节上传端点——前端先调 /infra/file/upload 拿 ref/url/size/mime再调本模块「按引用登记」端点。
# studio 仍拥有领域端点:浏览/选用/登记 + game_material 实体 + assetContext。
# 六类冻结sprite/character/effect/scene/ui/music与 StudioAssetContextItem + source-project.schema.json 同引同枚举)。
# 鉴权:均需用户 Token不可 @PermitAll归属隔离在 Service 强制(创作者只见/只用自己的素材,前端不是边界)。
# 登记自检:六类校验 + 声明 mimeType 与类目族 best-effort 一致性image/* 给图类、audio/* 给 music非法类目/MIME 错配前置拒1-112-005-***)。
# 深度字节内容/magic-byte 校验已上移共享 infra 上传 + 合规「资产入库·文件安全」门P2——裁定后 studio 不持字节。
# ===========================================================================
/app-api/studio/asset:
post:
tags: [app-studio]
summary: 按引用登记素材R-MAT字节先经 /infra/file/upload 拿 ref
description: >-
字节先经共享 huijing-module-infra 的 POST /infra/file/upload前端直调拿 ref/url/size/mime本端点据此登记一条素材行供浏览/选用)。
编排:六类校验 → 声明 mimeType 与类目族 best-effort 一致性自检 → 落 game_material(归属本人) → 返回输入态六类引用项(直接喂 assetContext.ref
provider 落缺省 mmx-cli。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioMaterialRegisterReqVO' }
responses:
'200':
description: 成功(素材引用项,喂 assetContext
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioAssetContextItem' }
/app-api/studio/asset/browse:
get:
tags: [app-studio]
summary: 浏览素材R-MATowner-isolated 分页)
description: 创作者只见自己的素材(服务端按当前登录用户强制过滤);可选按 category 过滤六类。按 id 倒序(新上传在前)。
parameters:
- { name: pageNo, in: query, required: true, schema: { type: integer, default: 1 }, description: '页码,从 1 开始' }
- { name: pageSize, in: query, required: true, schema: { type: integer, default: 10 }, description: '每页条数,最大 200' }
- { name: category, in: query, required: false, schema: { type: string, enum: [sprite, character, effect, scene, ui, music] }, description: '按类目过滤(可空=全部六类)' }
responses:
'200':
description: 成功(本人素材分页)
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioMaterialPage' }
/app-api/studio/asset/select:
post:
tags: [app-studio]
summary: 选用素材入草稿R-MATselect-into-draft
description: >-
把选中素材(按 materialIds本人素材库写入目标草稿会话的 assetContext取代旧 attachments。归属校验本人会话 + 本人素材;
与既有 assetContext 按 ref 去重合并。C3 create/modify/extend 已直接接受 assetContext 输入,本端点是「选好→落草稿」的便利产出。
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/StudioMaterialSelectReqVO' }
responses:
'200':
description: 成功(写入后草稿的完整 assetContext
content:
application/json:
schema: { $ref: '#/components/schemas/CommonResultStudioAssetContextItemList' }
components:
schemas:
# ========== 请求 VO ==========
StudioDraftCreateReqVO:
type: object
required: [title, templateId]
properties:
title: { type: string, maxLength: 128, description: '作品标题(透传 project createProject', example: '我的放置小镇' }
templateId: { type: string, description: '玩法模板 ID透传 project/aigc', example: 'idle' }
prompt: { type: string, maxLength: 1000, description: '一句话 Prompt建草稿可空generate 必填)', example: '做一个躲避陨石的小游戏' }
attachments: { type: string, description: '附件上下文 JSONP-CRT-04本波仅持久化P1 透传 aigc' }
StudioGenerateReqVO:
type: object
required: [sessionId, prompt]
properties:
sessionId: { type: integer, format: int64, description: '创作会话 ID建草稿返回的 sessionId', example: 1024 }
prompt: { type: string, maxLength: 1000, description: '一句话 Prompt透传 aigc submitGenerate', example: '做一个躲避陨石的小游戏' }
attachments: { type: string, description: '附件上下文 JSONP-CRT-04【本波仅持久化P1 透传 aigc】——studio 侧落库持久化,本波不透传 aigc' }
# ---- 生命周期操作请求 VO契约 C3execution §5.6----
StudioCreateReqVO:
type: object
required: [title, prompt]
description: 一步式创作draft+generate 封装templateId 缺省 genericassetContext 取代旧 attachments
properties:
title: { type: string, maxLength: 128, description: '作品标题(透传 project createProject', example: '我的放置小镇' }
prompt: { type: string, maxLength: 1000, description: '一句话 Prompt一步式必填透传 aigc', example: '做一个躲避陨石的小游戏' }
templateId: { type: string, description: '玩法模板/品类引导 ID缺省 generic一句话直生免选模板对齐 7534bdf9', example: 'generic' }
assetContext: { type: array, items: { $ref: '#/components/schemas/StudioAssetContextItem' }, description: '六类素材引用(取代旧 attachmentsadditive空=纯一句话生成' }
idempotencyKey: { type: string, maxLength: 64, description: '幂等键C3防重复提交触发重复生成可空' }
StudioModifyReqVO:
type: object
required: [baseVersionId, mode, target, payload]
description: >-
改源不改产物execution §5.6 modifyPatch产新预览版不动 currentVersion走发布审核。
【mode×target.kind 锁定映射——后端可信边界校验,违则 1-112-*** 拒schema 不用 oneOf 编码以保 mock/codegen 简单)】:
mode=deterministic ⇔ target.kind∈{asset,config,level} ∧ payload.value 必填(确定性覆写免 LLM
mode=regenerate-module ⇔ target.kind=behavior ∧ payload.intent 必填LLM 只重生成那一个 behavior
properties:
baseVersionId: { type: integer, format: int64, description: '被改的 base 产物版本 IDproject.game_version.id', example: 4096 }
mode: { type: string, enum: [deterministic, regenerate-module], description: 'deterministic=确定性编辑源文件免 LLMregenerate-module=LLM 只重生成单 behavior 模块', example: 'deterministic' }
target: { $ref: '#/components/schemas/StudioModifyTarget' }
payload: { $ref: '#/components/schemas/StudioModifyPayload' }
idempotencyKey: { type: string, maxLength: 64, description: '幂等键C3可空' }
StudioModifyTarget:
type: object
required: [kind]
anyOf:
- { required: [path] }
- { required: [id] }
description: 寻址源项目部件path 与 id 至少其一JSON 指针或部件 id
properties:
kind: { type: string, enum: [asset, config, level, behavior], description: '换美术=asset / 调参=config / 改关卡=level(scene) / 改玩法=behavior' }
path: { type: string, description: '源项目内 JSON 指针(如 /config/speed、/assets/0、/files/src/game.js', example: '/config/speed' }
id: { type: string, description: '或按部件 id 寻址behaviors[].id / assets[].id' }
StudioModifyPayload:
type: object
description: mode=deterministic 用 value直接覆写免 LLM必填mode=regenerate-module 用 intent喂 LLM 重生成意图,必填);后端按 mode 校验(见 StudioModifyReqVO 锁定映射)
properties:
value: { type: object, additionalProperties: true, description: 'deterministic 新值(确定性覆写)' }
intent: { type: string, maxLength: 1000, description: 'regenerate-module 改玩法逻辑的自然语言意图(只重生成那一个 behavior', example: '把陨石下落改成会左右摇摆' }
# ---- 判意图请求 VOA11 M2两段式第一段----
StudioModifyPlanReqVO:
type: object
required: [baseVersionId, instruction]
description: 判意图入参(用户试玩后的自然语言改话 + 被改 base 版本);判意图不执行、不建版本、不计费。
properties:
baseVersionId: { type: integer, format: int64, description: '被改的 base 产物版本 IDproject.game_version.id判意图据此反查 base 源工程)', example: 4096 }
instruction: { type: string, maxLength: 1000, description: '用户原话(自然语言改话)', example: '把主角颜色调亮一点' }
StudioModifyPlanRespVO:
type: object
description: >-
判意图建议改动(对齐 worker /classify 响应)。前端据此预填一次 /modifycategory/mode/target/payload 直接喂第二段;
needsConfirm=true 时必须先让用户确认/编辑。判意图不可用时返兜底 {category:unclear, mode:null, needsConfirm:true}。
properties:
category: { type: string, enum: [asset, config, level, behavior, big-change, unclear], description: '换美术=asset / 调数值=config / 改关卡=level / 改玩法=behavior / 换品类大改=big-change / 意图不明=unclear' }
mode: { type: string, nullable: true, enum: [deterministic, regenerate-module], description: 'asset/config/level→deterministic免 LLM 确定性改behavior→regenerate-module重生成单模块big-change/unclear→null不可直接执行须澄清/确认)' }
target: { $ref: '#/components/schemas/StudioModifyPlanTarget' }
payload: { type: object, additionalProperties: true, nullable: true, description: '确定性改用 {value:{…}}behavior 改用 {intent:"…"}big-change/unclear 为 null' }
riskLevel: { type: string, enum: [low, medium, high], description: '风险等级big-change 强制 high' }
needsConfirm: { type: boolean, description: '是否必须用户确认后才可调 /modify只有「低风险 + 确定性改」为 false其余危险/大改/改玩法/意图不明/判意图不可用)一律 true' }
rationale: { type: string, description: '判断依据(中文,一句话)' }
clarify: { type: string, nullable: true, description: 'unclear/big-change 时回问用户的话;否则 null' }
StudioModifyPlanTarget:
type: object
nullable: true
description: 建议的寻址落点big-change/unclear 为 null前端预填 /modify 的 target。
properties:
kind: { type: string, enum: [asset, config, level, behavior], description: '落点类目' }
path: { type: string, description: '落点路径assets.js 键名 / core.js 常量名 / 文件路径)', example: '/files/src/core.js#ROUND_MS' }
StudioExtendReqVO:
type: object
required: [baseVersionId, intent]
description: additive 内容扩展(加关卡/机制/内容),不重写既有部件
properties:
baseVersionId: { type: integer, format: int64, description: '在哪个产物版本上扩展', example: 4096 }
intent: { type: string, maxLength: 1000, description: '扩展意图(加关卡/机制/内容)', example: '再加一个 boss 关卡' }
assetContext: { type: array, items: { $ref: '#/components/schemas/StudioAssetContextItem' }, description: '扩展用的新增六类素材引用(可空)' }
idempotencyKey: { type: string, maxLength: 64, description: '幂等键C3可空' }
StudioAssetContextItem:
type: object
required: [category, ref]
description: 六类素材引用(输入态,对齐 source-project.schema.json assetSpec.category取代旧 attachments。后端 asset 节点据此派生 sourceProject.assets[].id项目内 id、provider 默认 mmx-cli§5.5)。
properties:
category: { type: string, enum: [sprite, character, effect, scene, ui, music], description: '六类:图元/角色/特效/场景/界面/音乐' }
ref: { type: string, description: '平台 assetId/ref', example: 'asset_88231' }
url: { type: string, format: uri, description: '只读镜像 URL可空' }
provider: { type: string, description: '素材来源 provider可空默认 mmx-cli切 provider 不动消费侧§5.5', example: 'mmx-cli' }
# ---- 素材库按引用登记 请求 VOR-MATU6上传归属裁定 plan-002----
StudioMaterialRegisterReqVO:
type: object
required: [category, ref]
description: >-
按引用登记素材(字节先经 /infra/file/upload 拿 ref。studio 不持字节:前端从 infra 上传响应透传 ref/url/size/mime 来此登记。
后端校验 category∈六类 + 声明 mimeType 与类目族 best-effort 一致image/* 给图类、audio/* 给 music。provider 落缺省 mmx-cli。
properties:
category: { type: string, enum: [sprite, character, effect, scene, ui, music], description: '六类素材类目' }
ref: { type: string, description: '平台素材引用 ref来自 /infra/file/upload 返回的访问路径/资源标识)', example: '/infra/file/abc/陨石.png' }
url: { type: string, format: uri, description: '只读镜像 URL可空来自上传响应' }
name: { type: string, description: '素材名称(可空,展示用;缺省取类目名)', example: '陨石.png' }
sizeBytes: { type: integer, format: int64, description: '文件大小(字节,可空;前端从上传响应透传,供配额/审计)', example: 20480 }
mimeType: { type: string, description: '文件 MIME 类型可空前端从上传响应透传best-effort 校验与类目族一致)', example: 'image/png' }
# ---- 素材库选用入草稿 请求 VOR-MATU6----
StudioMaterialSelectReqVO:
type: object
required: [sessionId, materialIds]
description: 选用素材入草稿(把本人素材库选中项写入草稿会话 assetContext取代旧 attachments
properties:
sessionId: { type: integer, format: int64, description: '目标草稿会话 ID写其 assetContext', example: 512 }
materialIds: { type: array, items: { type: integer, format: int64 }, description: '选用的素材 ID 列表(本人素材库)', example: [88231, 88232] }
# ========== 响应 VO ==========
# ---- 素材库浏览项 响应 VOR-MATU6比输入态 StudioAssetContextItem 多 id + 展示元数据)----
StudioMaterialRespVO:
type: object
description: 素材浏览项(含 id 供选用 + 六类引用四元组 + 名称/大小/MIME/上传时间)
properties:
id: { type: integer, format: int64, description: '素材 ID选用入参 materialIds', example: 88231 }
category: { type: string, enum: [sprite, character, effect, scene, ui, music], description: '六类素材类目' }
ref: { type: string, description: '平台素材引用 ref喂 assetContext.ref', example: 'asset_88231' }
url: { type: string, format: uri, description: '素材访问 URL只读镜像可空' }
provider: { type: string, description: '素材来源 provider缺省 mmx-cli', example: 'mmx-cli' }
name: { type: string, description: '素材名称(展示用)', example: '陨石.png' }
sizeBytes: { type: integer, format: int64, description: '文件大小(字节)', example: 20480 }
mimeType: { type: string, description: '文件 MIME 类型', example: 'image/png' }
createTime: { type: string, format: date-time, description: '上传时间' }
StudioTemplateRespVO:
type: object
description: 玩法模板(透传 aigc 模板注册表,对齐 aigc.yaml TemplateRespVO
properties:
templateId: { type: string, description: '模板 ID', example: 'dodge' }
name: { type: string, description: '模板名称', example: '躲避' }
description: { type: string, description: '模板说明' }
coverUrl: { type: string, description: '模板封面/示意图 URL' }
examplePrompt: { type: string, description: '示例 PromptP-CRT-11', example: '做一个躲避陨石的小游戏' }
StudioSessionRespVO:
type: object
properties:
id: { type: integer, format: int64, description: '创作会话 IDsessionId', example: 1024 }
gameId: { type: integer, format: int64, description: '移交后的游戏 IDproject.game_project.id', example: 2048 }
templateId: { type: string, description: '玩法模板 ID', example: 'idle' }
title: { type: string, description: '作品标题', example: '我的放置小镇' }
prompt: { type: string, description: '一句话 Prompt' }
status: { type: integer, description: '会话状态0草稿 1生成中 2完成 3失败', example: 0 }
StudioTaskChainRespVO:
type: object
properties:
id: { type: integer, format: int64, description: '创作任务链 IDtaskChainId轮询用', example: 1024 }
sessionId: { type: integer, format: int64, description: '所属创作会话 ID', example: 512 }
aigcTaskId: { type: integer, format: int64, description: '委托的 aigc 生成任务 ID', example: 8888 }
gameId: { type: integer, format: int64, description: '关联游戏 IDproject.game_project.id', example: 2048 }
versionId: { type: integer, format: int64, description: '产物版本 IDproject.game_version.id完成后非空', example: 4096 }
status: { type: integer, description: '任务链状态0初始 1生成中 2完成 3失败', example: 1 }
progress: { type: integer, description: '进度百分比 0-100透传 aigc', example: 60 }
retryOf: { type: integer, format: int64, description: '若为重生成,指向原任务链 IDP-CRT-09 血缘)', example: 1000 }
baseVersionId: { type: integer, format: int64, description: 'modify/extend 血缘:本预览版派生自的 base 版本create/generate 为空additive', example: 4096 }
# ========== CommonResult 信封 ==========
CommonResultStudioTemplateList:
type: object
properties:
code: { type: integer, example: 0 }
data: { type: array, items: { $ref: '#/components/schemas/StudioTemplateRespVO' } }
msg: { type: string }
CommonResultStudioSession:
type: object
properties:
code: { type: integer, example: 0 }
data: { $ref: '#/components/schemas/StudioSessionRespVO' }
msg: { type: string }
CommonResultStudioTaskChain:
type: object
properties:
code: { type: integer, example: 0 }
data: { $ref: '#/components/schemas/StudioTaskChainRespVO' }
msg: { type: string }
CommonResultStudioModifyPlan:
type: object
description: 判意图返回A11 M2 建议改动 + 风险)
properties:
code: { type: integer, example: 0 }
data: { $ref: '#/components/schemas/StudioModifyPlanRespVO' }
msg: { type: string }
# ---- 素材库 R-MAT 信封U6----
CommonResultStudioAssetContextItem:
type: object
description: 上传素材返回(单条六类引用项,喂 assetContext
properties:
code: { type: integer, example: 0 }
data: { $ref: '#/components/schemas/StudioAssetContextItem' }
msg: { type: string }
CommonResultStudioAssetContextItemList:
type: object
description: 选用入草稿返回(写入后草稿的完整 assetContext 列表)
properties:
code: { type: integer, example: 0 }
data: { type: array, items: { $ref: '#/components/schemas/StudioAssetContextItem' } }
msg: { type: string }
CommonResultStudioMaterialPage:
type: object
description: 素材浏览分页返回owner-isolated
properties:
code: { type: integer, example: 0 }
data:
type: object
properties:
list: { type: array, items: { $ref: '#/components/schemas/StudioMaterialRespVO' } }
total: { type: integer, format: int64, example: 42 }
msg: { type: string }