diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/claude_code_cli.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/claude_code_cli.rs index 1b56483b5..84d61771d 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/claude_code_cli.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/claude_code_cli.rs @@ -212,7 +212,7 @@ async fn run_sidecar_turn( .take() .ok_or_else(|| "Claude Agent SDK sidecar stderr 未建立".to_string())?; let stderr_task = tokio::spawn(read_capped(stderr, CLAUDE_CODE_OUTPUT_MAX_BYTES)); - let result = tokio::time::timeout(Duration::from_millis(timeout_ms.max(1)), async { + let result = match tokio::time::timeout(Duration::from_millis(timeout_ms.max(1)), async { let mut lines = BufReader::new(stdout).lines(); let mut events = Vec::new(); let mut terminal = None; @@ -257,7 +257,21 @@ async fn run_sidecar_turn( Ok(SidecarTurnResult { events, result }) }) .await - .map_err(|_| "Claude Agent SDK sidecar 回合超时".to_string())??; + { + Ok(result) => result?, + Err(_) => { + let detail = stderr_task + .await + .ok() + .and_then(Result::ok) + .and_then(|bytes| String::from_utf8(bytes).ok()) + .map(|value| value.trim().chars().take(512).collect::()) + .filter(|value| !value.is_empty()) + .map(|value| format!(":{value}")) + .unwrap_or_default(); + return Err(format!("Claude Agent SDK sidecar 回合超时{detail}")); + } + }; let _ = stderr_task.await; Ok(result) } @@ -317,6 +331,14 @@ pub(crate) fn game_creator_claude_code_cli_route_error( if model.is_empty() || model.chars().count() > CLAUDE_CODE_MODEL_MAX_CHARS { return Some("cc 模式需要有效的 Claude Code 模型标识".to_string()); } + if llm.api_key.trim().is_empty() + && !llm.custom_enabled + && std::env::var_os("ANTHROPIC_API_KEY").is_none() + && std::env::var_os("ANTHROPIC_AUTH_TOKEN").is_none() + && crate::platform_session::current_platform_session().is_none() + { + return Some("cc 模式需要先登录陶泥儿账号".to_string()); + } None }