fix: 修复 Hedra 口型合成工具的 API 调用问题

- 修复前端和后端参数类型不匹配问题
- 在前端服务中添加 fileToBytes 方法,将 File 对象转换为字节数组
- 更新后端 HedraFileUploadRequest 结构,添加 purpose 字段
- 修复 Tauri 命令参数接收方式,使用 params 而不是 request
- 将 bowong_wait_for_task_completion 的模拟实现替换为真实的 API 调用
- 使用 wait_for_task_completion 方法实现真实的任务等待逻辑

现在 Hedra 工具应该能够正确调用后端 API 进行文件上传和任务处理
This commit is contained in:
imeepos 2025-08-01 11:13:25 +08:00
parent 0ec73f03ca
commit 538254ee38
3 changed files with 46 additions and 16 deletions

View File

@ -263,6 +263,7 @@ pub struct ComfyUISyncExecuteRequest {
pub struct HedraFileUploadRequest { pub struct HedraFileUploadRequest {
pub file_data: Vec<u8>, pub file_data: Vec<u8>,
pub filename: String, pub filename: String,
pub purpose: Option<String>, // 'image', 'audio', 'video', 'voice'
} }
/// Hedra 任务提交请求 /// Hedra 任务提交请求

View File

@ -668,22 +668,25 @@ pub async fn bowong_batch_query_task_status(
/// 等待任务完成 /// 等待任务完成
#[command] #[command]
pub async fn bowong_wait_for_task_completion( pub async fn bowong_wait_for_task_completion(
state: State<'_, AppState>,
task_id: String, task_id: String,
max_wait_time: u64, max_wait_time: u64,
poll_interval: u64, poll_interval: u64,
) -> Result<TaskStatusResponse, String> { ) -> Result<TaskStatusResponse, String> {
// 模拟等待 // 克隆服务以避免跨 await 点持有 MutexGuard
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; let service = {
let service_guard = state.get_bowong_service()
.map_err(|e| format!("Failed to get BowongTextVideoAgent service: {}", e))?;
Ok(TaskStatusResponse { service_guard.as_ref()
task_id, .ok_or_else(|| "BowongTextVideoAgent service not initialized".to_string())?
status: "completed".to_string(), .clone()
progress: Some(100.0), };
result: Some(serde_json::json!({"output": "Task completed after waiting"})),
error: None, // 使用真实的轮询逻辑等待任务完成
created_at: Some("2024-01-01T00:00:00Z".to_string()), service.wait_for_task_completion(&task_id, max_wait_time, poll_interval)
updated_at: Some("2024-01-01T00:00:00Z".to_string()), .await
}) .map_err(|e| format!("Failed to wait for task completion: {}", e))
} }
// ============================================================================ // ============================================================================
@ -694,7 +697,7 @@ pub async fn bowong_wait_for_task_completion(
#[command] #[command]
pub async fn hedra_upload_file( pub async fn hedra_upload_file(
state: State<'_, AppState>, state: State<'_, AppState>,
request: HedraFileUploadRequest, params: HedraFileUploadRequest,
) -> Result<FileUploadResponse, String> { ) -> Result<FileUploadResponse, String> {
// 克隆服务以避免跨 await 点持有 MutexGuard // 克隆服务以避免跨 await 点持有 MutexGuard
let service = { let service = {
@ -706,7 +709,7 @@ pub async fn hedra_upload_file(
.clone() .clone()
}; };
service.hedra_upload_file(&request) service.hedra_upload_file(&params)
.await .await
.map_err(|e| format!("Failed to upload file to Hedra: {}", e)) .map_err(|e| format!("Failed to upload file to Hedra: {}", e))
} }
@ -715,7 +718,7 @@ pub async fn hedra_upload_file(
#[command] #[command]
pub async fn hedra_submit_task( pub async fn hedra_submit_task(
state: State<'_, AppState>, state: State<'_, AppState>,
request: HedraTaskSubmitRequest, params: HedraTaskSubmitRequest,
) -> Result<TaskResponse, String> { ) -> Result<TaskResponse, String> {
// 克隆服务以避免跨 await 点持有 MutexGuard // 克隆服务以避免跨 await 点持有 MutexGuard
let service = { let service = {
@ -727,7 +730,7 @@ pub async fn hedra_submit_task(
.clone() .clone()
}; };
service.hedra_submit_task(&request) service.hedra_submit_task(&params)
.await .await
.map_err(|e| format!("Failed to submit Hedra task: {}", e)) .map_err(|e| format!("Failed to submit Hedra task: {}", e))
} }

View File

@ -606,7 +606,15 @@ export class BowongTextVideoAgentFastApiService implements BowongTextVideoAgentA
// ============================================================================ // ============================================================================
async hedraUploadFile(request: HedraFileUploadRequest): Promise<FileUploadResponse> { async hedraUploadFile(request: HedraFileUploadRequest): Promise<FileUploadResponse> {
return this.invokeAPI<FileUploadResponse>('hedra_upload_file', request); // 将 File 对象转换为后端期望的格式
const fileData = await this.fileToBytes(request.local_file);
const backendRequest = {
file_data: Array.from(fileData), // 转换为数字数组
filename: request.local_file.name,
purpose: request.purpose || 'image'
};
return this.invokeAPI<FileUploadResponse>('hedra_upload_file', backendRequest);
} }
async hedraSubmitTask(request: HedraTaskSubmitRequest): Promise<TaskResponse> { async hedraSubmitTask(request: HedraTaskSubmitRequest): Promise<TaskResponse> {
@ -633,6 +641,24 @@ export class BowongTextVideoAgentFastApiService implements BowongTextVideoAgentA
// 工具方法 // 工具方法
// ============================================================================ // ============================================================================
/**
* File
*/
private async fileToBytes(file: File): Promise<Uint8Array> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
if (reader.result instanceof ArrayBuffer) {
resolve(new Uint8Array(reader.result));
} else {
reject(new Error('Failed to read file as ArrayBuffer'));
}
};
reader.onerror = () => reject(reader.error);
reader.readAsArrayBuffer(file);
});
}
/** /**
* *
*/ */