feat(comfy-cloud): /history 轮询翻译(status+jobs→history)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
boos
2026-06-17 23:21:44 +08:00
parent 03eea2e267
commit e90beda1a5
+51 -2
View File
@@ -47,12 +47,40 @@ async fn submit_prompt(
Ok(Json(value)) Ok(Json(value))
} }
async fn fetch_history(db: &sqlx::SqlitePool, prompt_id: &str) -> AppResult<Value> {
let (base_url, api_key) = resolve_comfy_cloud_site(db).await?;
let http = client();
let status_resp = http
.get(format!("{base_url}/api/job/{prompt_id}/status"))
.header("X-API-Key", &api_key)
.send().await
.map_err(|e| AppError::UpstreamError(e.to_string()))?;
if !status_resp.status().is_success() {
let st = status_resp.status();
let body = status_resp.text().await.unwrap_or_default();
return Err(AppError::UpstreamError(format!("Comfy Cloud status [{st}]: {body}")));
}
let status_json: Value = status_resp.json().await.map_err(|e| AppError::UpstreamError(e.to_string()))?;
let status = status_json.get("status").and_then(Value::as_str).unwrap_or("in_progress");
if status != "completed" {
return Ok(comfy_cloud_job_to_history(prompt_id, status, None));
}
let detail_resp = http
.get(format!("{base_url}/api/jobs/{prompt_id}"))
.header("X-API-Key", &api_key)
.send().await
.map_err(|e| AppError::UpstreamError(e.to_string()))?;
let detail_json: Value = detail_resp.json().await.map_err(|e| AppError::UpstreamError(e.to_string()))?;
let outputs = detail_json.get("outputs");
Ok(comfy_cloud_job_to_history(prompt_id, status, outputs))
}
async fn get_history( async fn get_history(
State(state): State<AppState>, State(state): State<AppState>,
Path(prompt_id): Path<String>, Path(prompt_id): Path<String>,
) -> AppResult<Json<Value>> { ) -> AppResult<Json<Value>> {
let _ = (&state, &prompt_id); Ok(Json(fetch_history(&state.db, &prompt_id).await?))
Ok(Json(serde_json::json!({})))
} }
async fn get_view( async fn get_view(
@@ -98,4 +126,25 @@ mod tests {
let v: Value = resp.json().await.unwrap(); let v: Value = resp.json().await.unwrap();
assert_eq!(v["prompt_id"], "p1"); assert_eq!(v["prompt_id"], "p1");
} }
#[tokio::test]
async fn history_in_progress_then_completed() {
let server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/api/job/p1/status"))
.and(match_header("X-API-Key", "key-123"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ "status": "completed" })))
.mount(&server).await;
Mock::given(method("GET"))
.and(path("/api/jobs/p1"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"outputs": { "9": { "images": [{ "filename": "a.png", "subfolder": "", "type": "output" }] } }
})))
.mount(&server).await;
let pool = db_with_site(&server.uri()).await;
let history = fetch_history(&pool, "p1").await.unwrap();
assert_eq!(history["p1"]["status"]["completed"], true);
assert_eq!(history["p1"]["outputs"]["9"]["images"][0]["filename"], "a.png");
}
} }