Merge remote-tracking branch 'origin/master'
# Conflicts: # docs/technical/README.md # server-rs/crates/spacetime-client/src/module_bindings/mod.rs
This commit is contained in:
@@ -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;
|
||||
|
||||
159
server-rs/crates/shared-contracts/src/match3d_agent.rs
Normal file
159
server-rs/crates/shared-contracts/src/match3d_agent.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
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 profile_id: String,
|
||||
pub game_name: String,
|
||||
pub theme_text: String,
|
||||
#[serde(default)]
|
||||
pub summary_text: Option<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 total_item_count: u32,
|
||||
pub publish_ready: bool,
|
||||
pub blockers: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Match3DAnchorItemResponse {
|
||||
pub key: String,
|
||||
pub label: String,
|
||||
pub value: String,
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Match3DAnchorPackResponse {
|
||||
pub theme: Match3DAnchorItemResponse,
|
||||
pub clear_count: Match3DAnchorItemResponse,
|
||||
pub difficulty: Match3DAnchorItemResponse,
|
||||
}
|
||||
|
||||
#[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,
|
||||
pub anchor_pack: Match3DAnchorPackResponse,
|
||||
#[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));
|
||||
}
|
||||
}
|
||||
125
server-rs/crates/shared-contracts/src/match3d_runtime.rs
Normal file
125
server-rs/crates/shared-contracts/src/match3d_runtime.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
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 {
|
||||
#[serde(default)]
|
||||
pub run_id: Option<String>,
|
||||
pub item_instance_id: String,
|
||||
pub client_snapshot_version: u64,
|
||||
pub client_event_id: String,
|
||||
pub clicked_at_ms: 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,
|
||||
/// 对外 HTTP 快照版本。领域层内部字段名为 board_version,facade 需要在这里完成映射。
|
||||
pub snapshot_version: u64,
|
||||
pub started_at_ms: u64,
|
||||
pub duration_limit_ms: u64,
|
||||
#[serde(default)]
|
||||
pub server_now_ms: Option<u64>,
|
||||
pub remaining_ms: u64,
|
||||
pub clear_count: u32,
|
||||
pub total_item_count: u32,
|
||||
pub cleared_item_count: u32,
|
||||
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 {
|
||||
run_id: Some("run-1".to_string()),
|
||||
item_instance_id: "item-1".to_string(),
|
||||
client_snapshot_version: 7,
|
||||
client_event_id: "event-1".to_string(),
|
||||
clicked_at_ms: 12_345,
|
||||
})
|
||||
.expect("payload should serialize");
|
||||
|
||||
assert_eq!(payload["runId"], json!("run-1"));
|
||||
assert_eq!(payload["itemInstanceId"], json!("item-1"));
|
||||
assert_eq!(payload["clientSnapshotVersion"], json!(7));
|
||||
assert_eq!(payload["clientEventId"], json!("event-1"));
|
||||
assert_eq!(payload["clickedAtMs"], json!(12_345));
|
||||
}
|
||||
}
|
||||
92
server-rs/crates/shared-contracts/src/match3d_works.rs
Normal file
92
server-rs/crates/shared-contracts/src/match3d_works.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PutMatch3DWorkRequest {
|
||||
pub game_name: String,
|
||||
#[serde(default)]
|
||||
pub theme_text: Option<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(),
|
||||
theme_text: Some("水果".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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user