1
This commit is contained in:
@@ -10,6 +10,7 @@ use axum::{
|
||||
use platform_llm::{LlmMessage, LlmTextRequest};
|
||||
use serde::Deserialize;
|
||||
use serde_json::{Value, json};
|
||||
use shared_contracts::runtime_story::RuntimeStorySnapshotPayload;
|
||||
use std::convert::Infallible;
|
||||
|
||||
use crate::{
|
||||
@@ -27,6 +28,8 @@ pub struct RuntimeCharacterChatRequest {
|
||||
#[serde(default)]
|
||||
session_id: Option<String>,
|
||||
#[serde(default)]
|
||||
snapshot: Option<RuntimeStorySnapshotPayload>,
|
||||
#[serde(default)]
|
||||
world_type: String,
|
||||
#[serde(default)]
|
||||
player_character: Value,
|
||||
@@ -54,6 +57,8 @@ pub struct RuntimeNpcDialogueRequest {
|
||||
#[serde(default)]
|
||||
session_id: Option<String>,
|
||||
#[serde(default)]
|
||||
snapshot: Option<RuntimeStorySnapshotPayload>,
|
||||
#[serde(default)]
|
||||
world_type: String,
|
||||
#[serde(default)]
|
||||
character: Value,
|
||||
@@ -77,6 +82,8 @@ pub struct RuntimeNpcRecruitDialogueRequest {
|
||||
#[serde(default)]
|
||||
session_id: Option<String>,
|
||||
#[serde(default)]
|
||||
snapshot: Option<RuntimeStorySnapshotPayload>,
|
||||
#[serde(default)]
|
||||
world_type: String,
|
||||
#[serde(default)]
|
||||
character: Value,
|
||||
@@ -346,6 +353,7 @@ async fn hydrate_character_chat_request_from_session(
|
||||
request_context,
|
||||
user_id,
|
||||
payload.session_id.as_deref(),
|
||||
payload.snapshot.as_ref(),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
@@ -382,6 +390,7 @@ async fn hydrate_npc_dialogue_request_from_session(
|
||||
request_context,
|
||||
user_id,
|
||||
payload.session_id.as_deref(),
|
||||
payload.snapshot.as_ref(),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
@@ -430,6 +439,7 @@ async fn hydrate_npc_recruit_request_from_session(
|
||||
request_context,
|
||||
user_id,
|
||||
payload.session_id.as_deref(),
|
||||
payload.snapshot.as_ref(),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
@@ -472,11 +482,19 @@ async fn resolve_runtime_chat_game_state(
|
||||
request_context: &RequestContext,
|
||||
user_id: String,
|
||||
session_id: Option<&str>,
|
||||
snapshot: Option<&RuntimeStorySnapshotPayload>,
|
||||
) -> Result<Option<Value>, Response> {
|
||||
let Some(session_id) = session_id.and_then(normalize_required_string) else {
|
||||
// 中文注释:未携带 sessionId 的旧调用仅保留兼容,后续正式运行态应全部走后端快照。
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
if let Some(game_state) =
|
||||
resolve_request_snapshot_game_state(request_context, session_id.as_str(), snapshot)?
|
||||
{
|
||||
return Ok(Some(game_state));
|
||||
}
|
||||
|
||||
let record = state
|
||||
.get_runtime_snapshot_record(user_id)
|
||||
.await
|
||||
@@ -516,6 +534,43 @@ async fn resolve_runtime_chat_game_state(
|
||||
Ok(Some(game_state))
|
||||
}
|
||||
|
||||
fn resolve_request_snapshot_game_state(
|
||||
request_context: &RequestContext,
|
||||
session_id: &str,
|
||||
snapshot: Option<&RuntimeStorySnapshotPayload>,
|
||||
) -> Result<Option<Value>, Response> {
|
||||
let Some(snapshot) = snapshot else {
|
||||
return Ok(None);
|
||||
};
|
||||
if !snapshot.game_state.is_object() {
|
||||
return Err(runtime_plain_chat_error_response(
|
||||
request_context,
|
||||
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": "runtime-chat",
|
||||
"field": "snapshot.gameState",
|
||||
"message": "snapshot.gameState 必须是 JSON object",
|
||||
})),
|
||||
));
|
||||
}
|
||||
|
||||
let snapshot_session_id =
|
||||
read_runtime_session_id(&snapshot.game_state).unwrap_or_else(|| session_id.to_string());
|
||||
if snapshot_session_id != session_id {
|
||||
return Err(runtime_plain_chat_error_response(
|
||||
request_context,
|
||||
AppError::from_status(StatusCode::CONFLICT).with_details(json!({
|
||||
"provider": "runtime-chat",
|
||||
"message": "请求的运行时会话与服务端快照不一致,请重新进入游戏",
|
||||
"sessionId": session_id,
|
||||
"snapshotSessionId": snapshot_session_id,
|
||||
})),
|
||||
));
|
||||
}
|
||||
|
||||
// 中文注释:临时运行态聊天只读取请求 snapshot 构造上下文,不把它写回 runtime_snapshot。
|
||||
Ok(Some(snapshot.game_state.clone()))
|
||||
}
|
||||
|
||||
async fn request_runtime_plain_text(
|
||||
state: &AppState,
|
||||
system_prompt: &'static str,
|
||||
|
||||
Reference in New Issue
Block a user