1
This commit is contained in:
@@ -30,15 +30,16 @@ use shared_contracts::{
|
||||
SwapPuzzlePiecesRequest,
|
||||
},
|
||||
puzzle_works::{
|
||||
PuzzleWorkDetailResponse, PuzzleWorkMutationResponse, PuzzleWorkProfileResponse,
|
||||
PuzzleWorkSummaryResponse, PuzzleWorksResponse, PutPuzzleWorkRequest,
|
||||
PutPuzzleWorkRequest, PuzzleWorkDetailResponse, PuzzleWorkMutationResponse,
|
||||
PuzzleWorkProfileResponse, PuzzleWorkSummaryResponse, PuzzleWorksResponse,
|
||||
},
|
||||
};
|
||||
use shared_kernel::build_prefixed_uuid_id;
|
||||
use spacetime_client::{
|
||||
PuzzleAgentMessageRecord, PuzzleAgentMessageSubmitRecordInput, PuzzleAgentSessionCreateRecordInput,
|
||||
PuzzleAgentSessionRecord, PuzzleAgentSuggestedActionRecord, PuzzleAnchorItemRecord,
|
||||
PuzzleAnchorPackRecord, PuzzleCreatorIntentRecord, PuzzleGeneratedImageCandidateRecord,
|
||||
PuzzleAgentMessageRecord, PuzzleAgentMessageSubmitRecordInput,
|
||||
PuzzleAgentSessionCreateRecordInput, PuzzleAgentSessionRecord,
|
||||
PuzzleAgentSuggestedActionRecord, PuzzleAnchorItemRecord, PuzzleAnchorPackRecord,
|
||||
PuzzleCreatorIntentRecord, PuzzleGeneratedImageCandidateRecord,
|
||||
PuzzleGeneratedImagesSaveRecordInput, PuzzlePublishRecordInput, PuzzleResultDraftRecord,
|
||||
PuzzleResultPreviewBlockerRecord, PuzzleResultPreviewFindingRecord, PuzzleResultPreviewRecord,
|
||||
PuzzleRunDragRecordInput, PuzzleRunRecord, PuzzleRunStartRecordInput, PuzzleRunSwapRecordInput,
|
||||
@@ -47,11 +48,8 @@ use spacetime_client::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
api_response::json_success_body,
|
||||
auth::AuthenticatedAccessToken,
|
||||
http_error::AppError,
|
||||
request_context::RequestContext,
|
||||
state::AppState,
|
||||
api_response::json_success_body, auth::AuthenticatedAccessToken, http_error::AppError,
|
||||
request_context::RequestContext, state::AppState,
|
||||
};
|
||||
|
||||
const PUZZLE_AGENT_API_BASE_PROVIDER: &str = "puzzle-agent";
|
||||
@@ -110,14 +108,16 @@ pub async fn get_puzzle_agent_session(
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
ensure_non_empty(&request_context, PUZZLE_AGENT_API_BASE_PROVIDER, &session_id, "sessionId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
&session_id,
|
||||
"sessionId",
|
||||
)?;
|
||||
|
||||
let session = state
|
||||
.spacetime_client()
|
||||
.get_puzzle_agent_session(
|
||||
session_id,
|
||||
authenticated.claims().user_id().to_string(),
|
||||
)
|
||||
.get_puzzle_agent_session(session_id, authenticated.claims().user_id().to_string())
|
||||
.await
|
||||
.map_err(|error| {
|
||||
puzzle_error_response(
|
||||
@@ -152,7 +152,12 @@ pub async fn submit_puzzle_agent_message(
|
||||
})),
|
||||
)
|
||||
})?;
|
||||
ensure_non_empty(&request_context, PUZZLE_AGENT_API_BASE_PROVIDER, &session_id, "sessionId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
&session_id,
|
||||
"sessionId",
|
||||
)?;
|
||||
|
||||
let client_message_id = payload.client_message_id.trim().to_string();
|
||||
let message_text = payload.text.trim().to_string();
|
||||
@@ -207,7 +212,12 @@ pub async fn stream_puzzle_agent_message(
|
||||
})),
|
||||
)
|
||||
})?;
|
||||
ensure_non_empty(&request_context, PUZZLE_AGENT_API_BASE_PROVIDER, &session_id, "sessionId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
&session_id,
|
||||
"sessionId",
|
||||
)?;
|
||||
|
||||
let session = state
|
||||
.spacetime_client()
|
||||
@@ -245,7 +255,12 @@ pub async fn stream_puzzle_agent_message(
|
||||
"session",
|
||||
&json!({ "session": session_response }),
|
||||
)?;
|
||||
append_sse_event(&request_context, &mut sse_body, "done", &json!({ "ok": true }))?;
|
||||
append_sse_event(
|
||||
&request_context,
|
||||
&mut sse_body,
|
||||
"done",
|
||||
&json!({ "ok": true }),
|
||||
)?;
|
||||
Ok(build_event_stream_response(sse_body))
|
||||
}
|
||||
|
||||
@@ -266,7 +281,12 @@ pub async fn execute_puzzle_agent_action(
|
||||
})),
|
||||
)
|
||||
})?;
|
||||
ensure_non_empty(&request_context, PUZZLE_AGENT_API_BASE_PROVIDER, &session_id, "sessionId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_AGENT_API_BASE_PROVIDER,
|
||||
&session_id,
|
||||
"sessionId",
|
||||
)?;
|
||||
|
||||
let owner_user_id = authenticated.claims().user_id().to_string();
|
||||
let now = current_utc_micros();
|
||||
@@ -327,11 +347,11 @@ pub async fn execute_puzzle_agent_action(
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.map_err(|error| {
|
||||
SpacetimeClientError::Runtime(format!(
|
||||
"拼图候选图序列化失败:{error}"
|
||||
))
|
||||
});
|
||||
.map_err(|error| {
|
||||
SpacetimeClientError::Runtime(format!(
|
||||
"拼图候选图序列化失败:{error}"
|
||||
))
|
||||
});
|
||||
match candidates_json {
|
||||
Ok(candidates_json) => {
|
||||
state
|
||||
@@ -497,7 +517,12 @@ pub async fn get_puzzle_work_detail(
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(_authenticated): Extension<AuthenticatedAccessToken>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
ensure_non_empty(&request_context, PUZZLE_WORKS_PROVIDER, &profile_id, "profileId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_WORKS_PROVIDER,
|
||||
&profile_id,
|
||||
"profileId",
|
||||
)?;
|
||||
|
||||
let item = state
|
||||
.spacetime_client()
|
||||
@@ -536,7 +561,12 @@ pub async fn put_puzzle_work(
|
||||
})),
|
||||
)
|
||||
})?;
|
||||
ensure_non_empty(&request_context, PUZZLE_WORKS_PROVIDER, &profile_id, "profileId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_WORKS_PROVIDER,
|
||||
&profile_id,
|
||||
"profileId",
|
||||
)?;
|
||||
|
||||
let item = state
|
||||
.spacetime_client()
|
||||
@@ -599,7 +629,12 @@ pub async fn get_puzzle_gallery_detail(
|
||||
AxumPath(profile_id): AxumPath<String>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
ensure_non_empty(&request_context, PUZZLE_GALLERY_PROVIDER, &profile_id, "profileId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_GALLERY_PROVIDER,
|
||||
&profile_id,
|
||||
"profileId",
|
||||
)?;
|
||||
|
||||
let item = state
|
||||
.spacetime_client()
|
||||
@@ -637,7 +672,12 @@ pub async fn start_puzzle_run(
|
||||
})),
|
||||
)
|
||||
})?;
|
||||
ensure_non_empty(&request_context, PUZZLE_RUNTIME_PROVIDER, &payload.profile_id, "profileId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_RUNTIME_PROVIDER,
|
||||
&payload.profile_id,
|
||||
"profileId",
|
||||
)?;
|
||||
|
||||
let run = state
|
||||
.spacetime_client()
|
||||
@@ -767,7 +807,12 @@ pub async fn drag_puzzle_piece_or_group(
|
||||
)
|
||||
})?;
|
||||
ensure_non_empty(&request_context, PUZZLE_RUNTIME_PROVIDER, &run_id, "runId")?;
|
||||
ensure_non_empty(&request_context, PUZZLE_RUNTIME_PROVIDER, &payload.piece_id, "pieceId")?;
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_RUNTIME_PROVIDER,
|
||||
&payload.piece_id,
|
||||
"pieceId",
|
||||
)?;
|
||||
|
||||
let run = state
|
||||
.spacetime_client()
|
||||
@@ -850,12 +895,16 @@ fn map_puzzle_agent_session_response(
|
||||
.into_iter()
|
||||
.map(map_puzzle_suggested_action_response)
|
||||
.collect(),
|
||||
result_preview: session.result_preview.map(map_puzzle_result_preview_response),
|
||||
result_preview: session
|
||||
.result_preview
|
||||
.map(map_puzzle_result_preview_response),
|
||||
updated_at: session.updated_at,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_puzzle_anchor_pack_response(anchor_pack: PuzzleAnchorPackRecord) -> PuzzleAnchorPackResponse {
|
||||
fn map_puzzle_anchor_pack_response(
|
||||
anchor_pack: PuzzleAnchorPackRecord,
|
||||
) -> PuzzleAnchorPackResponse {
|
||||
PuzzleAnchorPackResponse {
|
||||
theme_promise: map_puzzle_anchor_item_response(anchor_pack.theme_promise),
|
||||
visual_subject: map_puzzle_anchor_item_response(anchor_pack.visual_subject),
|
||||
@@ -1098,8 +1147,7 @@ fn resolve_author_display_name(
|
||||
|
||||
fn build_puzzle_welcome_text(seed_text: &str) -> String {
|
||||
if seed_text.trim().is_empty() {
|
||||
return "先告诉我你想做一张什么样的拼图图像,我会帮你收束成可发布的题材锚点。"
|
||||
.to_string();
|
||||
return "先告诉我你想做一张什么样的拼图图像,我会帮你收束成可发布的题材锚点。".to_string();
|
||||
}
|
||||
|
||||
"我先接住你的画面灵感,再一起把它收束成正式拼图关卡。".to_string()
|
||||
@@ -1124,11 +1172,7 @@ fn ensure_non_empty(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn puzzle_bad_request(
|
||||
request_context: &RequestContext,
|
||||
provider: &str,
|
||||
message: &str,
|
||||
) -> Response {
|
||||
fn puzzle_bad_request(request_context: &RequestContext, provider: &str, message: &str) -> Response {
|
||||
puzzle_error_response(
|
||||
request_context,
|
||||
provider,
|
||||
@@ -1279,7 +1323,11 @@ fn save_placeholder_puzzle_asset(
|
||||
fs::write(output_dir.join(&file_name), svg).map_err(io_error)?;
|
||||
|
||||
Ok(GeneratedPuzzleAssetResponse {
|
||||
image_src: format!("/{}/{}", relative_dir.to_string_lossy().replace('\\', "/"), file_name),
|
||||
image_src: format!(
|
||||
"/{}/{}",
|
||||
relative_dir.to_string_lossy().replace('\\', "/"),
|
||||
file_name
|
||||
),
|
||||
asset_id,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user