feat: implement Phase 6 Agent Integration (Translation API)
This commit is contained in:
87
src/api/agent_api.rs
Normal file
87
src/api/agent_api.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::StatusCode,
|
||||
response::Json,
|
||||
routing::post,
|
||||
Router,
|
||||
};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing;
|
||||
|
||||
use crate::api::server::AppState;
|
||||
|
||||
pub fn agent_routes() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/api/v1/agents/translate", post(translate_text))
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TranslationRequest {
|
||||
pub text: String,
|
||||
pub target_language: String,
|
||||
pub source_language: Option<String>, // "auto" if not specified
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct TranslationResponse {
|
||||
pub success: bool,
|
||||
pub translated_text: String,
|
||||
pub source_language_detected: String,
|
||||
pub model_used: String,
|
||||
}
|
||||
|
||||
async fn translate_text(
|
||||
State(_state): State<AppState>,
|
||||
Json(req): Json<TranslationRequest>,
|
||||
) -> Result<Json<TranslationResponse>, (StatusCode, String)> {
|
||||
|
||||
let system_prompt = "You are a professional translator for Momentry Core, a digital asset management system specializing in video analysis.
|
||||
|
||||
## Guidelines:
|
||||
1. **Accuracy**: Translate the meaning accurately, maintaining the original tone.
|
||||
2. **Style**:
|
||||
- For subtitles: Keep it concise and natural for reading.
|
||||
- For technical terms (e.g., 5W1H, metadata): Use standard industry translations.
|
||||
3. **Output**: Return ONLY the translated text. Do not include explanations or notes.";
|
||||
|
||||
let prompt = format!(
|
||||
"Translate the following text to {}: \n\n{}",
|
||||
req.target_language, req.text
|
||||
);
|
||||
|
||||
// Call Ollama API
|
||||
let client = Client::new();
|
||||
let ollama_url = "http://localhost:11434/api/generate";
|
||||
|
||||
// Using qwen3:latest which is available locally
|
||||
let model = "qwen3:latest".to_string();
|
||||
|
||||
let body = serde_json::json!({
|
||||
"model": model,
|
||||
"prompt": prompt,
|
||||
"system": system_prompt,
|
||||
"stream": false
|
||||
});
|
||||
|
||||
let response = client.post(ollama_url)
|
||||
.json(&body)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to call LLM: {}", e)))?;
|
||||
|
||||
let ollama_resp: serde_json::Value = response.json().await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to parse LLM response: {}", e)))?;
|
||||
|
||||
let translated_text = ollama_resp.get("response")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("Translation failed")
|
||||
.to_string();
|
||||
|
||||
Ok(Json(TranslationResponse {
|
||||
success: true,
|
||||
translated_text,
|
||||
source_language_detected: req.source_language.unwrap_or("unknown".to_string()),
|
||||
model_used: model,
|
||||
}))
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod agent_api;
|
||||
pub mod face_recognition;
|
||||
pub mod identities;
|
||||
pub mod identity_api;
|
||||
|
||||
@@ -20,6 +20,7 @@ use crate::core::db::{Database, PostgresDb, QdrantDb, RedisClient, VideoRecord,
|
||||
use crate::core::text::tokenizer::tokenize_chinese_text;
|
||||
use crate::{Embedder, FileManager};
|
||||
|
||||
use super::agent_api;
|
||||
use super::face_recognition;
|
||||
use super::identities;
|
||||
use super::identity_binding;
|
||||
@@ -2482,6 +2483,7 @@ pub async fn start_server(host: &str, port: u16) -> anyhow::Result<()> {
|
||||
post(search_visual_chunks_by_combination),
|
||||
)
|
||||
.merge(identity_api::identity_routes()) // Phase 3 Routes
|
||||
.merge(agent_api::agent_routes()) // Phase 6 Routes
|
||||
.merge(protected_routes)
|
||||
.layer(cors)
|
||||
.with_state(state);
|
||||
|
||||
Reference in New Issue
Block a user