抓大鹅F3实现
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-30 21:01:36 +08:00
parent 22f6e6f4e7
commit 08815d98bc
39 changed files with 5891 additions and 18 deletions

View File

@@ -7,6 +7,9 @@ pub mod big_fish;
pub mod big_fish_works;
pub mod creation_agent_document_input;
pub mod llm;
pub mod match3d_agent;
pub mod match3d_runtime;
pub mod match3d_works;
pub mod puzzle_agent;
pub mod puzzle_gallery;
pub mod puzzle_runtime;

View File

@@ -0,0 +1,137 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct CreateMatch3DAgentSessionRequest {
#[serde(default)]
pub seed_text: Option<String>,
#[serde(default)]
pub theme_text: Option<String>,
#[serde(default)]
pub reference_image_src: Option<String>,
#[serde(default)]
pub clear_count: Option<u32>,
#[serde(default)]
pub difficulty: Option<u32>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SendMatch3DAgentMessageRequest {
pub client_message_id: String,
pub text: String,
#[serde(default)]
pub quick_fill_requested: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ExecuteMatch3DAgentActionRequest {
pub action: String,
#[serde(default)]
pub game_name: Option<String>,
#[serde(default)]
pub summary: Option<String>,
#[serde(default)]
pub tags: Option<Vec<String>>,
#[serde(default)]
pub cover_image_src: Option<String>,
#[serde(default)]
pub clear_count: Option<u32>,
#[serde(default)]
pub difficulty: Option<u32>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DCreatorConfigResponse {
pub theme_text: String,
#[serde(default)]
pub reference_image_src: Option<String>,
pub clear_count: u32,
pub difficulty: u32,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DResultDraftResponse {
pub game_name: String,
pub theme_text: String,
pub summary: String,
pub tags: Vec<String>,
#[serde(default)]
pub cover_image_src: Option<String>,
#[serde(default)]
pub reference_image_src: Option<String>,
pub clear_count: u32,
pub difficulty: u32,
pub publish_ready: bool,
pub blockers: Vec<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DAgentMessageResponse {
pub id: String,
pub role: String,
pub kind: String,
pub text: String,
pub created_at: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DAgentSessionSnapshotResponse {
pub session_id: String,
pub current_turn: u32,
pub progress_percent: u32,
pub stage: String,
#[serde(default)]
pub config: Option<Match3DCreatorConfigResponse>,
#[serde(default)]
pub draft: Option<Match3DResultDraftResponse>,
pub messages: Vec<Match3DAgentMessageResponse>,
#[serde(default)]
pub last_assistant_reply: Option<String>,
#[serde(default)]
pub published_profile_id: Option<String>,
pub updated_at: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DAgentSessionResponse {
pub session: Match3DAgentSessionSnapshotResponse,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DAgentActionResponse {
pub session: Match3DAgentSessionSnapshotResponse,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn create_match3d_session_request_uses_camel_case() {
let payload = serde_json::to_value(CreateMatch3DAgentSessionRequest {
seed_text: Some("水果消除".to_string()),
theme_text: Some("水果".to_string()),
reference_image_src: Some("data:image/png;base64,abc".to_string()),
clear_count: Some(4),
difficulty: Some(3),
})
.expect("payload should serialize");
assert_eq!(payload["seedText"], json!("水果消除"));
assert_eq!(payload["themeText"], json!("水果"));
assert_eq!(
payload["referenceImageSrc"],
json!("data:image/png;base64,abc")
);
assert_eq!(payload["clearCount"], json!(4));
}
}

View File

@@ -0,0 +1,115 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct StartMatch3DRunRequest {
pub profile_id: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ClickMatch3DItemRequest {
pub item_instance_id: String,
pub client_action_id: String,
pub snapshot_version: u64,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct StopMatch3DRunRequest {
pub client_action_id: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DItemSnapshotResponse {
pub item_instance_id: String,
pub item_type_id: String,
pub visual_key: String,
pub x: f32,
pub y: f32,
pub radius: f32,
pub layer: u32,
pub state: String,
pub clickable: bool,
#[serde(default)]
pub tray_slot_index: Option<u32>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DTraySlotResponse {
pub slot_index: u32,
#[serde(default)]
pub item_instance_id: Option<String>,
#[serde(default)]
pub item_type_id: Option<String>,
#[serde(default)]
pub visual_key: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DRunSnapshotResponse {
pub run_id: String,
pub profile_id: String,
pub owner_user_id: String,
pub status: String,
pub started_at_ms: u64,
pub duration_limit_ms: u64,
pub remaining_ms: u64,
pub clear_count: u32,
pub total_item_count: u32,
pub cleared_item_count: u32,
pub board_version: u64,
pub items: Vec<Match3DItemSnapshotResponse>,
pub tray_slots: Vec<Match3DTraySlotResponse>,
#[serde(default)]
pub failure_reason: Option<String>,
#[serde(default)]
pub last_confirmed_action_id: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DClickConfirmationResponse {
pub accepted: bool,
#[serde(default)]
pub reject_reason: Option<String>,
#[serde(default)]
pub entered_slot_index: Option<u32>,
pub cleared_item_instance_ids: Vec<String>,
pub run: Match3DRunSnapshotResponse,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DRunResponse {
pub run: Match3DRunSnapshotResponse,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DClickResponse {
pub confirmation: Match3DClickConfirmationResponse,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn click_match3d_item_request_uses_camel_case() {
let payload = serde_json::to_value(ClickMatch3DItemRequest {
item_instance_id: "item-1".to_string(),
client_action_id: "action-1".to_string(),
snapshot_version: 7,
})
.expect("payload should serialize");
assert_eq!(payload["itemInstanceId"], json!("item-1"));
assert_eq!(payload["clientActionId"], json!("action-1"));
assert_eq!(payload["snapshotVersion"], json!(7));
}
}

View File

@@ -0,0 +1,89 @@
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct PutMatch3DWorkRequest {
pub game_name: String,
pub summary: String,
pub tags: Vec<String>,
#[serde(default)]
pub cover_image_src: Option<String>,
#[serde(default)]
pub reference_image_src: Option<String>,
pub clear_count: u32,
pub difficulty: u32,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DWorkSummaryResponse {
pub work_id: String,
pub profile_id: String,
pub owner_user_id: String,
#[serde(default)]
pub source_session_id: Option<String>,
pub game_name: String,
pub theme_text: String,
pub summary: String,
pub tags: Vec<String>,
#[serde(default)]
pub cover_image_src: Option<String>,
#[serde(default)]
pub reference_image_src: Option<String>,
pub clear_count: u32,
pub difficulty: u32,
pub publication_status: String,
pub play_count: u32,
pub updated_at: String,
#[serde(default)]
pub published_at: Option<String>,
pub publish_ready: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DWorkProfileResponse {
#[serde(flatten)]
pub summary: Match3DWorkSummaryResponse,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DWorksResponse {
pub items: Vec<Match3DWorkSummaryResponse>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DWorkDetailResponse {
pub item: Match3DWorkProfileResponse,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Match3DWorkMutationResponse {
pub item: Match3DWorkProfileResponse,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn match3d_work_request_uses_camel_case() {
let payload = serde_json::to_value(PutMatch3DWorkRequest {
game_name: "水果抓大鹅".to_string(),
summary: "水果主题".to_string(),
tags: vec!["水果".to_string()],
cover_image_src: None,
reference_image_src: None,
clear_count: 4,
difficulty: 5,
})
.expect("payload should serialize");
assert_eq!(payload["gameName"], json!("水果抓大鹅"));
assert_eq!(payload["clearCount"], json!(4));
}
}