Compare commits

..

13 Commits

Author SHA1 Message Date
lhk229 e180368c48 合并最新 master 到抠图功能分支
同步 origin/master 至 6f161a6b3
合并客户端 Skill、测试与决策记录的冲突,保留双方变更
2026-09-17 21:24:36 +08:00
lhk229 0c6b62dc8a 整理抠图测试导入并明确对外说明边界
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 6m25s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 5m28s
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
将主站与客户端抠图测试模块的导入统一放到模块顶部
明确 provider 选择与兜底策略仅保留在内部技术方案中
2026-09-17 00:47:23 +08:00
lhk229 124e552e3a Merge branch 'master' into feat/bgfilter-api
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 6m54s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 7m4s
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 7m22s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 7m52s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m44s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m53s
Project CI / Frontend tests (pull_request) Failing after 4m7s
Project CI / Repository checks (pull_request) Successful in 4m22s
Project CI / Native shell tests (pull_request) Successful in 8m13s
Project CI / Backend tests (pull_request) Successful in 9m10s
Project CI / AI game creator shell web tests (pull_request) Successful in 4m7s
2026-09-17 00:33:21 +08:00
lhk229 3ffd37236f 补齐抠图参数透传与验收
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 4m4s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 3m51s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 4m45s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 4m15s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m9s
Project CI / Backend tests (pull_request) Failing after 12s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m50s
Project CI / Repository checks (pull_request) Failing after 9s
Project CI / Frontend tests (pull_request) Successful in 6m9s
Project CI / AI game creator shell web tests (pull_request) Successful in 9m8s
Project CI / Native shell tests (pull_request) Successful in 12m36s
修复flat自动识别门禁并严格校验模式和颜色

保持旧请求幂等指纹并区分客户端抠图意图

同步工具说明和Skill契约并补充定向测试

记录真实BgFilter验证及本地数据库阻塞的待验收项
2026-09-16 22:06:08 +08:00
lhk229 af9078cb97 补充抠图模式调用说明
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
说明complex语义分割与flat纯色背景抠图

明确纯色背景优先使用flat并移除内部实现术语
2026-09-16 21:36:15 +08:00
lhk229 e522f651bc Merge remote-tracking branch 'origin/master' into feat/bgfilter-api
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
2026-09-16 21:26:18 +08:00
lhk229 c72f77e9ca 调整抠图模式参数说明 2026-09-16 21:25:55 +08:00
lhk229 fe4c2da9b3 扩展AGC抠图客户端参数
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
支持complex与flat模式及auto背景色

保留旧客户端参数调用兼容性
2026-09-16 21:14:03 +08:00
lhk229 aa74c8a9f9 接通抠图模式到BgFilter队列
透传backgroundMode和screenColor到内部worker

保留auto及省略颜色的下游识别语义
2026-09-16 20:41:48 +08:00
lhk229 483f636570 增加主站抠图参数归一化
缺省模式兼容为complex并校验颜色格式

将auto颜色原样保留给BgFilter
2026-09-16 20:26:46 +08:00
lhk229 5aecadf700 扩展主站抠图请求契约
增加backgroundMode和screenColor可选字段

同步External v1 OpenAPI抠图模式说明
2026-09-16 20:02:23 +08:00
lhk229 f42d8ee811 冻结BgFilter抠图服务契约
记录flat与complex模式及auto背景色行为

补充服务器认证头和当前运行版本
2026-09-16 19:59:34 +08:00
lhk229 4b6df610af 补充AGC抠图模式透传方案
新增主站与BgFilter模式及背景色契约

补充AGC客户端同步任务与兼容性规则

