已发布作品可二次编辑
This commit is contained in:
@@ -434,13 +434,7 @@ pub async fn execute_big_fish_action(
|
||||
let now = current_utc_micros();
|
||||
let session = match payload.action.trim() {
|
||||
"big_fish_compile_draft" => {
|
||||
compile_big_fish_draft_with_all_assets(
|
||||
&state,
|
||||
session_id,
|
||||
owner_user_id,
|
||||
now,
|
||||
)
|
||||
.await
|
||||
compile_big_fish_draft_with_all_assets(&state, session_id, owner_user_id, now).await
|
||||
}
|
||||
"big_fish_generate_level_main_image" => {
|
||||
let asset_url = generate_big_fish_formal_asset(
|
||||
|
||||
@@ -2538,6 +2538,7 @@ fn map_custom_world_agent_operation_response(
|
||||
phase_detail: operation.phase_detail,
|
||||
progress: operation.progress,
|
||||
error: operation.error_message,
|
||||
started_at: Some(timestamp_micros_to_rfc3339(operation.started_at_micros)),
|
||||
updated_at: Some(timestamp_micros_to_rfc3339(operation.updated_at_micros)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2548,26 +2548,24 @@ mod tests {
|
||||
name: Some("礁石神殿".to_string()),
|
||||
description: Some("古老礁石上的半沉神殿。".to_string()),
|
||||
};
|
||||
let manual_prompt = build_custom_world_scene_image_prompt(
|
||||
SceneImagePromptParams {
|
||||
profile: SceneImagePromptProfile {
|
||||
name: profile_input.name.as_deref().unwrap_or_default(),
|
||||
subtitle: profile_input.subtitle.as_deref().unwrap_or_default(),
|
||||
tone: profile_input.tone.as_deref().unwrap_or_default(),
|
||||
player_goal: profile_input.player_goal.as_deref().unwrap_or_default(),
|
||||
summary: profile_input.summary.as_deref().unwrap_or_default(),
|
||||
setting_text: profile_input.setting_text.as_deref().unwrap_or_default(),
|
||||
},
|
||||
landmark: SceneImagePromptLandmark {
|
||||
name: landmark.name.as_deref().unwrap_or_default(),
|
||||
description: landmark.description.as_deref().unwrap_or_default(),
|
||||
},
|
||||
user_prompt,
|
||||
has_reference_image: false,
|
||||
fallback_landmark_name: Some("礁石神殿"),
|
||||
fallback_world_name: "雾海群岛",
|
||||
let manual_prompt = build_custom_world_scene_image_prompt(SceneImagePromptParams {
|
||||
profile: SceneImagePromptProfile {
|
||||
name: profile_input.name.as_deref().unwrap_or_default(),
|
||||
subtitle: profile_input.subtitle.as_deref().unwrap_or_default(),
|
||||
tone: profile_input.tone.as_deref().unwrap_or_default(),
|
||||
player_goal: profile_input.player_goal.as_deref().unwrap_or_default(),
|
||||
summary: profile_input.summary.as_deref().unwrap_or_default(),
|
||||
setting_text: profile_input.setting_text.as_deref().unwrap_or_default(),
|
||||
},
|
||||
);
|
||||
landmark: SceneImagePromptLandmark {
|
||||
name: landmark.name.as_deref().unwrap_or_default(),
|
||||
description: landmark.description.as_deref().unwrap_or_default(),
|
||||
},
|
||||
user_prompt,
|
||||
has_reference_image: false,
|
||||
fallback_landmark_name: Some("礁石神殿"),
|
||||
fallback_world_name: "雾海群岛",
|
||||
});
|
||||
|
||||
let normalized = normalize_scene_image_request(CustomWorldSceneImageRequest {
|
||||
profile_id: Some("profile_001".to_string()),
|
||||
|
||||
@@ -47,13 +47,14 @@ use spacetime_client::{
|
||||
PuzzleAgentMessageRecord, PuzzleAgentMessageSubmitRecordInput,
|
||||
PuzzleAgentSessionCreateRecordInput, PuzzleAgentSessionRecord,
|
||||
PuzzleAgentSuggestedActionRecord, PuzzleAnchorItemRecord, PuzzleAnchorPackRecord,
|
||||
PuzzleCreatorIntentRecord, PuzzleGeneratedImageCandidateRecord,
|
||||
PuzzleGeneratedImagesSaveRecordInput, PuzzlePublishRecordInput, PuzzleResultDraftRecord,
|
||||
PuzzleResultPreviewBlockerRecord, PuzzleResultPreviewFindingRecord, PuzzleResultPreviewRecord,
|
||||
PuzzleBoardRecord, PuzzleCellPositionRecord, PuzzleMergedGroupRecord, PuzzlePieceStateRecord,
|
||||
PuzzleRunDragRecordInput, PuzzleRunRecord, PuzzleRunStartRecordInput, PuzzleRunSwapRecordInput,
|
||||
PuzzleRuntimeLevelRecord, PuzzleSelectCoverImageRecordInput, PuzzleWorkProfileRecord,
|
||||
PuzzleWorkUpsertRecordInput, SpacetimeClientError,
|
||||
PuzzleBoardRecord, PuzzleCellPositionRecord, PuzzleCreatorIntentRecord,
|
||||
PuzzleGeneratedImageCandidateRecord, PuzzleGeneratedImagesSaveRecordInput,
|
||||
PuzzleMergedGroupRecord, PuzzlePieceStateRecord, PuzzlePublishRecordInput,
|
||||
PuzzleResultDraftRecord, PuzzleResultPreviewBlockerRecord, PuzzleResultPreviewFindingRecord,
|
||||
PuzzleResultPreviewRecord, PuzzleRunDragRecordInput, PuzzleRunRecord,
|
||||
PuzzleRunStartRecordInput, PuzzleRunSwapRecordInput, PuzzleRuntimeLevelRecord,
|
||||
PuzzleSelectCoverImageRecordInput, PuzzleWorkProfileRecord, PuzzleWorkUpsertRecordInput,
|
||||
SpacetimeClientError,
|
||||
};
|
||||
use std::convert::Infallible;
|
||||
use tokio::time::sleep;
|
||||
@@ -1639,7 +1640,10 @@ async fn generate_puzzle_image_candidates(
|
||||
let mut items = Vec::with_capacity(generated.images.len());
|
||||
|
||||
for (index, image) in generated.images.into_iter().enumerate() {
|
||||
let candidate_id = format!("{session_id}-candidate-{}", candidate_start_index + index + 1);
|
||||
let candidate_id = format!(
|
||||
"{session_id}-candidate-{}",
|
||||
candidate_start_index + index + 1
|
||||
);
|
||||
let asset = persist_puzzle_generated_asset(
|
||||
state,
|
||||
owner_user_id,
|
||||
@@ -1690,10 +1694,12 @@ async fn build_local_next_puzzle_run(
|
||||
}))
|
||||
})?;
|
||||
if current_level.status != "cleared" {
|
||||
return Err(AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": PUZZLE_RUNTIME_PROVIDER,
|
||||
"message": "current level is not cleared",
|
||||
})));
|
||||
return Err(
|
||||
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": PUZZLE_RUNTIME_PROVIDER,
|
||||
"message": "current level is not cleared",
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(gallery_item) = resolve_gallery_next_puzzle_work(state, &run).await? {
|
||||
@@ -1702,10 +1708,12 @@ async fn build_local_next_puzzle_run(
|
||||
|
||||
let source_session_id = payload.source_session_id.unwrap_or_default();
|
||||
if source_session_id.trim().is_empty() {
|
||||
return Err(AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": PUZZLE_RUNTIME_PROVIDER,
|
||||
"message": "sourceSessionId is required when gallery has no next puzzle work",
|
||||
})));
|
||||
return Err(
|
||||
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": PUZZLE_RUNTIME_PROVIDER,
|
||||
"message": "sourceSessionId is required when gallery has no next puzzle work",
|
||||
})),
|
||||
);
|
||||
}
|
||||
let session = state
|
||||
.spacetime_client()
|
||||
@@ -1767,14 +1775,23 @@ async fn build_local_next_puzzle_run(
|
||||
let candidate = updated_session
|
||||
.draft
|
||||
.as_ref()
|
||||
.and_then(|draft| draft.candidates.iter().find(|candidate| !candidate.image_src.is_empty()))
|
||||
.and_then(|draft| {
|
||||
draft
|
||||
.candidates
|
||||
.iter()
|
||||
.find(|candidate| !candidate.image_src.is_empty())
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": PUZZLE_RUNTIME_PROVIDER,
|
||||
"message": "现场生成后没有可用候选图",
|
||||
}))
|
||||
})?;
|
||||
Ok(build_next_run_from_candidate(run, &updated_session, candidate))
|
||||
Ok(build_next_run_from_candidate(
|
||||
run,
|
||||
&updated_session,
|
||||
candidate,
|
||||
))
|
||||
}
|
||||
|
||||
async fn resolve_gallery_next_puzzle_work(
|
||||
@@ -1788,7 +1805,10 @@ async fn resolve_gallery_next_puzzle_work(
|
||||
.map_err(map_puzzle_client_error)?;
|
||||
Ok(items.into_iter().find(|item| {
|
||||
item.publication_status == "published"
|
||||
&& item.cover_image_src.as_ref().is_some_and(|value| !value.is_empty())
|
||||
&& item
|
||||
.cover_image_src
|
||||
.as_ref()
|
||||
.is_some_and(|value| !value.is_empty())
|
||||
&& !run.played_profile_ids.contains(&item.profile_id)
|
||||
}))
|
||||
}
|
||||
@@ -1836,7 +1856,9 @@ fn build_next_run_from_candidate(
|
||||
.map(|draft| format!("{} · 候选 {}", draft.level_name, level_index))
|
||||
.unwrap_or_else(|| format!("候选拼图 {level_index}")),
|
||||
"当前草稿".to_string(),
|
||||
draft.map(|draft| draft.theme_tags.clone()).unwrap_or_default(),
|
||||
draft
|
||||
.map(|draft| draft.theme_tags.clone())
|
||||
.unwrap_or_default(),
|
||||
Some(candidate.image_src.clone()),
|
||||
)
|
||||
}
|
||||
@@ -1893,13 +1915,14 @@ fn build_local_puzzle_board(grid_size: u32) -> PuzzleBoardRecord {
|
||||
}
|
||||
let pieces = (0..total)
|
||||
.map(|index| {
|
||||
let current = positions
|
||||
.get(index as usize)
|
||||
.cloned()
|
||||
.unwrap_or(PuzzleCellPositionRecord {
|
||||
row: index / grid_size,
|
||||
col: index % grid_size,
|
||||
});
|
||||
let current =
|
||||
positions
|
||||
.get(index as usize)
|
||||
.cloned()
|
||||
.unwrap_or(PuzzleCellPositionRecord {
|
||||
row: index / grid_size,
|
||||
col: index % grid_size,
|
||||
});
|
||||
PuzzlePieceStateRecord {
|
||||
piece_id: format!("piece-{index}"),
|
||||
correct_row: index / grid_size,
|
||||
|
||||
Reference in New Issue
Block a user