diff --git a/server-rs/crates/api-server/src/editor_agent/api.rs b/server-rs/crates/api-server/src/editor_agent/api.rs index 62806b488..4ed3319dd 100644 --- a/server-rs/crates/api-server/src/editor_agent/api.rs +++ b/server-rs/crates/api-server/src/editor_agent/api.rs @@ -159,7 +159,7 @@ pub async fn editor_agent_message( .with_details(json!({ "message": "LLM client not configured" })) })?; let llm_client = llm_client.clone(); - let pricing = state.editor_generation_pricing().map_err(|error| { + let pricing = state.editor_generation_pricing().await.map_err(|error| { AppError::from_status(axum::http::StatusCode::INTERNAL_SERVER_ERROR).with_details(json!({ "provider": "editor-generation-pricing", "message": error.to_string(), @@ -1006,13 +1006,20 @@ pub async fn confirm_editor_agent_tool_call( // Each confirmed tool reuses its existing editor-generation entry point. match tool_name.as_str() { GenerateSoundEffectTool::NAME => { - let args: GenerateSoundEffectToolArgs = serde_json::from_value(tc.args.clone()) + let args: GenerateSoundEffectToolArgs = serde_json::from_value(tool_args.clone()) .map_err(|error| { editor_agent_bad_request(format!("invalid tool call args: {error}")) })?; let project = load_editor_agent_project(&state, &conversation).await?; let title = args.prompt.clone(); let tool = GenerateSoundEffectTool; + persist_editor_agent_tool_call_executing( + &state, + &conversation, + &mut document, + message_id, + ) + .await?; let result = tool .execute( &state, @@ -1053,13 +1060,20 @@ pub async fn confirm_editor_agent_tool_call( .await } GenerateBackgroundMusicTool::NAME => { - let args: GenerateBackgroundMusicToolArgs = serde_json::from_value(tc.args.clone()) + let args: GenerateBackgroundMusicToolArgs = serde_json::from_value(tool_args.clone()) .map_err(|error| { - editor_agent_bad_request(format!("invalid tool call args: {error}")) - })?; + editor_agent_bad_request(format!("invalid tool call args: {error}")) + })?; let project = load_editor_agent_project(&state, &conversation).await?; let title = "生成背景音乐".to_string(); let tool = GenerateBackgroundMusicTool; + persist_editor_agent_tool_call_executing( + &state, + &conversation, + &mut document, + message_id, + ) + .await?; let result = tool .execute( &state, @@ -1109,6 +1123,13 @@ pub async fn confirm_editor_agent_tool_call( let tool = GenerateVideoTool { context: build_tool_context(&document), }; + persist_editor_agent_tool_call_executing( + &state, + &conversation, + &mut document, + message_id, + ) + .await?; let result = tool .execute( &state, @@ -1160,6 +1181,13 @@ pub async fn confirm_editor_agent_tool_call( let tool = GenerateIconSpritesheetTool { context: build_tool_context(&document), }; + persist_editor_agent_tool_call_executing( + &state, + &conversation, + &mut document, + message_id, + ) + .await?; let result = tool .execute( &state, @@ -1221,6 +1249,13 @@ pub async fn confirm_editor_agent_tool_call( build_editor_agent_canvas_completion(&project, tool_name.as_str(), &title); let generation_inputs = editor_agent_generation_inputs(&conversation, message_id, &args); + persist_editor_agent_tool_call_executing( + &state, + &conversation, + &mut document, + message_id, + ) + .await?; let result = if tool_name == GenerateCharacterTool::NAME { GenerateCharacterTool { context: build_tool_context(&document), @@ -1286,6 +1321,13 @@ pub async fn confirm_editor_agent_tool_call( let generate_tool = GenerateImageTool { context: tool_context, }; + persist_editor_agent_tool_call_executing( + &state, + &conversation, + &mut document, + message_id, + ) + .await?; let result = generate_tool .execute( &state, @@ -1344,12 +1386,13 @@ pub async fn confirm_editor_agent_tool_call( let edit_tool = EditImageTool { context: tool_context, }; - - // mark it quickly - if let Some(tool_call) = &mut document.messages[message_id].tool_call { - tool_call.status = EditorAgentToolCallStatus::Executing; - } - write_messages_document(&state, &conversation, &document).await?; + persist_editor_agent_tool_call_executing( + &state, + &conversation, + &mut document, + message_id, + ) + .await?; let result = edit_tool .execute( @@ -1416,6 +1459,31 @@ pub async fn confirm_editor_agent_tool_call( } } +async fn persist_editor_agent_tool_call_executing( + state: &AppState, + conversation: &EditorAgentConversationRecord, + document: &mut EditorAgentConversationMessagesDocument, + message_id: usize, +) -> Result<(), AppError> { + fn mark_editor_agent_tool_call_executing( + tool_call: &mut EditorAgentToolCall, + ) -> Result<(), AppError> { + if tool_call.status != EditorAgentToolCallStatus::PendingConfirmation { + return Err(editor_agent_bad_request( + "tool call is not in PendingConfirmation status", + )); + } + tool_call.status = EditorAgentToolCallStatus::Executing; + Ok(()) + } + let tool_call = document.messages[message_id] + .tool_call + .as_mut() + .ok_or_else(|| editor_agent_bad_request("message has no tool call"))?; + mark_editor_agent_tool_call_executing(tool_call)?; + write_messages_document(state, conversation, document).await +} + async fn load_editor_agent_project( state: &AppState, conversation: &EditorAgentConversationRecord,