记录联调验收和发布回滚边界
2026-09-16 19:58:12 +08:00
75 changed files with 87 additions and 2416 deletions
-18
View File
@@ -50,24 +50,6 @@ _Avoid_: 为每个玩法单独发明素材流水线、把系列素材建模成
## Language
### 3D Model Generation
**3D 模型生成操作**:
由文本提示驱动、可异步查询并最终产生模型文件的 provider-neutral 操作;操作状态和产品资源结果分开建模。
_Avoid_: 直接把第三方 provider task 当作产品资源、把模型 URL 当作永久资源地址
**Provider task**:
第三方 3D 生成平台返回的任务引用与任务快照,只存在于 provider adapter 的 Rust 边界内;它不是 Genarrative 的内部操作 ID。
_Avoid_: 把 Tripo task ID 当作稳定产品 operationId、让 SDK 类型穿透 api-server
**临时 provider URL**:
第三方任务完成后返回的短时模型下载地址,必须通过显式下载流程转换为本地或持久化资源,不能直接当作长期资产地址。
_Avoid_: 永久 OSS URL、资源 ID
**模型 artifact**:
由 text-to-model、image-to-model 或 multiview-to-model 任务产生、待应用层登记和持久化的模型文件结果;provider adapter 只提供可下载结果,不负责生成 resourceId 或 assetId。
_Avoid_: 仅 UI 中展示的模型链接、没有来源任务的静态文件
### Puzzle Clear
**拼消消**:
-1
View File
@@ -5016,7 +5016,6 @@ dependencies = [
"serde",
"serde_json",
"sha2",
"ts-rs",
]
[[package]]
@@ -411,9 +411,7 @@ export function registerClientHomeTests() {
await openResourceBookCategory('UI 交互');
expect(await findResourceSelectButton('live-hero.png')).not.toBeNull();
await openResourceBookCategory('项目版本');
expect(
await findResourceSelectButton('版本 1'),
).not.toBeNull();
expect(await findResourceSelectButton('版本 1')).not.toBeNull();
expect(runButton.getAttribute('data-unavailable')).toBeNull();
await waitFor(() => {
expect(invoke).toHaveBeenCalledWith(
@@ -582,9 +580,7 @@ export function registerClientHomeTests() {
}),
).not.toBeNull();
await openResourceBookCategory('项目版本');
expect(
await findResourceSelectButton('版本 1'),
).not.toBeNull();
expect(await findResourceSelectButton('版本 1')).not.toBeNull();
expect(runButton.getAttribute('data-unavailable')).toBeNull();
await waitFor(() => {
expect(
@@ -3836,7 +3836,9 @@ export function registerProjectWorkbenchFoundationTests() {
];
await openResourceBookCategory('角色与对象');
const infoButton = await screen.findByRole('button', { name: '查看hero.png资源信息' });
const infoButton = await screen.findByRole('button', {
name: '查看hero.png资源信息',
});
expect(infoButton.getAttribute('aria-pressed')).toBe('false');
// 未选中的卡片直接打开信息,不被选中变化 effect 立即关闭。
@@ -4096,13 +4098,7 @@ export function registerProjectWorkbenchFoundationTests() {
within(audioToolbar)
.getAllByRole('button')
.map((button) => button.getAttribute('aria-label')),
).toEqual([
'引用资源 bgm.mp3',
'编辑标签',
'重命名',
'导出',
'删除素材',
]);
).toEqual(['引用资源 bgm.mp3', '编辑标签', '重命名', '导出', '删除素材']);
// 工具条的「导出」必须真的走通落盘链路:原生保存对话框 + Rust 分块复制,
// 而不是只渲染一个按钮。原生对话框由入口文件 mock 成"用户选了
@@ -2072,7 +2072,9 @@ describe('project resource live canvas integration', () => {
await openResourceBookCategory('角色与对象');
fireEvent.click(await findResourceSelectButton('hero.png'));
const toolbar = await screen.findByRole('toolbar', { name: '图片工具栏' });
fireEvent.click(screen.getByRole('button', { name: '查看hero.png资源信息' }));
fireEvent.click(
screen.getByRole('button', { name: '查看hero.png资源信息' }),
);
const infoPanel = await screen.findByRole('dialog', { name: '资源信息' });
// 分类值本身仍是只读文本(`dd` 里只有值,入口按钮在它外面)。
@@ -379,7 +379,10 @@ function toolbarAction(toolbar: HTMLElement, name: string) {
const visible = within(toolbar).queryByRole('button', { name });
if (visible) return visible;
fireEvent.mouseEnter(within(toolbar).getByRole('button', { name: '更多' }));
return within(screen.getByRole('group', { name: '更多操作' })).getByRole('button', { name });
return within(screen.getByRole('group', { name: '更多操作' })).getByRole(
'button',
{ name },
);
}
async function selectCardAndOpenToolbar(label: string) {
@@ -550,12 +553,20 @@ describe('版本级资源替换', () => {
const toolbar = await selectCardAndOpenToolbar('legacy.png');
fireEvent.mouseEnter(within(toolbar).getByRole('button', { name: '更多' }));
const menu = screen.getByRole('group', { name: '更多操作' });
const viewport = () => document.querySelector('[data-resource-viewport]')
?.getAttribute('data-resource-viewport');
const viewport = () =>
document
.querySelector('[data-resource-viewport]')
?.getAttribute('data-resource-viewport');
const before = viewport();
expect(before).toBeTruthy();
const wheel = new WheelEvent('wheel', { bubbles: true, cancelable: true, deltaY: 120 });
act(() => { menu.dispatchEvent(wheel); });
const wheel = new WheelEvent('wheel', {
bubbles: true,
cancelable: true,
deltaY: 120,
});
act(() => {
menu.dispatchEvent(wheel);
});
expect(wheel.defaultPrevented).toBe(false);
expect(viewport()).toBe(before);
@@ -568,9 +579,15 @@ describe('版本级资源替换', () => {
const scene = document.querySelector('.game-resource-book-scene')!;
act(() => {
scene.dispatchEvent(new WheelEvent('wheel', {
bubbles: true, cancelable: true, deltaY: 120, clientX: 90, clientY: 70,
}));
scene.dispatchEvent(
new WheelEvent('wheel', {
bubbles: true,
cancelable: true,
deltaY: 120,
clientX: 90,
clientY: 70,
}),
);
});
expect(viewport()).not.toBe(before);
});
@@ -578,13 +595,17 @@ describe('版本级资源替换', () => {
it('信息从未选中卡打开并跟随资源身份,普通换选会关闭', async () => {
renderReplacementWorkbench();
await selectCardAndOpenToolbar('legacy.png');
const lateInfo = screen.getByRole('button', { name: '查看late.png资源信息' });
const lateInfo = screen.getByRole('button', {
name: '查看late.png资源信息',
});
fireEvent.pointerDown(lateInfo, { button: 0 });
fireEvent.click(lateInfo);
const panel = screen.getByRole('dialog', { name: '资源信息' });
expect(within(panel).getByText('late.png')).toBeTruthy();
expect(lateInfo.getAttribute('aria-pressed')).toBe('true');
fireEvent.click(screen.getByRole('button', { name: '查看legacy.png资源信息' }));
fireEvent.click(
screen.getByRole('button', { name: '查看legacy.png资源信息' }),
);
const switched = screen.getByRole('dialog', { name: '资源信息' });
expect(within(switched).getByText('legacy.png')).toBeTruthy();
expect(within(switched).queryByText('late.png')).toBeNull();
@@ -597,10 +618,10 @@ describe('版本级资源替换', () => {
// 未被初始版本绑定的素材(版本创建之后才登记):工具条照常出现,但没有「替换素材」。
const lateToolbar = await selectCardAndOpenToolbar('late.png');
fireEvent.mouseEnter(within(lateToolbar).getByRole('button', { name: '更多' }));
expect(
screen.queryByRole('button', { name: '替换素材' }),
).toBeNull();
fireEvent.mouseEnter(
within(lateToolbar).getByRole('button', { name: '更多' }),
);
expect(screen.queryByRole('button', { name: '替换素材' })).toBeNull();
expect(
within(lateToolbar).getByRole('button', { name: '快速编辑' }),
).not.toBeNull();
@@ -614,9 +635,7 @@ describe('版本级资源替换', () => {
// 被当前版本绑定的素材:入口出现。
const sourceToolbar = await selectCardAndOpenToolbar('legacy.png');
expect(
toolbarAction(sourceToolbar, '替换素材'),
).not.toBeNull();
expect(toolbarAction(sourceToolbar, '替换素材')).not.toBeNull();
});
it('从入口一路走到写入:候选弹窗禁用硬门禁项、给出格式提示、直接替换且不产生新版本', async () => {
@@ -895,9 +914,10 @@ describe('版本级资源替换', () => {
const deleteButton = toolbarAction(toolbar, '删除素材');
const toolbarLabels = [
...within(toolbar).getAllByRole('button'),
...within(screen.getByRole('group', { name: '更多操作' })).getAllByRole('button'),
]
.map((button) => button.getAttribute('aria-label') ?? '');
...within(screen.getByRole('group', { name: '更多操作' })).getAllByRole(
'button',
),
].map((button) => button.getAttribute('aria-label') ?? '');
// 末位:在最后一个非破坏性动作(替换素材)之后、共享导出按钮之前。
expect(toolbarLabels.indexOf('删除素材')).toBeGreaterThan(
toolbarLabels.indexOf('替换素材'),
@@ -1411,9 +1431,7 @@ describe('版本级资源替换', () => {
// 第一次:legacy → final。
const legacyToolbar = await selectCardAndOpenToolbar('legacy.png');
fireEvent.click(
toolbarAction(legacyToolbar, '替换素材'),
);
fireEvent.click(toolbarAction(legacyToolbar, '替换素材'));
let dialog = await screen.findByRole('dialog', {
name: '选择替换素材',
});
@@ -1431,9 +1449,7 @@ describe('版本级资源替换', () => {
// 第二次:final → final.webp(同一个工作台会话内)。
const finalToolbar = await selectCardAndOpenToolbar('final.png');
fireEvent.click(
toolbarAction(finalToolbar, '替换素材'),
);
fireEvent.click(toolbarAction(finalToolbar, '替换素材'));
dialog = await screen.findByRole('dialog', { name: '选择替换素材' });
fireEvent.click(
within(dialog).getByRole('option', { name: '选择替换素材final.webp' }),
-4
View File
@@ -25,8 +25,6 @@
## AI 游戏创作与 Agent Runtime
- [Tripo 3D 模型 Provider 集成](./technical/【技术方案】Tripo文本到3D模型Provider集成-2026-09-18.md):实现 text-to-model、image-to-model、multiview-to-model 的 Rust provider adapter,暂不接入 api-server。
- [策划 Agent 生产迁移与工作区浏览](./technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md):实施中;以自由协作原型为行为基线,复用生产基建,采用阶段审批与用户工作区文件浏览。无旧 V2 会话的策划入口切换到新设计 Agent。
- [LLM 累计额度结算](./technical/【技术方案】LLM累计额度结算-2026-09-05.md):Router 累计额度、首次基线与原子钱包结算。
@@ -76,8 +74,6 @@
## 后端、运维与测试
- [Tripo SDK 隔离与 Provider DTO 边界 ADR](./adr/【ADR】0001-Tripo%20SDK隔离与Provider%20DTO边界-2026-09-18.md):固定 SDK 只存在于 `platform-tripo` 内部,provider task 与产品资源结果分层。
- [BgFilter 受限资源调度方案](./technical/【后端架构】BgFilter受限资源调度方案-2026-07-21.md)
- [Issue225 登录成功 AGC 用户归属修复](./technical/【后端架构】Issue225登录成功AGC用户归属修复方案-2026-09-03.md):登录 route tracking 的真实用户归属、`daily_login` 幂等边界和实施验收。
- [SpacetimeDB 连接池取消安全](./【后端架构】SpacetimeDB连接池租约Drop兜底与取消安全-2026-06-11.md)
@@ -1,9 +0,0 @@
# 【ADR】0001-Tripo SDK隔离与Provider DTO边界-2026-09-18
状态:已接受
`tripo3d-sdk` 只允许出现在 `platform-tripo` 内部。该 crate 以显式必填配置创建可复用 provider client,只公开自己的 text-to-model、image-to-model、multiview-to-model DTO、通用单次 task 查询、显式模型下载和结构化错误;不暴露 SDK 类型、`wait_for_task` 或后台轮询。共享产品契约与 provider task 结果分层,provider adapter 不伪造 `resourceId`/`assetId`shared-contracts 的 Rust 类型始终通过 ts-rs 生成目录化 TypeScript binding。
选择这个边界是为了避免 API 层绑定第三方 SDK 的任务/错误模型,同时让未来的资源持久化、幂等和 provider 替换由应用层负责。请求 enum 以 Tripo API 文档为准;当前 `compress=geometry`、纹理质量 `fast/standard/detailed/extreme` 及纹理版本已经纳入目录化 Rust/TypeScript contracts。文档确认不存在于这三个 endpoint 的 `style` 字段不再保留占位类型,组合约束在 provider 副作用前执行。
完成结果按 endpoint 建模为严格类型:text-to-model 要求模型、渲染图和生成参考图 URLimage-to-model 与 multiview-to-model 要求模型和渲染图 URL;共同 task DTO 只用 enum 标识具体结果,不再提供由 `Vec` 和可选字段组成的宽松通用 output。URL 使用语义中性的 `TripoUrl`,真实响应缺少对应必填字段时以 output schema error 失败关闭。
@@ -1,37 +0,0 @@
# 【技术方案】Tripo文本到3D模型 Provider 集成-2026-09-18
## 目标
本阶段在 `server-rs/crates/platform-tripo` 内接入固定 revision 的 `tripo3d-sdk`,完成 text-to-model、image-to-model 和 multiview-to-model 三个 3D 生成入口的 Rust provider adapter。adapter 提供显式配置、提交、单次通用 task 查询和模型下载能力;共享产品契约继续由 `shared-contracts` 管理,并始终生成目录化 ts-rs TypeScript binding。
代码按 API 目录组织:公共 SDK 配置、client、任务映射、错误、下载类型和 task 生命周期 DTO 位于 `platform-tripo/src/common/`;三个生成 API 各自拥有独立目录和结果类型。Rust 与 TypeScript contracts 按 `common/``text_to_model/``image_to_model/``multiview_to_model/` 分目录生成。
## 非目标
- 不接入 `api-server`、worker、SpacetimeDB、OSS、计费或 UI。
- 不暴露 SDK 的 `wait_for_task`,不在 adapter 内启动后台轮询。
- 不实现后处理、rig、animation、图片生成或其它 SDK endpoint。
## 边界与状态
`platform-tripo` 是唯一接触 `tripo3d-sdk` 的边界。它返回自己的 provider DTO,不让 SDK 类型穿透到未来的 `api-server`。Tripo 的 `success` 映射为 `completed``failed`/`banned` 映射为 `failed``cancelled``expired` 保留为独立终态;未知状态返回结构化错误。
provider task 结果与产品资源结果分离。provider adapter 不生成 `resourceId``assetId`;未来应用层在资源持久化后再构造带资源 ID 的产品 DTO。模型 URL 被视为临时 provider 引用,下载由显式方法完成。`TripoUrl``Debug``redacted()` 只输出 scheme、host 与 path,隐藏可能带签名的 query 与 fragment;完整 URL 仅通过 `as_str()` 显式读取;`TripoUrl` 不实现 `Display`,避免 `{}` 这类通用格式化把带签名的完整地址写进日志,冒烟示例同样只打印脱敏后的地址。
task 尚未完成时 `output` 为空;完成后 `output` 必须是与 task type 一致的 enum variant,不使用把不同 endpoint 字段揉在一起的通用可选字段结构。真实 provider smoke 确认:text-to-model 结果固定包含 `model_url``rendered_image_url``generated_image_url`image-to-model 和 multiview-to-model 结果固定包含 `model_url``rendered_image_url`。这些字段在各自结果 struct 中均为必填 `TripoUrl`;缺失、URL 非法或 task type 不受支持时返回 `TripoError::OutputSchema`
生成结果 DTO 中的 `poll_after_ms``updated_at_micros``size_bytes` 以 TypeScript `number` 导出:毫秒级轮询间隔与几十 MB 的产物字节数远低于 2^53,微秒时间戳在 2^53 内也可精确表示(约到公元 2255 年),因此不做 `bigint`/`string` 特殊处理;若将来出现超过 2^53 的取值再评估。
## 请求与类型
三个生成请求使用官方文档已确认的 enum:模型版本、纹理版本、纹理质量(含 `fast`)、几何质量、纹理对齐、输入方向、导出方向和压缩类型(`geometry`)。文档未将 `style` 列为这三个 endpoint 的请求字段,因此不再保留占位 enum。`model` 在三个请求中都是必填字段(缺失或取值非法时在反序列化阶段即拒绝);除它以外的参数可选,在 Rust 侧为 `Option`TypeScript 绑定对应 `field?: T | null`,调用方既可省略字段也可显式传 `null`。TypeScript 绑定仍按目录生成到 `packages/shared/src/contracts/model3d/`,并由该目录的 `index.ts``packages/shared` 的 barrel 统一再导出;生成命令 `npm run contracts:model3d:generate` 写入的是未格式化的 ts-rs 输出,需再执行 `prettier --write packages/shared/src/contracts/model3d` 后提交。
提交前由 provider 统一执行组合校验:模型版本决定 family;`fast` 必须配 `v3.5-20260815`;几何质量 / 压缩 / 自动尺寸 / P 系列与 H 系列能力按模型版本限制;`quad``generate_parts``smart_low_poly``texture/pbr` 组合按文档的互斥关系拒绝;`face_limit` 按模型、quad 和 smart-low-poly 模式检查范围。SDK 返回的参数错误仍统一归一为 `TripoError`
## 验收
- `platform-tripo` 不公开 re-export SDK 类型或 `wait_for_task`
- 三个 3D 生成入口的 submit、通用 get task、按 endpoint 严格映射的完成结果和显式 download API 可编译。
- provider 错误统一为 adapter 错误类型。
- shared contracts 的 ts-rs binding 无 feature 开关且始终可生成。
- 真实 Provider smoke 已覆盖三个入口;example 保留脱敏后的结果结构和下载产物信息。
-1
View File
@@ -41,7 +41,6 @@
"admin-web:typecheck": "node scripts/admin-web-build.mjs typecheck",
"admin-web:preview": "npm --prefix apps/admin-web run preview --",
"spacetime:generate": "node scripts/generate-spacetime-bindings.mjs",
"contracts:model3d:generate": "cargo test --locked -p shared-contracts model3d --manifest-path server-rs/Cargo.toml",
"spacetime:external-generation:maintain": "node scripts/spacetime-maintain-external-generation-jobs.mjs",
"spacetime:editor-image-asset-kind:clean": "node scripts/spacetime-clean-editor-image-asset-kind.mjs",
"spacetime:editor-canvas-layout:migrate": "node scripts/spacetime-migrate-editor-canvas-layout.mjs",
-1
View File
@@ -3,4 +3,3 @@ export type * from './editorAudio';
export * from './gameCreationApp';
export * from './hostBridge';
export type * from './hyper3d';
export type * from './model3d';
@@ -1,3 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dCompression = 'geometry';
@@ -1,3 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dExportOrientation = '+x' | '-x' | '+y' | '-y';
@@ -1,3 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dGeometryQuality = 'standard' | 'detailed';
@@ -1,3 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dInputOrientation = 'default' | 'align_image';
@@ -1,8 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dModelVersion =
| 'v3.1-20260211'
| 'v3.0-20250812'
| 'v2.5-20250123'
| 'P1-20260311'
| 'P2-20260801';
@@ -1,10 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dOutputFormat =
| 'glb'
| 'gltf'
| 'fbx'
| 'obj'
| 'stl'
| 'usdz'
| '3mf';
@@ -1,9 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dTaskStatus =
| 'queued'
| 'running'
| 'completed'
| 'failed'
| 'cancelled'
| 'expired';
@@ -1,3 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dTextureAlignment = 'original_image' | 'geometry';
@@ -1,7 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dTextureQuality =
| 'fast'
| 'standard'
| 'detailed'
| 'extreme';
@@ -1,6 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dTextureVersion =
| 'v3.5-20260815'
| 'v3.0-20250812'
| 'v2.5-20250123';
@@ -1,33 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Model3dCompression } from '../common/Model3dCompression';
import type { Model3dExportOrientation } from '../common/Model3dExportOrientation';
import type { Model3dGeometryQuality } from '../common/Model3dGeometryQuality';
import type { Model3dInputOrientation } from '../common/Model3dInputOrientation';
import type { Model3dModelVersion } from '../common/Model3dModelVersion';
import type { Model3dTextureAlignment } from '../common/Model3dTextureAlignment';
import type { Model3dTextureQuality } from '../common/Model3dTextureQuality';
import type { Model3dTextureVersion } from '../common/Model3dTextureVersion';
export type Model3dImageToModelRequest = {
input: string;
model: Model3dModelVersion;
enableImageAutofix?: boolean | null;
modelSeed?: number | null;
textureSeed?: number | null;
texture?: boolean | null;
pbr?: boolean | null;
textureQuality?: Model3dTextureQuality | null;
textureVersion?: Model3dTextureVersion | null;
delight?: boolean | null;
textureAlignment?: Model3dTextureAlignment | null;
geometryQuality?: Model3dGeometryQuality | null;
faceLimit?: number | null;
autoSize?: boolean | null;
orientation?: Model3dInputOrientation | null;
quad?: boolean | null;
smartLowPoly?: boolean | null;
generateParts?: boolean | null;
compress?: Model3dCompression | null;
exportUv?: boolean | null;
exportOrientation?: Model3dExportOrientation | null;
};
@@ -1,18 +0,0 @@
export type * from './common/Model3dCompression';
export type * from './common/Model3dExportOrientation';
export type * from './common/Model3dGeometryQuality';
export type * from './common/Model3dInputOrientation';
export type * from './common/Model3dModelVersion';
export type * from './common/Model3dOutputFormat';
export type * from './common/Model3dTaskStatus';
export type * from './common/Model3dTextureAlignment';
export type * from './common/Model3dTextureQuality';
export type * from './common/Model3dTextureVersion';
export type * from './image-to-model/Model3dImageToModelRequest';
export type * from './multiview-to-model/Model3dMultiviewInputs';
export type * from './multiview-to-model/Model3dMultiviewToModelRequest';
export type * from './text-to-model/Model3dArtifact';
export type * from './text-to-model/Model3dGenerationJob';
export type * from './text-to-model/Model3dGenerationResult';
export type * from './text-to-model/Model3dGenerationSubmission';
export type * from './text-to-model/Model3dTextToModelRequest';
@@ -1,11 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Model3dMultiviewInputs =
| {
kind: 'views';
front: string;
left?: string | null;
back?: string | null;
right?: string | null;
}
| { kind: 'taskId'; taskId: string };
@@ -1,33 +0,0 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Model3dCompression } from '../common/Model3dCompression';
import type { Model3dExportOrientation } from '../common/Model3dExportOrientation';
import type { Model3dGeometryQuality } from '../common/Model3dGeometryQuality';
import type { Model3dInputOrientation } from '../common/Model3dInputOrientation';
import type { Model3dModelVersion } from '../common/Model3dModelVersion';
import type { Model3dTextureAlignment } from '../common/Model3dTextureAlignment';
import type { Model3dTextureQuality } from '../common/Model3dTextureQuality';
import type { Model3dTextureVersion } from '../common/Model3dTextureVersion';
import type { Model3dMultiviewInputs } from './Model3dMultiviewInputs';
export type Model3dMultiviewToModelRequest = {
inputs: Model3dMultiviewInputs;
model: Model3dModelVersion;
modelSeed?: number | null;
textureSeed?: number | null;
texture?: boolean | null;
pbr?: boolean | null;
textureQuality?: Model3dTextureQuality | null;
textureVersion?: Model3dTextureVersion | null;
delight?: boolean | null;
geometryQuality?: Model3dGeometryQuality | null;
textureAlignment?: Model3dTextureAlignment | null;
faceLimit?: number | null;
autoSize?: boolean | null;
orientation?: Model3dInputOrientation | null;
quad?: boolean | null;
smartLowPoly?: boolean | null;
generateParts?: boolean | null;
compress?: Model3dCompression | null;
exportUv?: boolean | null;
exportOrientation?: Model3dExportOrientation | null;
};

Some files were not shown because too many files have changed in this diff Show More