feat: add Vision LLM integration (CLIP + Qwen3-VL cascade)
- Add Qwen3-VL dynamic management (start/stop/status CLI) - Add CLIP + Qwen3-VL cascade detection strategy - Add Vision CLI commands (vision start/stop/status, detect) - Add cascade_vision processor module - Add clip processor module - Add qwen_vl_manager module Changes: - scripts/start_qwen3vl.sh, stop_qwen3vl.sh: Qwen3-VL management scripts - src/core/vision/: Qwen3-VL manager module - src/core/processor/cascade_vision.rs: CLIP + Qwen3-VL cascade logic - src/core/processor/clip.rs: CLIP classification and detection - src/api/clip_api.rs: CLIP API endpoints - src/cli/vision.rs: Vision CLI implementation - src/cli/args.rs: Add Vision and Detect commands - src/main.rs: Integrate Vision CLI - src/core/mod.rs: Add vision module - src/core/processor/mod.rs: Add cascade_vision module
This commit is contained in:
+20
-11
@@ -593,7 +593,11 @@ async fn get_trace_thumbnail_inner(
|
||||
// For trace_id=0 (untracked/stranger), check unbound directory instead
|
||||
let output_dir = crate::core::config::OUTPUT_DIR.as_str();
|
||||
let trace_id_str = trace_id.to_string();
|
||||
let trace_dir_name = if trace_id == 0 { "unbound" } else { &trace_id_str };
|
||||
let trace_dir_name = if trace_id == 0 {
|
||||
"unbound"
|
||||
} else {
|
||||
&trace_id_str
|
||||
};
|
||||
let trace_dir = std::path::PathBuf::from(output_dir)
|
||||
.join(".faces")
|
||||
.join(&file_uuid)
|
||||
@@ -605,15 +609,16 @@ async fn get_trace_thumbnail_inner(
|
||||
while let Some(Ok(entry)) = entries.next() {
|
||||
let path = entry.path();
|
||||
if path.extension().map_or(false, |e| e == "jpg") {
|
||||
tracing::info!("[trace_thumbnail] Using cached face crop: {}", path.display());
|
||||
let bytes = tokio::fs::read(&path)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(serde_json::json!({"error": e.to_string()})),
|
||||
)
|
||||
})?;
|
||||
tracing::info!(
|
||||
"[trace_thumbnail] Using cached face crop: {}",
|
||||
path.display()
|
||||
);
|
||||
let bytes = tokio::fs::read(&path).await.map_err(|e| {
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(serde_json::json!({"error": e.to_string()})),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Validate cached JPEG
|
||||
crate::core::thumbnail::validator::validate_jpeg(&bytes).map_err(|e| {
|
||||
@@ -647,7 +652,11 @@ async fn get_trace_thumbnail_inner(
|
||||
let seek = sel.frame as f64 / sel.fps;
|
||||
let tmp = std::env::temp_dir().join(format!("trace_{}_{}.jpg", file_uuid, trace_id));
|
||||
|
||||
tracing::debug!("[trace_thumbnail] Fallback to ffmpeg for trace {} frame {}", trace_id, sel.frame);
|
||||
tracing::debug!(
|
||||
"[trace_thumbnail] Fallback to ffmpeg for trace {} frame {}",
|
||||
trace_id,
|
||||
sel.frame
|
||||
);
|
||||
|
||||
let status = tokio::process::Command::new("ffmpeg")
|
||||
.args([
|
||||
|
||||
Reference in New Issue
Block a user