refactor(api-server): narrow puzzle state surface
This commit is contained in:
@@ -141,6 +141,86 @@ impl FromRef<AppState> for BackpressureState {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PuzzleApiState {
|
||||
root_state: AppState,
|
||||
spacetime_client: SpacetimeClient,
|
||||
puzzle_gallery_cache: PuzzleGalleryCache,
|
||||
oss_client: Option<OssClient>,
|
||||
auth_user_service: AuthUserService,
|
||||
llm_client: Option<LlmClient>,
|
||||
creative_agent_gpt5_client: Option<LlmClient>,
|
||||
creation_agent_llm_web_search_enabled: bool,
|
||||
vector_engine_image_request_timeout_ms: u64,
|
||||
}
|
||||
|
||||
impl PuzzleApiState {
|
||||
pub fn root_state(&self) -> &AppState {
|
||||
&self.root_state
|
||||
}
|
||||
|
||||
pub fn spacetime_client(&self) -> &SpacetimeClient {
|
||||
&self.spacetime_client
|
||||
}
|
||||
|
||||
pub fn puzzle_gallery_cache(&self) -> &PuzzleGalleryCache {
|
||||
&self.puzzle_gallery_cache
|
||||
}
|
||||
|
||||
pub fn oss_client(&self) -> Option<&OssClient> {
|
||||
self.oss_client.as_ref()
|
||||
}
|
||||
|
||||
pub fn auth_user_service(&self) -> &AuthUserService {
|
||||
&self.auth_user_service
|
||||
}
|
||||
|
||||
pub fn llm_client(&self) -> Option<&LlmClient> {
|
||||
self.llm_client.as_ref()
|
||||
}
|
||||
|
||||
pub fn creative_agent_gpt5_client(&self) -> Option<&LlmClient> {
|
||||
self.creative_agent_gpt5_client.as_ref()
|
||||
}
|
||||
|
||||
pub fn creation_agent_llm_web_search_enabled(&self) -> bool {
|
||||
self.creation_agent_llm_web_search_enabled
|
||||
}
|
||||
|
||||
pub fn vector_engine_image_request_timeout_ms(&self) -> u64 {
|
||||
self.vector_engine_image_request_timeout_ms
|
||||
}
|
||||
|
||||
pub fn vector_engine_base_url(&self) -> &str {
|
||||
self.root_state.config.vector_engine_base_url.as_str()
|
||||
}
|
||||
|
||||
pub fn vector_engine_api_key(&self) -> Option<&str> {
|
||||
self.root_state.config.vector_engine_api_key.as_deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for PuzzleApiState {
|
||||
fn from_ref(state: &AppState) -> Self {
|
||||
// 中文注释:拼图路由只暴露本能力需要的依赖快照,避免 handler 直接看见完整 AppState。
|
||||
Self {
|
||||
root_state: state.clone(),
|
||||
spacetime_client: state.spacetime_client.clone(),
|
||||
puzzle_gallery_cache: state.puzzle_gallery_cache.clone(),
|
||||
oss_client: state.oss_client.clone(),
|
||||
auth_user_service: state.auth_user_service.clone(),
|
||||
llm_client: state.llm_client.clone(),
|
||||
creative_agent_gpt5_client: state.creative_agent_gpt5_client.clone(),
|
||||
creation_agent_llm_web_search_enabled: state
|
||||
.config
|
||||
.creation_agent_llm_web_search_enabled,
|
||||
vector_engine_image_request_timeout_ms: state
|
||||
.config
|
||||
.vector_engine_image_request_timeout_ms,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Axum/Hyper 会在路由树和连接 service 上频繁 clone state;AppState 外层必须保持浅拷贝。
|
||||
#[derive(Debug)]
|
||||
pub struct AppStateInner {
|
||||
@@ -1319,4 +1399,23 @@ mod tests {
|
||||
);
|
||||
assert!(client.config().official_fallback());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn puzzle_api_state_exposes_puzzle_dependency_snapshot() {
|
||||
let mut config = AppConfig::default();
|
||||
config.creation_agent_llm_web_search_enabled = false;
|
||||
config.vector_engine_image_request_timeout_ms = 987_654;
|
||||
|
||||
let state = AppState::new(config).expect("state should build");
|
||||
let puzzle_state: PuzzleApiState = FromRef::from_ref(&state);
|
||||
|
||||
assert!(!puzzle_state.creation_agent_llm_web_search_enabled());
|
||||
assert_eq!(
|
||||
puzzle_state.vector_engine_image_request_timeout_ms(),
|
||||
987_654
|
||||
);
|
||||
assert!(puzzle_state.llm_client().is_none());
|
||||
assert!(puzzle_state.creative_agent_gpt5_client().is_none());
|
||||
assert!(puzzle_state.oss_client().is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user