This commit is contained in:
2026-05-09 17:15:23 +08:00
parent 80a4183b45
commit a0ed128bde
43 changed files with 2573 additions and 381 deletions

View File

@@ -0,0 +1,169 @@
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum Hyper3dGenerationMode {
TextToModel,
ImageToModel,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dTextToModelRequest {
pub prompt: String,
#[serde(default)]
pub negative_prompt: Option<String>,
#[serde(default)]
pub seed: Option<u32>,
#[serde(default)]
pub geometry_file_format: Option<String>,
#[serde(default)]
pub material: Option<String>,
#[serde(default)]
pub quality: Option<String>,
#[serde(default)]
pub mesh_mode: Option<String>,
#[serde(default)]
pub addons: Vec<String>,
#[serde(default)]
pub bbox_condition: Option<Vec<f32>>,
#[serde(default)]
pub preview_render: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dImageToModelRequest {
#[serde(default)]
pub image_data_urls: Vec<String>,
#[serde(default)]
pub image_urls: Vec<String>,
#[serde(default)]
pub prompt: Option<String>,
#[serde(default)]
pub condition_mode: Option<String>,
#[serde(default)]
pub seed: Option<u32>,
#[serde(default)]
pub geometry_file_format: Option<String>,
#[serde(default)]
pub material: Option<String>,
#[serde(default)]
pub quality: Option<String>,
#[serde(default)]
pub mesh_mode: Option<String>,
#[serde(default)]
pub addons: Vec<String>,
#[serde(default)]
pub bbox_condition: Option<Vec<f32>>,
#[serde(default)]
pub preview_render: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dTaskSubmitResponse {
pub ok: bool,
pub provider: String,
pub mode: Hyper3dGenerationMode,
pub task_uuid: String,
pub subscription_key: String,
pub job_uuids: Vec<String>,
pub message: Option<String>,
pub tier: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dTaskStatusRequest {
pub subscription_key: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dTaskStatusResponse {
pub ok: bool,
pub provider: String,
pub status: String,
#[serde(default)]
pub jobs: Vec<Hyper3dJobStatusPayload>,
pub raw: Value,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dJobStatusPayload {
pub uuid: Option<String>,
pub status: String,
pub progress: Option<f32>,
pub message: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dDownloadRequest {
pub task_uuid: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dDownloadResponse {
pub ok: bool,
pub provider: String,
#[serde(default)]
pub files: Vec<Hyper3dDownloadFilePayload>,
pub raw: Value,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Hyper3dDownloadFilePayload {
pub name: String,
pub url: String,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn text_to_model_request_uses_camel_case_fields() {
let payload = serde_json::to_value(Hyper3dTextToModelRequest {
prompt: "低多边形宝箱".to_string(),
negative_prompt: Some("文字".to_string()),
seed: Some(42),
geometry_file_format: Some("glb".to_string()),
material: Some("PBR".to_string()),
quality: Some("medium".to_string()),
mesh_mode: Some("Quad".to_string()),
addons: vec!["HighPack".to_string()],
bbox_condition: Some(vec![1.0, 1.0, 1.0]),
preview_render: Some(true),
})
.expect("request should serialize");
assert_eq!(payload["geometryFileFormat"], json!("glb"));
assert_eq!(payload["meshMode"], json!("Quad"));
assert_eq!(payload["bboxCondition"], json!([1.0, 1.0, 1.0]));
}
#[test]
fn submit_response_keeps_mode_as_kebab_case() {
let payload = serde_json::to_value(Hyper3dTaskSubmitResponse {
ok: true,
provider: "hyper3d-rodin".to_string(),
mode: Hyper3dGenerationMode::ImageToModel,
task_uuid: "task-1".to_string(),
subscription_key: "sub-1".to_string(),
job_uuids: vec!["job-1".to_string()],
message: Some("submitted".to_string()),
tier: "Gen-2".to_string(),
})
.expect("response should serialize");
assert_eq!(payload["mode"], json!("image-to-model"));
assert_eq!(payload["subscriptionKey"], json!("sub-1"));
}
}

View File

@@ -7,6 +7,7 @@ pub mod big_fish;
pub mod big_fish_works;
pub mod creation_agent_document_input;
pub mod creative_agent;
pub mod hyper3d;
pub mod llm;
pub mod match3d_agent;
pub mod match3d_runtime;