From 1392303f1c4359c218d5cf4c5e0d15f6086cb7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Sat, 19 Sep 2026 14:16:39 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=A5=91=E7=BA=A6=E6=8A=8A?= =?UTF-8?q?=20model=20=E6=94=B9=E4=B8=BA=E5=BF=85=E5=A1=AB=E5=AD=97?= =?UTF-8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 三个生成请求的 model 由 Option 改为必填 Model3dModelVersion,并同步重新生成 TypeScript 绑定 validate_generation_options 不再重复校验 model 缺失,直接由必填的 model 推导 family 三个 client 的 to_sdk_params 改为直接提交模型版本字符串 冒烟示例与技术方案文档同步为必填写法 --- ...术方案】Tripo文本到3D模型Provider集成-2026-09-18.md | 4 ++-- .../image-to-model/Model3dImageToModelRequest.ts | 2 +- .../Model3dMultiviewToModelRequest.ts | 2 +- .../text-to-model/Model3dTextToModelRequest.ts | 2 +- .../platform-tripo/examples/tripo_generation_smoke.rs | 6 +++--- .../crates/platform-tripo/src/common/validation.rs | 11 ++--------- .../platform-tripo/src/image_to_model/client.rs | 7 ++----- .../platform-tripo/src/multiview_to_model/client.rs | 7 ++----- .../crates/platform-tripo/src/text_to_model/client.rs | 9 +++------ .../src/model3d/image_to_model/request.rs | 3 +-- .../src/model3d/multiview_to_model/request.rs | 3 +-- .../src/model3d/text_to_model/request.rs | 3 +-- 12 files changed, 20 insertions(+), 39 deletions(-) diff --git a/docs/technical/【技术方案】Tripo文本到3D模型Provider集成-2026-09-18.md b/docs/technical/【技术方案】Tripo文本到3D模型Provider集成-2026-09-18.md index 8d909d1ec..8dacd7237 100644 --- a/docs/technical/【技术方案】Tripo文本到3D模型Provider集成-2026-09-18.md +++ b/docs/technical/【技术方案】Tripo文本到3D模型Provider集成-2026-09-18.md @@ -24,9 +24,9 @@ task 尚未完成时 `output` 为空;完成后 `output` 必须是与 task type ## 请求与类型 -三个生成请求使用官方文档已确认的 enum:模型版本、纹理版本、纹理质量(含 `fast`)、几何质量、纹理对齐、输入方向、导出方向和压缩类型(`geometry`)。文档未将 `style` 列为这三个 endpoint 的请求字段,因此不再保留占位 enum。请求可选字段在 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` 后提交。 +三个生成请求使用官方文档已确认的 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 统一执行组合校验:模型必填;`fast` 必须配 `v3.5-20260815`;几何质量 / 压缩 / 自动尺寸 / P 系列与 H 系列能力按模型版本限制;`quad`、`generate_parts`、`smart_low_poly` 和 `texture/pbr` 组合按文档的互斥关系拒绝;`face_limit` 按模型、quad 和 smart-low-poly 模式检查范围。SDK 返回的参数错误仍统一归一为 `TripoError`。 +提交前由 provider 统一执行组合校验:模型版本决定 family;`fast` 必须配 `v3.5-20260815`;几何质量 / 压缩 / 自动尺寸 / P 系列与 H 系列能力按模型版本限制;`quad`、`generate_parts`、`smart_low_poly` 和 `texture/pbr` 组合按文档的互斥关系拒绝;`face_limit` 按模型、quad 和 smart-low-poly 模式检查范围。SDK 返回的参数错误仍统一归一为 `TripoError`。 ## 验收 diff --git a/packages/shared/src/contracts/model3d/image-to-model/Model3dImageToModelRequest.ts b/packages/shared/src/contracts/model3d/image-to-model/Model3dImageToModelRequest.ts index 5f0d9e56d..94fb476ee 100644 --- a/packages/shared/src/contracts/model3d/image-to-model/Model3dImageToModelRequest.ts +++ b/packages/shared/src/contracts/model3d/image-to-model/Model3dImageToModelRequest.ts @@ -10,7 +10,7 @@ import type { Model3dTextureVersion } from '../common/Model3dTextureVersion'; export type Model3dImageToModelRequest = { input: string; - model?: Model3dModelVersion | null; + model: Model3dModelVersion; enableImageAutofix?: boolean | null; modelSeed?: number | null; textureSeed?: number | null; diff --git a/packages/shared/src/contracts/model3d/multiview-to-model/Model3dMultiviewToModelRequest.ts b/packages/shared/src/contracts/model3d/multiview-to-model/Model3dMultiviewToModelRequest.ts index 1d44e7796..152def9bb 100644 --- a/packages/shared/src/contracts/model3d/multiview-to-model/Model3dMultiviewToModelRequest.ts +++ b/packages/shared/src/contracts/model3d/multiview-to-model/Model3dMultiviewToModelRequest.ts @@ -11,7 +11,7 @@ import type { Model3dMultiviewInputs } from './Model3dMultiviewInputs'; export type Model3dMultiviewToModelRequest = { inputs: Model3dMultiviewInputs; - model?: Model3dModelVersion | null; + model: Model3dModelVersion; modelSeed?: number | null; textureSeed?: number | null; texture?: boolean | null; diff --git a/packages/shared/src/contracts/model3d/text-to-model/Model3dTextToModelRequest.ts b/packages/shared/src/contracts/model3d/text-to-model/Model3dTextToModelRequest.ts index d1e6633b0..310d05e7f 100644 --- a/packages/shared/src/contracts/model3d/text-to-model/Model3dTextToModelRequest.ts +++ b/packages/shared/src/contracts/model3d/text-to-model/Model3dTextToModelRequest.ts @@ -8,7 +8,7 @@ import type { Model3dTextureVersion } from '../common/Model3dTextureVersion'; export type Model3dTextToModelRequest = { prompt: string; - model?: Model3dModelVersion | null; + model: Model3dModelVersion; negativePrompt?: string | null; imageSeed?: number | null; modelSeed?: number | null; diff --git a/server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs b/server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs index abc010eac..a353c5da5 100644 --- a/server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs +++ b/server-rs/crates/platform-tripo/examples/tripo_generation_smoke.rs @@ -47,7 +47,7 @@ async fn main() -> Result<(), Box> { let text = client .submit(&Model3dTextToModelRequest { prompt: "a low-poly wooden treasure chest".to_string(), - model: Some(Model3dModelVersion::H31), + model: Model3dModelVersion::H31, negative_prompt: None, image_seed: None, model_seed: None, @@ -73,7 +73,7 @@ async fn main() -> Result<(), Box> { let image = client .submit_image_to_model(&Model3dImageToModelRequest { input: SAMPLE_IMAGE_URL.to_string(), - model: Some(Model3dModelVersion::H31), + model: Model3dModelVersion::H31, enable_image_autofix: None, model_seed: None, texture_seed: None, @@ -105,7 +105,7 @@ async fn main() -> Result<(), Box> { back: None, right: None, }, - model: Some(Model3dModelVersion::H31), + model: Model3dModelVersion::H31, model_seed: None, texture_seed: None, texture: Some(true), diff --git a/server-rs/crates/platform-tripo/src/common/validation.rs b/server-rs/crates/platform-tripo/src/common/validation.rs index 3bb6dd878..8e0282643 100644 --- a/server-rs/crates/platform-tripo/src/common/validation.rs +++ b/server-rs/crates/platform-tripo/src/common/validation.rs @@ -6,7 +6,7 @@ use shared_contracts::model3d::common::{ use super::{TripoError, TripoField, TripoValidationReason}; pub(crate) struct TripoGenerationOptions { - pub model: Option, + pub model: Model3dModelVersion, pub texture: Option, pub pbr: Option, pub texture_quality: Option, @@ -23,14 +23,7 @@ pub(crate) struct TripoGenerationOptions { pub(crate) fn validate_generation_options( options: &TripoGenerationOptions, ) -> Result<(), TripoError> { - let model = options.model.ok_or_else(|| { - invalid( - Some(TripoField::Model), - TripoValidationReason::Required, - "model is required", - ) - })?; - let family = ModelFamily::from(model); + let family = ModelFamily::from(options.model); if options.texture_quality.is_some() && matches!(family, ModelFamily::H25) { return Err(invalid( diff --git a/server-rs/crates/platform-tripo/src/image_to_model/client.rs b/server-rs/crates/platform-tripo/src/image_to_model/client.rs index 1ec776e05..8ed928534 100644 --- a/server-rs/crates/platform-tripo/src/image_to_model/client.rs +++ b/server-rs/crates/platform-tripo/src/image_to_model/client.rs @@ -1,6 +1,6 @@ use shared_contracts::model3d::common::{ Model3dCompression, Model3dExportOrientation, Model3dGeometryQuality, Model3dInputOrientation, - Model3dModelVersion, Model3dTextureAlignment, Model3dTextureQuality, Model3dTextureVersion, + Model3dTextureAlignment, Model3dTextureQuality, Model3dTextureVersion, }; use shared_contracts::model3d::image_to_model::Model3dImageToModelRequest; use tripo3d_sdk::{models::FileInput, params::ImageToModelParams}; @@ -49,10 +49,7 @@ impl TripoProviderClient { fn to_sdk_params(request: &Model3dImageToModelRequest) -> ImageToModelParams { ImageToModelParams { input: FileInput::from(request.input.trim()), - model: request - .model - .map(Model3dModelVersion::as_str) - .map(str::to_owned), + model: Some(request.model.as_str().to_owned()), enable_image_autofix: request.enable_image_autofix, model_seed: request.model_seed, texture_seed: request.texture_seed, diff --git a/server-rs/crates/platform-tripo/src/multiview_to_model/client.rs b/server-rs/crates/platform-tripo/src/multiview_to_model/client.rs index fd650950a..c69c0cd73 100644 --- a/server-rs/crates/platform-tripo/src/multiview_to_model/client.rs +++ b/server-rs/crates/platform-tripo/src/multiview_to_model/client.rs @@ -1,6 +1,6 @@ use shared_contracts::model3d::common::{ Model3dCompression, Model3dExportOrientation, Model3dGeometryQuality, Model3dInputOrientation, - Model3dModelVersion, Model3dTextureAlignment, Model3dTextureQuality, + Model3dTextureAlignment, Model3dTextureQuality, }; use shared_contracts::model3d::multiview_to_model::{ Model3dMultiviewInputs, Model3dMultiviewToModelRequest, @@ -97,10 +97,7 @@ fn to_sdk_params(request: &Model3dMultiviewToModelRequest) -> MultiviewToModelPa MultiviewToModelParams::from_task_id(task_id.trim().to_owned()) } }; - params.model = request - .model - .map(Model3dModelVersion::as_str) - .map(str::to_owned); + params.model = Some(request.model.as_str().to_owned()); params.model_seed = request.model_seed; params.texture_seed = request.texture_seed; params.texture = request.texture; diff --git a/server-rs/crates/platform-tripo/src/text_to_model/client.rs b/server-rs/crates/platform-tripo/src/text_to_model/client.rs index cb150e4f1..fa0dbc66f 100644 --- a/server-rs/crates/platform-tripo/src/text_to_model/client.rs +++ b/server-rs/crates/platform-tripo/src/text_to_model/client.rs @@ -1,7 +1,7 @@ use crate::common::{TripoError, TripoProviderClient, TripoTaskHandle}; use shared_contracts::model3d::common::{ - Model3dCompression, Model3dExportOrientation, Model3dGeometryQuality, Model3dModelVersion, - Model3dTextureQuality, Model3dTextureVersion, + Model3dCompression, Model3dExportOrientation, Model3dGeometryQuality, Model3dTextureQuality, + Model3dTextureVersion, }; use shared_contracts::model3d::text_to_model::Model3dTextToModelRequest; @@ -25,10 +25,7 @@ impl TripoProviderClient { fn to_sdk_params(request: &Model3dTextToModelRequest) -> tripo3d_sdk::params::TextToModelParams { tripo3d_sdk::params::TextToModelParams { prompt: request.prompt.clone(), - model: request - .model - .map(Model3dModelVersion::as_str) - .map(str::to_owned), + model: Some(request.model.as_str().to_owned()), negative_prompt: request.negative_prompt.clone(), image_seed: request.image_seed, model_seed: request.model_seed, diff --git a/server-rs/crates/shared-contracts/src/model3d/image_to_model/request.rs b/server-rs/crates/shared-contracts/src/model3d/image_to_model/request.rs index 4b5e15892..e2f89c2a6 100644 --- a/server-rs/crates/shared-contracts/src/model3d/image_to_model/request.rs +++ b/server-rs/crates/shared-contracts/src/model3d/image_to_model/request.rs @@ -13,8 +13,7 @@ use super::MODEL3D_TS_EXPORT_DIR; #[ts(export, export_to = MODEL3D_TS_EXPORT_DIR)] pub struct Model3dImageToModelRequest { pub input: String, - #[ts(optional = nullable)] - pub model: Option, + pub model: Model3dModelVersion, #[ts(optional = nullable)] pub enable_image_autofix: Option, #[ts(type = "number | null")] diff --git a/server-rs/crates/shared-contracts/src/model3d/multiview_to_model/request.rs b/server-rs/crates/shared-contracts/src/model3d/multiview_to_model/request.rs index 55e8ceb4c..d91603a4f 100644 --- a/server-rs/crates/shared-contracts/src/model3d/multiview_to_model/request.rs +++ b/server-rs/crates/shared-contracts/src/model3d/multiview_to_model/request.rs @@ -35,8 +35,7 @@ pub enum Model3dMultiviewInputs { #[ts(export, export_to = MODEL3D_TS_EXPORT_DIR)] pub struct Model3dMultiviewToModelRequest { pub inputs: Model3dMultiviewInputs, - #[ts(optional = nullable)] - pub model: Option, + pub model: Model3dModelVersion, #[ts(type = "number | null")] #[ts(optional = nullable)] pub model_seed: Option, diff --git a/server-rs/crates/shared-contracts/src/model3d/text_to_model/request.rs b/server-rs/crates/shared-contracts/src/model3d/text_to_model/request.rs index 62a690e3b..1198deb8b 100644 --- a/server-rs/crates/shared-contracts/src/model3d/text_to_model/request.rs +++ b/server-rs/crates/shared-contracts/src/model3d/text_to_model/request.rs @@ -12,8 +12,7 @@ use crate::model3d::common::{ #[ts(export, export_to = MODEL3D_TS_EXPORT_DIR)] pub struct Model3dTextToModelRequest { pub prompt: String, - #[ts(optional = nullable)] - pub model: Option, + pub model: Model3dModelVersion, #[ts(optional = nullable)] pub negative_prompt: Option, #[ts(type = "number | null")]