From d83b34b98cc2a175fff89c43d319d3ec28ecb1c1 Mon Sep 17 00:00:00 2001 From: wuyangji <694410194@qq.com> Date: Thu, 14 May 2026 04:27:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(import):=20=E6=8B=92=E7=BB=9D=E9=9D=9E?= =?UTF-8?q?=E6=B3=95=E6=B6=88=E6=81=AF=E8=A7=92=E8=89=B2=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cortex-cli/src/import_cmd.rs | 77 +++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/src/cortex-cli/src/import_cmd.rs b/src/cortex-cli/src/import_cmd.rs index 696d93ae8..921bc0622 100644 --- a/src/cortex-cli/src/import_cmd.rs +++ b/src/cortex-cli/src/import_cmd.rs @@ -427,7 +427,12 @@ fn validate_export_messages(messages: &[ExportMessage]) -> Result<()> { /// Convert an export message to a protocol event. fn message_to_event(message: &ExportMessage, turn_id: &mut u64, cwd: &Path) -> Result { - let event_msg = match message.role.as_str() { + let role = message.role.trim(); + if role.is_empty() { + bail!("Invalid message role: role cannot be empty or whitespace-only"); + } + + let event_msg = match role { "user" => { *turn_id += 1; EventMsg::UserMessage(UserMessageEvent { @@ -474,15 +479,10 @@ fn message_to_event(message: &ExportMessage, turn_id: &mut u64, cwd: &Path) -> R finish_reason: None, }) } - other => { - // Unknown role, treat as assistant message - EventMsg::AgentMessage(AgentMessageEvent { - id: None, - parent_id: None, - message: format!("[{other}] {}", message.content), - finish_reason: None, - }) - } + other => bail!( + "Invalid message role '{}': expected one of user, assistant, tool, or system", + other + ), }; Ok(Event { @@ -545,6 +545,63 @@ mod tests { assert!(matches!(event.msg, EventMsg::AgentMessage(_))); } + #[test] + fn test_message_to_event_rejects_empty_role() { + let mut turn_id = 0u64; + let cwd = PathBuf::from("/tmp"); + let msg = ExportMessage { + role: "".to_string(), + content: "hello".to_string(), + tool_calls: None, + tool_call_id: None, + timestamp: None, + }; + + let err = message_to_event(&msg, &mut turn_id, &cwd).unwrap_err(); + assert!( + err.to_string() + .contains("role cannot be empty or whitespace-only") + ); + } + + #[test] + fn test_message_to_event_rejects_whitespace_only_role() { + let mut turn_id = 0u64; + let cwd = PathBuf::from("/tmp"); + let msg = ExportMessage { + role: " ".to_string(), + content: "hello".to_string(), + tool_calls: None, + tool_call_id: None, + timestamp: None, + }; + + let err = message_to_event(&msg, &mut turn_id, &cwd).unwrap_err(); + assert!( + err.to_string() + .contains("role cannot be empty or whitespace-only") + ); + } + + #[test] + fn test_message_to_event_rejects_unknown_role() { + let mut turn_id = 0u64; + let cwd = PathBuf::from("/tmp"); + let msg = ExportMessage { + role: "developer".to_string(), + content: "hello".to_string(), + tool_calls: None, + tool_call_id: None, + timestamp: None, + }; + + let err = message_to_event(&msg, &mut turn_id, &cwd).unwrap_err(); + assert!( + err.to_string() + .contains("expected one of user, assistant, tool, or system") + ); + } + #[tokio::test] async fn test_import_empty_source_validation() { let cmd = ImportCommand {