Merge branch 'master' of http://82.157.175.59:3000/GenarrativeAI/Genarrative
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-05-01 01:53:21 +08:00
2 changed files with 124 additions and 47 deletions

View File

@@ -76,11 +76,12 @@ use crate::{
logout::logout,
logout_all::logout_all,
match3d::{
click_match3d_item, create_match3d_agent_session, delete_match3d_work,
execute_match3d_agent_action, finish_match3d_time_up, get_match3d_agent_session,
get_match3d_run, get_match3d_work_detail, get_match3d_works, list_match3d_gallery,
publish_match3d_work, put_match3d_work, restart_match3d_run, start_match3d_run,
stop_match3d_run, stream_match3d_agent_message, submit_match3d_agent_message,
click_match3d_item, compile_match3d_agent_draft, create_match3d_agent_session,
delete_match3d_work, execute_match3d_agent_action, finish_match3d_time_up,
get_match3d_agent_session, get_match3d_run, get_match3d_work_detail, get_match3d_works,
list_match3d_gallery, publish_match3d_work, put_match3d_work, restart_match3d_run,
start_match3d_run, stop_match3d_run, stream_match3d_agent_message,
submit_match3d_agent_message,
},
password_entry::password_entry,
password_management::{change_password, reset_password},
@@ -749,7 +750,7 @@ pub fn build_router(state: AppState) -> Router {
)
.route(
"/api/creation/match3d/sessions/{session_id}/compile",
post(execute_match3d_agent_action).route_layer(middleware::from_fn_with_state(
post(compile_match3d_agent_draft).route_layer(middleware::from_fn_with_state(
state.clone(),
require_bearer_auth,
)),

View File

@@ -68,6 +68,19 @@ struct Match3DConfigJson {
difficulty: u32,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct CompileMatch3DDraftRequest {
#[serde(default)]
game_name: Option<String>,
#[serde(default)]
summary: Option<String>,
#[serde(default)]
tags: Option<Vec<String>>,
#[serde(default)]
cover_image_src: Option<String>,
}
pub async fn create_match3d_agent_session(
State(state): State<AppState>,
Extension(request_context): Extension<RequestContext>,
@@ -245,47 +258,59 @@ pub async fn execute_match3d_agent_action(
));
}
let owner_user_id = authenticated.claims().user_id().to_string();
let session = state
.spacetime_client()
.get_match3d_agent_session(session_id.clone(), owner_user_id.clone())
.await
.map_err(|error| {
match3d_error_response(
&request_context,
MATCH3D_AGENT_PROVIDER,
map_match3d_client_error(error),
)
})?;
let config = resolve_config_or_default(session.config.as_ref());
let tags_json = payload
.tags
.as_ref()
.map(|tags| serde_json::to_string(&normalize_tags(tags.clone())).unwrap_or_default());
let session = state
.spacetime_client()
.compile_match3d_draft(Match3DCompileDraftRecordInput {
session_id,
owner_user_id,
profile_id: build_prefixed_uuid_id(MATCH3D_PROFILE_ID_PREFIX),
author_display_name: resolve_author_display_name(&state, &authenticated),
game_name: payload
.game_name
.or_else(|| Some(format!("{}抓大鹅", config.theme_text))),
summary_text: payload.summary,
tags_json,
cover_image_src: payload.cover_image_src,
cover_asset_id: None,
compiled_at_micros: current_utc_micros(),
})
.await
.map_err(|error| {
match3d_error_response(
&request_context,
MATCH3D_AGENT_PROVIDER,
map_match3d_client_error(error),
)
})?;
let session = compile_match3d_draft_for_session(
&state,
&request_context,
&authenticated,
session_id,
payload.game_name,
payload.summary,
payload.tags,
payload.cover_image_src,
)
.await?;
Ok(json_success_body(
Some(&request_context),
Match3DAgentActionResponse {
session: map_match3d_agent_session_response(session),
},
))
}
pub async fn compile_match3d_agent_draft(
State(state): State<AppState>,
Path(session_id): Path<String>,
Extension(request_context): Extension<RequestContext>,
Extension(authenticated): Extension<AuthenticatedAccessToken>,
payload: Result<Json<CompileMatch3DDraftRequest>, JsonRejection>,
) -> Result<Json<Value>, Response> {
let payload = payload
.map(|Json(payload)| payload)
.unwrap_or(CompileMatch3DDraftRequest {
game_name: None,
summary: None,
tags: None,
cover_image_src: None,
});
ensure_non_empty(
&request_context,
MATCH3D_AGENT_PROVIDER,
&session_id,
"sessionId",
)?;
let session = compile_match3d_draft_for_session(
&state,
&request_context,
&authenticated,
session_id,
payload.game_name,
payload.summary,
payload.tags,
payload.cover_image_src,
)
.await?;
Ok(json_success_body(
Some(&request_context),
@@ -818,6 +843,57 @@ async fn submit_and_finalize_match3d_message(
})
}
async fn compile_match3d_draft_for_session(
state: &AppState,
request_context: &RequestContext,
authenticated: &AuthenticatedAccessToken,
session_id: String,
game_name: Option<String>,
summary: Option<String>,
tags: Option<Vec<String>>,
cover_image_src: Option<String>,
) -> Result<Match3DAgentSessionRecord, Response> {
let owner_user_id = authenticated.claims().user_id().to_string();
let session = state
.spacetime_client()
.get_match3d_agent_session(session_id.clone(), owner_user_id.clone())
.await
.map_err(|error| {
match3d_error_response(
request_context,
MATCH3D_AGENT_PROVIDER,
map_match3d_client_error(error),
)
})?;
let config = resolve_config_or_default(session.config.as_ref());
let tags_json = tags
.as_ref()
.map(|tags| serde_json::to_string(&normalize_tags(tags.clone())).unwrap_or_default());
state
.spacetime_client()
.compile_match3d_draft(Match3DCompileDraftRecordInput {
session_id,
owner_user_id,
profile_id: build_prefixed_uuid_id(MATCH3D_PROFILE_ID_PREFIX),
author_display_name: resolve_author_display_name(state, authenticated),
game_name: game_name.or_else(|| Some(format!("{}抓大鹅", config.theme_text))),
summary_text: summary,
tags_json,
cover_image_src,
cover_asset_id: None,
compiled_at_micros: current_utc_micros(),
})
.await
.map_err(|error| {
match3d_error_response(
request_context,
MATCH3D_AGENT_PROVIDER,
map_match3d_client_error(error),
)
})
}
fn map_match3d_agent_session_response(
session: Match3DAgentSessionRecord,
) -> Match3DAgentSessionSnapshotResponse {