feat: complete M5 custom world and agent chain
This commit is contained in:
@@ -106,6 +106,9 @@ use crate::module_bindings::{
|
||||
BattleStateSnapshot as BindingBattleStateSnapshot, BattleStatus as BindingBattleStatus,
|
||||
CombatOutcome as BindingCombatOutcome,
|
||||
CustomWorldAgentMessageSnapshot as BindingCustomWorldAgentMessageSnapshot,
|
||||
CustomWorldAgentActionExecuteInput as BindingCustomWorldAgentActionExecuteInput,
|
||||
CustomWorldAgentActionExecuteResult as BindingCustomWorldAgentActionExecuteResult,
|
||||
CustomWorldAgentCardDetailGetInput as BindingCustomWorldAgentCardDetailGetInput,
|
||||
CustomWorldAgentMessageSubmitInput as BindingCustomWorldAgentMessageSubmitInput,
|
||||
CustomWorldAgentOperationGetInput as BindingCustomWorldAgentOperationGetInput,
|
||||
CustomWorldAgentOperationProcedureResult as BindingCustomWorldAgentOperationProcedureResult,
|
||||
@@ -114,6 +117,9 @@ use crate::module_bindings::{
|
||||
CustomWorldAgentSessionGetInput as BindingCustomWorldAgentSessionGetInput,
|
||||
CustomWorldAgentSessionProcedureResult as BindingCustomWorldAgentSessionProcedureResult,
|
||||
CustomWorldAgentSessionSnapshot as BindingCustomWorldAgentSessionSnapshot,
|
||||
CustomWorldDraftCardDetailResult as BindingCustomWorldDraftCardDetailResult,
|
||||
CustomWorldDraftCardDetailSectionSnapshot as BindingCustomWorldDraftCardDetailSectionSnapshot,
|
||||
CustomWorldDraftCardDetailSnapshot as BindingCustomWorldDraftCardDetailSnapshot,
|
||||
CustomWorldDraftCardSnapshot as BindingCustomWorldDraftCardSnapshot,
|
||||
CustomWorldGalleryDetailInput as BindingCustomWorldGalleryDetailInput,
|
||||
CustomWorldGalleryEntrySnapshot as BindingCustomWorldGalleryEntrySnapshot,
|
||||
@@ -130,6 +136,9 @@ use crate::module_bindings::{
|
||||
CustomWorldPublishWorldInput as BindingCustomWorldPublishWorldInput,
|
||||
CustomWorldPublishWorldResult as BindingCustomWorldPublishWorldResult,
|
||||
CustomWorldPublishedProfileCompileSnapshot as BindingCustomWorldPublishedProfileCompileSnapshot,
|
||||
CustomWorldWorkSummarySnapshot as BindingCustomWorldWorkSummarySnapshot,
|
||||
CustomWorldWorksListInput as BindingCustomWorldWorksListInput,
|
||||
CustomWorldWorksListResult as BindingCustomWorldWorksListResult,
|
||||
CustomWorldThemeMode as BindingCustomWorldThemeMode, DbConnection,
|
||||
InventoryContainerKind as BindingInventoryContainerKind,
|
||||
InventoryEquipmentSlot as BindingInventoryEquipmentSlot,
|
||||
@@ -207,8 +216,10 @@ use crate::module_bindings::{
|
||||
create_battle_state_and_return_procedure::create_battle_state_and_return as _,
|
||||
create_custom_world_agent_session_procedure::create_custom_world_agent_session as _,
|
||||
delete_runtime_snapshot_and_return_procedure::delete_runtime_snapshot_and_return as _,
|
||||
execute_custom_world_agent_action_procedure::execute_custom_world_agent_action as _,
|
||||
fail_ai_task_and_return_procedure::fail_ai_task_and_return as _,
|
||||
get_battle_state_procedure::get_battle_state as _,
|
||||
get_custom_world_agent_card_detail_procedure::get_custom_world_agent_card_detail as _,
|
||||
get_custom_world_agent_operation_procedure::get_custom_world_agent_operation as _,
|
||||
get_custom_world_agent_session_procedure::get_custom_world_agent_session as _,
|
||||
get_custom_world_gallery_detail_procedure::get_custom_world_gallery_detail as _,
|
||||
@@ -221,6 +232,7 @@ use crate::module_bindings::{
|
||||
get_story_session_state_procedure::get_story_session_state as _,
|
||||
list_custom_world_gallery_entries_procedure::list_custom_world_gallery_entries as _,
|
||||
list_custom_world_profiles_procedure::list_custom_world_profiles as _,
|
||||
list_custom_world_works_procedure::list_custom_world_works as _,
|
||||
list_platform_browse_history_procedure::list_platform_browse_history as _,
|
||||
list_profile_save_archives_procedure::list_profile_save_archives as _,
|
||||
list_profile_wallet_ledger_procedure::list_profile_wallet_ledger as _,
|
||||
@@ -764,6 +776,76 @@ impl SpacetimeClient {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_custom_world_works(
|
||||
&self,
|
||||
owner_user_id: String,
|
||||
) -> Result<Vec<CustomWorldWorkSummaryRecord>, SpacetimeClientError> {
|
||||
let procedure_input = BindingCustomWorldWorksListInput { owner_user_id };
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.list_custom_world_works_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_custom_world_works_list_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_custom_world_agent_card_detail(
|
||||
&self,
|
||||
session_id: String,
|
||||
owner_user_id: String,
|
||||
card_id: String,
|
||||
) -> Result<CustomWorldDraftCardDetailRecord, SpacetimeClientError> {
|
||||
let procedure_input = BindingCustomWorldAgentCardDetailGetInput {
|
||||
session_id,
|
||||
owner_user_id,
|
||||
card_id,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.get_custom_world_agent_card_detail_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_custom_world_draft_card_detail_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn execute_custom_world_agent_action(
|
||||
&self,
|
||||
input: CustomWorldAgentActionExecuteRecordInput,
|
||||
) -> Result<CustomWorldAgentActionExecuteRecord, SpacetimeClientError> {
|
||||
let procedure_input = BindingCustomWorldAgentActionExecuteInput {
|
||||
session_id: input.session_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
operation_id: input.operation_id,
|
||||
action: input.action,
|
||||
payload_json: input.payload_json,
|
||||
submitted_at_micros: input.submitted_at_micros,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.execute_custom_world_agent_action_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_custom_world_agent_action_execute_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn submit_custom_world_agent_message(
|
||||
&self,
|
||||
input: CustomWorldAgentMessageSubmitRecordInput,
|
||||
@@ -2259,6 +2341,66 @@ fn map_custom_world_agent_operation_procedure_result(
|
||||
Ok(map_custom_world_agent_operation_snapshot(operation))
|
||||
}
|
||||
|
||||
fn map_custom_world_works_list_result(
|
||||
result: BindingCustomWorldWorksListResult,
|
||||
) -> Result<Vec<CustomWorldWorkSummaryRecord>, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
result
|
||||
.items
|
||||
.into_iter()
|
||||
.map(map_custom_world_work_summary_snapshot)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn map_custom_world_draft_card_detail_result(
|
||||
result: BindingCustomWorldDraftCardDetailResult,
|
||||
) -> Result<CustomWorldDraftCardDetailRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let card = result.card.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure(
|
||||
"SpacetimeDB procedure 未返回 custom world card detail 快照".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
map_custom_world_draft_card_detail_snapshot(card)
|
||||
}
|
||||
|
||||
fn map_custom_world_agent_action_execute_result(
|
||||
result: BindingCustomWorldAgentActionExecuteResult,
|
||||
) -> Result<CustomWorldAgentActionExecuteRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let operation = result.operation.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure(
|
||||
"SpacetimeDB procedure 未返回 custom world action operation 快照".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(CustomWorldAgentActionExecuteRecord {
|
||||
operation: map_custom_world_agent_operation_snapshot(operation),
|
||||
})
|
||||
}
|
||||
|
||||
fn map_story_session_procedure_result(
|
||||
result: BindingStorySessionProcedureResult,
|
||||
) -> Result<StorySessionResultRecord, SpacetimeClientError> {
|
||||
@@ -2647,6 +2789,40 @@ fn map_custom_world_published_profile_compile_snapshot(
|
||||
})
|
||||
}
|
||||
|
||||
fn map_custom_world_work_summary_snapshot(
|
||||
snapshot: BindingCustomWorldWorkSummarySnapshot,
|
||||
) -> Result<CustomWorldWorkSummaryRecord, SpacetimeClientError> {
|
||||
Ok(CustomWorldWorkSummaryRecord {
|
||||
work_id: snapshot.work_id,
|
||||
source_type: snapshot.source_type,
|
||||
status: snapshot.status,
|
||||
title: snapshot.title,
|
||||
subtitle: snapshot.subtitle,
|
||||
summary: snapshot.summary,
|
||||
cover_image_src: snapshot.cover_image_src,
|
||||
cover_render_mode: snapshot.cover_render_mode,
|
||||
cover_character_image_srcs: parse_json_string_array(
|
||||
&snapshot.cover_character_image_srcs_json,
|
||||
"custom world work cover_character_image_srcs_json",
|
||||
)?,
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
published_at: snapshot.published_at_micros.map(format_timestamp_micros),
|
||||
stage: snapshot.stage.map(map_rpg_agent_stage),
|
||||
stage_label: snapshot.stage_label,
|
||||
playable_npc_count: snapshot.playable_npc_count,
|
||||
landmark_count: snapshot.landmark_count,
|
||||
role_visual_ready_count: snapshot.role_visual_ready_count,
|
||||
role_animation_ready_count: snapshot.role_animation_ready_count,
|
||||
role_asset_summary_label: snapshot.role_asset_summary_label,
|
||||
session_id: snapshot.session_id,
|
||||
profile_id: snapshot.profile_id,
|
||||
can_resume: snapshot.can_resume,
|
||||
can_enter_world: snapshot.can_enter_world,
|
||||
blocker_count: snapshot.blocker_count,
|
||||
publish_ready: snapshot.publish_ready,
|
||||
})
|
||||
}
|
||||
|
||||
fn map_custom_world_agent_session_snapshot(
|
||||
snapshot: BindingCustomWorldAgentSessionSnapshot,
|
||||
) -> Result<CustomWorldAgentSessionRecord, SpacetimeClientError> {
|
||||
@@ -2706,6 +2882,12 @@ fn map_custom_world_agent_session_snapshot(
|
||||
.into_iter()
|
||||
.map(map_custom_world_checkpoint_record)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let supported_actions = parse_supported_actions_json(&snapshot.supported_actions_json)?;
|
||||
let publish_gate = snapshot
|
||||
.publish_gate_json
|
||||
.as_deref()
|
||||
.map(parse_custom_world_publish_gate_record)
|
||||
.transpose()?;
|
||||
|
||||
Ok(CustomWorldAgentSessionRecord {
|
||||
session_id: snapshot.session_id,
|
||||
@@ -2736,12 +2918,8 @@ fn map_custom_world_agent_session_snapshot(
|
||||
quality_findings,
|
||||
asset_coverage,
|
||||
checkpoints,
|
||||
supported_actions: build_minimal_custom_world_supported_actions(
|
||||
snapshot.stage,
|
||||
snapshot.progress_percent,
|
||||
snapshot.result_preview_json.is_some(),
|
||||
snapshot.checkpoints_json.as_str(),
|
||||
),
|
||||
supported_actions,
|
||||
publish_gate,
|
||||
result_preview: snapshot
|
||||
.result_preview_json
|
||||
.as_deref()
|
||||
@@ -2797,9 +2975,57 @@ fn map_custom_world_draft_card_snapshot(
|
||||
.asset_status
|
||||
.map(format_custom_world_role_asset_status_back),
|
||||
asset_status_label: snapshot.asset_status_label,
|
||||
detail_payload: snapshot
|
||||
.detail_payload_json
|
||||
.as_deref()
|
||||
.map(|value| parse_json_value(value, "custom world draft_card detail_payload_json"))
|
||||
.transpose()?,
|
||||
})
|
||||
}
|
||||
|
||||
fn map_custom_world_draft_card_detail_snapshot(
|
||||
snapshot: BindingCustomWorldDraftCardDetailSnapshot,
|
||||
) -> Result<CustomWorldDraftCardDetailRecord, SpacetimeClientError> {
|
||||
Ok(CustomWorldDraftCardDetailRecord {
|
||||
card_id: snapshot.card_id,
|
||||
kind: format_rpg_agent_draft_card_kind(snapshot.kind).to_string(),
|
||||
title: snapshot.title,
|
||||
sections: snapshot
|
||||
.sections
|
||||
.into_iter()
|
||||
.map(map_custom_world_draft_card_detail_section_snapshot)
|
||||
.collect(),
|
||||
linked_ids: parse_json_string_array(
|
||||
&snapshot.linked_ids_json,
|
||||
"custom world card detail linked_ids_json",
|
||||
)?,
|
||||
locked: snapshot.locked,
|
||||
editable: snapshot.editable,
|
||||
editable_section_ids: parse_json_string_array(
|
||||
&snapshot.editable_section_ids_json,
|
||||
"custom world card detail editable_section_ids_json",
|
||||
)?,
|
||||
warning_messages: parse_json_string_array(
|
||||
&snapshot.warning_messages_json,
|
||||
"custom world card detail warning_messages_json",
|
||||
)?,
|
||||
asset_status: snapshot
|
||||
.asset_status
|
||||
.map(format_custom_world_role_asset_status_back),
|
||||
asset_status_label: snapshot.asset_status_label,
|
||||
})
|
||||
}
|
||||
|
||||
fn map_custom_world_draft_card_detail_section_snapshot(
|
||||
snapshot: BindingCustomWorldDraftCardDetailSectionSnapshot,
|
||||
) -> CustomWorldDraftCardDetailSectionRecord {
|
||||
CustomWorldDraftCardDetailSectionRecord {
|
||||
section_id: snapshot.section_id,
|
||||
label: snapshot.label,
|
||||
value: snapshot.value,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_story_session_snapshot(snapshot: BindingStorySessionSnapshot) -> StorySessionRecord {
|
||||
StorySessionRecord {
|
||||
story_session_id: snapshot.story_session_id,
|
||||
@@ -3607,45 +3833,159 @@ fn map_custom_world_checkpoint_record(
|
||||
})
|
||||
}
|
||||
|
||||
fn build_minimal_custom_world_supported_actions(
|
||||
stage: crate::module_bindings::RpgAgentStage,
|
||||
progress_percent: u32,
|
||||
has_result_preview: bool,
|
||||
checkpoints_json: &str,
|
||||
) -> Vec<CustomWorldSupportedActionRecord> {
|
||||
let has_checkpoint = parse_json_array(checkpoints_json, "custom world agent checkpoints_json")
|
||||
.map(|entries| !entries.is_empty())
|
||||
.unwrap_or(false);
|
||||
let refining_ready = matches!(
|
||||
stage,
|
||||
crate::module_bindings::RpgAgentStage::FoundationReview
|
||||
| crate::module_bindings::RpgAgentStage::ObjectRefining
|
||||
| crate::module_bindings::RpgAgentStage::VisualRefining
|
||||
| crate::module_bindings::RpgAgentStage::LongTailReview
|
||||
| crate::module_bindings::RpgAgentStage::ReadyToPublish
|
||||
| crate::module_bindings::RpgAgentStage::Published
|
||||
);
|
||||
fn parse_supported_actions_json(
|
||||
value: &str,
|
||||
) -> Result<Vec<CustomWorldSupportedActionRecord>, SpacetimeClientError> {
|
||||
parse_json_array(value, "custom world agent supported_actions_json")?
|
||||
.into_iter()
|
||||
.map(|entry| {
|
||||
let object = entry.as_object().ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world supported action 必须是 JSON object".to_string(),
|
||||
)
|
||||
})?;
|
||||
let action = object
|
||||
.get("action")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world supported action.action 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
let enabled = object
|
||||
.get("enabled")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world supported action.enabled 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
vec![
|
||||
CustomWorldSupportedActionRecord {
|
||||
action: "draft_foundation".to_string(),
|
||||
enabled: progress_percent >= 100,
|
||||
reason: (progress_percent < 100)
|
||||
.then(|| "draft_foundation requires progressPercent >= 100".to_string()),
|
||||
},
|
||||
CustomWorldSupportedActionRecord {
|
||||
action: "publish_world".to_string(),
|
||||
enabled: refining_ready && has_result_preview,
|
||||
reason: (!refining_ready || !has_result_preview)
|
||||
.then(|| "publish_world requires refined draft and resultPreview".to_string()),
|
||||
},
|
||||
CustomWorldSupportedActionRecord {
|
||||
action: "revert_checkpoint".to_string(),
|
||||
enabled: has_checkpoint,
|
||||
reason: (!has_checkpoint)
|
||||
.then(|| "revert_checkpoint requires at least one checkpoint".to_string()),
|
||||
},
|
||||
]
|
||||
Ok(CustomWorldSupportedActionRecord {
|
||||
action: action.to_string(),
|
||||
enabled,
|
||||
reason: object
|
||||
.get("reason")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(ToOwned::to_owned),
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn parse_custom_world_publish_gate_record(
|
||||
value: &str,
|
||||
) -> Result<CustomWorldPublishGateRecord, SpacetimeClientError> {
|
||||
let object = parse_json_value(value, "custom world publish_gate_json")?
|
||||
.as_object()
|
||||
.cloned()
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish_gate_json 必须是 JSON object".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let profile_id = object
|
||||
.get("profileId")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish_gate.profileId 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
let blockers = object
|
||||
.get("blockers")
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish_gate.blockers 缺失".to_string(),
|
||||
)
|
||||
})?
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|entry| {
|
||||
let object = entry.as_object().ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish gate blocker 必须是 JSON object".to_string(),
|
||||
)
|
||||
})?;
|
||||
let id = object
|
||||
.get("id")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish gate blocker.id 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
let code = object
|
||||
.get("code")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish gate blocker.code 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
let message = object
|
||||
.get("message")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish gate blocker.message 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(CustomWorldResultPreviewBlockerRecord {
|
||||
id: id.to_string(),
|
||||
code: code.to_string(),
|
||||
message: message.to_string(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let blocker_count = object
|
||||
.get("blockerCount")
|
||||
.and_then(serde_json::Value::as_u64)
|
||||
.and_then(|value| u32::try_from(value).ok())
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish_gate.blockerCount 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
let publish_ready = object
|
||||
.get("publishReady")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish_gate.publishReady 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
let can_enter_world = object
|
||||
.get("canEnterWorld")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.ok_or_else(|| {
|
||||
SpacetimeClientError::Runtime(
|
||||
"custom world publish_gate.canEnterWorld 缺失".to_string(),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(CustomWorldPublishGateRecord {
|
||||
profile_id: profile_id.to_string(),
|
||||
blockers,
|
||||
blocker_count,
|
||||
publish_ready,
|
||||
can_enter_world,
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -3785,6 +4125,7 @@ pub struct CustomWorldDraftCardRecord {
|
||||
pub warning_count: u32,
|
||||
pub asset_status: Option<String>,
|
||||
pub asset_status_label: Option<String>,
|
||||
pub detail_payload: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@@ -3804,6 +4145,72 @@ pub struct CustomWorldCheckpointRecord {
|
||||
// 兼容并行 custom world facade 中仍在使用的旧命名,避免本轮 module-npc 收口被无关改动阻塞。
|
||||
pub type CustomWorldAgentCheckpointRecord = CustomWorldCheckpointRecord;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CustomWorldResultPreviewBlockerRecord {
|
||||
pub id: String,
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CustomWorldPublishGateRecord {
|
||||
pub profile_id: String,
|
||||
pub blockers: Vec<CustomWorldResultPreviewBlockerRecord>,
|
||||
pub blocker_count: u32,
|
||||
pub publish_ready: bool,
|
||||
pub can_enter_world: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CustomWorldWorkSummaryRecord {
|
||||
pub work_id: String,
|
||||
pub source_type: String,
|
||||
pub status: String,
|
||||
pub title: String,
|
||||
pub subtitle: String,
|
||||
pub summary: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub cover_render_mode: Option<String>,
|
||||
pub cover_character_image_srcs: Vec<String>,
|
||||
pub updated_at: String,
|
||||
pub published_at: Option<String>,
|
||||
pub stage: Option<String>,
|
||||
pub stage_label: Option<String>,
|
||||
pub playable_npc_count: u32,
|
||||
pub landmark_count: u32,
|
||||
pub role_visual_ready_count: Option<u32>,
|
||||
pub role_animation_ready_count: Option<u32>,
|
||||
pub role_asset_summary_label: Option<String>,
|
||||
pub session_id: Option<String>,
|
||||
pub profile_id: Option<String>,
|
||||
pub can_resume: bool,
|
||||
pub can_enter_world: bool,
|
||||
pub blocker_count: u32,
|
||||
pub publish_ready: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CustomWorldDraftCardDetailSectionRecord {
|
||||
pub section_id: String,
|
||||
pub label: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CustomWorldDraftCardDetailRecord {
|
||||
pub card_id: String,
|
||||
pub kind: String,
|
||||
pub title: String,
|
||||
pub sections: Vec<CustomWorldDraftCardDetailSectionRecord>,
|
||||
pub linked_ids: Vec<String>,
|
||||
pub locked: bool,
|
||||
pub editable: bool,
|
||||
pub editable_section_ids: Vec<String>,
|
||||
pub warning_messages: Vec<String>,
|
||||
pub asset_status: Option<String>,
|
||||
pub asset_status_label: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CustomWorldAgentSessionRecord {
|
||||
pub session_id: String,
|
||||
@@ -3827,6 +4234,7 @@ pub struct CustomWorldAgentSessionRecord {
|
||||
pub asset_coverage: serde_json::Value,
|
||||
pub checkpoints: Vec<CustomWorldCheckpointRecord>,
|
||||
pub supported_actions: Vec<CustomWorldSupportedActionRecord>,
|
||||
pub publish_gate: Option<CustomWorldPublishGateRecord>,
|
||||
pub result_preview: Option<serde_json::Value>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
@@ -3892,6 +4300,21 @@ pub struct CustomWorldAgentMessageSubmitRecordInput {
|
||||
pub submitted_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CustomWorldAgentActionExecuteRecordInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub operation_id: String,
|
||||
pub action: String,
|
||||
pub payload_json: Option<String>,
|
||||
pub submitted_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CustomWorldAgentActionExecuteRecord {
|
||||
pub operation: CustomWorldAgentOperationRecord,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ResolveNpcBattleInteractionInput {
|
||||
pub npc_interaction: DomainResolveNpcInteractionInput,
|
||||
|
||||
Reference in New Issue
Block a user