Files
kdletters fc14190f58
Project CI / AI game creator shell Rust shard 1/4 (push) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (push) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (push) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (push) Has been cancelled
Project CI / AI game creator shell Rust smoke (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
图集切片模式改为必须显式声明并补齐决策要求 (#408)
## 背景

切图新增基于连通域的切分后,LLM 仍倾向显式传 `sliceMode=grid`:参数只存在于部分 LLM 可见面、带默认值、没有任何决策规则,生成结果也不回显生效模式。

## 变更

- 平台:`/api/editor/icon-spritesheets/generations` 与 `/api/external/v1/editor/icon-spritesheets/generations` 把 `sliceMode` 改为必填并移除默认值;缺失、空白或未知取值在引用解析、定价与任何 provider / OSS 副作用之前返回 `400`,错误统一带 `field` 与决策要求。
- 契约:`grid` 必须同时提供 `gridX`/`gridY`,`connected-components` 不接受网格尺寸;`sliceCount` 只约束连通域切分,请求与响应的公开上限统一为 `256`;OpenAPI 去掉默认值并补必填与失败语义。
- AGC:MCP 工具说明去掉默认值并补决策要求,桥接层新增可测试的切分声明校验;原生工具 `canvas.asset_generate` 暴露 `sliceMode/gridX/gridY/sliceCount` 并要求图集显式声明;生成结果回显 `sliceMode/gridX/gridY` 与 `slicePaths`;严格图集在本地提交前校验平台回显与请求声明一致。
- 标准美术包:显式声明 `connected-components` 加 `sliceCount=4`,并在四张 canonical 切片用途映射前校验数量,禁止截断或错位。
- 前端与画板:画板 Agent 工具装配与画板提交计划显式声明连通域切分;前端类型要求显式 `sliceMode` 并在本地校验声明自洽。
- 文档与 Skill:主规范、OpenAPI、AGC Skill、外部编辑器 Skill、里程碑与实施计划、共享决策记录同步更新。
- 测试环境:测试构建对提权 Windows 主机上系统临时目录的所有者偏差做一次性所有者初始化重试,临时目录之外的越权所有者继续失败关闭。

## 兼容性影响

省略 `sliceMode` 的旧调用方(含已发布但未更新的 AGC 客户端与第三方外部 API 调用方)会在图集生成上收到 `400`;这是本次"不允许默认值"的预期结果,仓库内自有调用方已全部改为显式声明。

## 验证

- 平台:`slice_mode_must_be_declared_*` 与 OpenAPI 契约测试通过;全量 `cargo test -p api-server` 1043 通过 / 11 失败(`wallet_refund_outbox` 临时文件 `拒绝访问`,已在改动前基线复现,属本机环境)。
- AGC:`slice` 30、`spritesheet` 21、`direct_tools_mcp` 23、`agent_native_tools` 16、`canvas_generation_tests` 83、提示词上限与桥接门禁各 1 条、`cargo check --tests` 全部通过。
- 前端:182 条定向测试与 `typecheck` 通过。
- 门禁:`cargo fmt --check`(两个 workspace)、`check:encoding`、`check:doc-index`、`git diff --check` 通过。
- 未验证:真实 Provider 与浏览器试玩、确定性 e2e 车道;整机全量 AGC 单进程运行在本机受提权 shell 的所有者与时序问题影响,不作为门禁信号。

---------

Co-authored-by: kdletters <61648117+kdletters@users.noreply.github.com>
Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/408
2026-09-17 18:10:34 +08:00

8.9 KiB
Raw Permalink Blame History

Capability Routing

Use this reference to translate user intent into a hosted MCP tool or its corresponding External v1 REST operation. Use genarrative://external-editor/openapi or GET /api/external/v1/openapi.json for exact schemas.

Integration Surface

  • Fixed production base URL: https://www.genarrative.world/.
  • Discovery manifest: GET /api/external/v1/agent-integration.json.
  • Hosted MCP: /api/external/v1/mcp, Streamable HTTP, authenticated with the same Bearer API Key as REST.
  • Public contract: GET /api/external/v1/openapi.json.
  • Skill fallback: GET /api/external/v1/skill/SKILL.md or GET /api/external/v1/skill.zip.

Prefer MCP when the Agent supports a remote endpoint plus a custom Bearer token. Prefer the complete Skill and Python helper when MCP is unavailable or a client-side local-file upload must be orchestrated. The MCP tool names are derived from OpenAPI operationId values in snake case; select by capability instead of memorizing the name.

Canvas Session

Before the first generation in a new conversation, obtain a canvas name unless the user already supplied an existing projectId and assetFolderId.

  1. List or create a project. When creating one, use the canvas name as title.
  2. Read the asset library. Reuse a folder with the same label or create one with the canvas name.
  3. Retain canvasName, projectId, assetFolderId, and the current art spec in conversation state.

Generated artifacts must enter both the current canvas and its same-name library folder whenever the endpoint supports that invariant. Pass projectId, assetFolderId, the endpoint's label field, and canvasCompletion. Character animation returns the final formal resource and asset directly; use those records and never create a duplicate from the first frame.

Art Spec Routing

Before art generation, normalize the user's request into:

{
  "assetType": "character | background | prop | ui | icon | animation | video | audio",
  "subject": "要生成的主体",
  "style": "画风、材质、时代或参考风格",
  "palette": "主色与禁用色",
  "composition": "构图、镜头、姿态或布局",
  "format": "比例、尺寸、分辨率、帧数或时长",
  "constraints": "必须保留、禁止出现、透明或绿幕要求",
  "references": ["objectKey、资源 ID 或本地文件说明"]
}

Infer what is already clear and ask only for missing fields that block the selected endpoint. Reuse the current spec unless the user changes style, subject family, palette, format, or constraints. Store structured context under generationInputs.artSpec where supported and summarize it in the prompt when useful.

Intent Map

User intent MCP/REST capability
Generate a background, character, spec, UI mockup, or publication image Image generation
Redraw, retouch, or replace an existing image Image edit
Remove the background from an existing image Background removal
Generate from a local reference Upload and confirm the local file, then image generation or edit
Build a reusable transparent icon/game atlas from a visual spec Icon spritesheet generation
Extract marked assets from an existing UI design UI design asset extraction
Animate a character into frames Character animation generation
Generate video Video generation
Generate a sound effect Sound-effect generation
Generate background music/BGM Background-music generation
Upload a local image/audio/video asset Upload ticket -> OSS form upload -> object confirm
Save viewport/layers Canvas save
Create, load, rename, or delete a canvas Project operations
Organize folders and asset records Asset-library operations
Obtain temporary access to private media Signed read URL
Check generation progress or retrieve its result Generation query

Do not present an API menu unless the request is genuinely ambiguous. Ask a follow-up when two routes create different artifacts, for example “处理这张图” could mean edit, extract marked UI assets, or use it as a reference for a new generation.

Route-Specific Decisions

  • Use image edit when the requested output replaces or modifies a source image. With projectId, pass targetLayerId to replace an existing layer when no explicit canvasCompletion is supplied.
  • Use icon spritesheet generation for a transparent reusable atlas when a stable visual-spec reference and concrete iconDescriptions exist. Do not use ordinary image generation just because it can draw several objects.
  • Use UI extraction only for an existing UI design image with red-box annotations. It is not UI generation.
  • Use a project layer ID as character animation sourceLayerId when one exists. For a local-only source, derive a stable synthetic ID from the filename.
  • For video with image/video/audio references, use a Seedance 2.0-family model; default to seedance2.0-fast, mode: "std", and explicit sound.
  • Use signedUrl only for preview/download. Feed stable objectKey or registered resource/asset identifiers into generation.

AI Game Creator Canonical Visual DAG

Keep the existing autonomous-build task graph. Do not add a parallel task system or collapse these artifacts into one ordinary generation request:

  1. art-director generates assets/art-spec.png with image generation, kind: "spec", then registers it as assetKind: "icon-spec". This image is the authoritative visual spec; generationInputs.artSpec is supporting structured context.
  2. design-foundation generates assets/ui-prototype.png with kind: "ui-design", using the registered art-spec resource ID in referenceImageSrcs.
  3. art-asset-plan generates transparent assets/art-spritesheet.png through icon spritesheet generation, using the same registered art-spec resource ID as referenceId plus concrete iconDescriptions. sliceMode is required and has no default: send sliceMode: "grid" with gridX/gridY only when the requirement itself fixes the slots or names the column/row count, and otherwise send sliceMode: "connected-components" (with sliceCount when a subject count must be constrained); never invent a grid to express "kinds of assets", and never send gridX/gridY with connected-components.

For a playable Canvas game, do not stop at generation. Make code-prototype depend on art-asset-plan and consume the persisted iconImageSrcs slices for core players, blocks or targets, scene obstacles, and feedback. When the requirement fixes grid slots, require the response sliceMode to match the declared grid request and exactly gridX × gridY slices before registering the local runtime sheet; a connected-components request is instead judged by its own sliceCount or by the requirement, and both fewer and extra components fail closed. Treat art-spec.png as reference-only. A full-sheet <img>, CSS background, path-only mention, guessed equal-grid crop, or code-drawn replacement for core entities is not runtime asset use. If slicing produces sliceWarning, keep the complete transparent sheet as a valid editor artifact, but fail the playable game asset gate until real slice files or verified atlas coordinates exist; never invent coordinates or replace the icon-spritesheet route with ordinary image generation.

Never use assets/ui-prototype.png as the spritesheet visual-spec reference. UI extraction is outside this canonical DAG.

Scope Boundary

Stay within /api/external/v1. Do not invent worker, queue, runtime task-list, admin, profile, or SpacetimeDB calls. The only external generation query is GET /api/external/v1/generations/{operationId}.