Release v1.0.0 candidate

This commit is contained in:
Accusys
2026-05-08 00:48:15 +08:00
parent 26d9c33419
commit 573714788f
17 changed files with 5040 additions and 895 deletions

View File

@@ -19,15 +19,34 @@ struct EmbedResponse {
embedding: Vec<f32>,
}
#[derive(Deserialize, Debug)]
struct OpenAIEmbedResponse {
data: Vec<OpenAIEmbedData>,
}
#[derive(Deserialize, Debug)]
struct OpenAIEmbedData {
embedding: Vec<f32>,
}
impl Embedder {
pub fn new(model: String) -> Self {
Self::with_url(model, Self::default_url())
}
pub fn with_url(model: String, base_url: String) -> Self {
Self {
model,
client: Client::new(),
base_url: "http://localhost:11434".to_string(),
base_url,
}
}
fn default_url() -> String {
std::env::var("MOMENTRY_EMBED_URL")
.unwrap_or_else(|_| "http://localhost:11434".to_string())
}
pub async fn embed_text(&self, text: &str) -> Result<Vec<f32>> {
self.embed_with_prefix(text, "").await
}
@@ -41,32 +60,64 @@ impl Embedder {
}
async fn embed_with_prefix(&self, text: &str, prefix: &str) -> Result<Vec<f32>> {
let url = format!("{}/api/embeddings", self.base_url);
let prompt = format!("{}{}", prefix, text);
let response = self
.client
.post(&url)
.json(&EmbedRequest {
model: self.model.clone(),
prompt,
})
.send()
.await
.context("Failed to send embedding request to Ollama")?;
// Ollama API: POST {base_url}/api/embeddings with {model, prompt}
// OpenAI-compatible: POST {base_url}/v1/embeddings with {input, model}
let is_openai = self.base_url.contains(":1143"); // llama.cpp ports: 11436, 11437
if !response.status().is_success() {
let status = response.status();
let body = response.text().await.unwrap_or_default();
anyhow::bail!("Ollama API error ({}): {}", status, body);
if is_openai {
let url = format!("{}/v1/embeddings", self.base_url);
let body = serde_json::json!({
"input": prompt,
"model": self.model,
});
let response = self
.client
.post(&url)
.json(&body)
.send()
.await
.context("Failed to send embedding request")?;
if !response.status().is_success() {
let status = response.status();
let body_text = response.text().await.unwrap_or_default();
anyhow::bail!("Embedding API error ({}): {}", status, body_text);
}
let result: OpenAIEmbedResponse = response
.json()
.await
.context("Failed to parse embedding response")?;
Ok(result.data.into_iter().next().map(|d| d.embedding).unwrap_or_default())
} else {
let url = format!("{}/api/embeddings", self.base_url);
let response = self
.client
.post(&url)
.json(&EmbedRequest {
model: self.model.clone(),
prompt,
})
.send()
.await
.context("Failed to send embedding request to Ollama")?;
if !response.status().is_success() {
let status = response.status();
let body_text = response.text().await.unwrap_or_default();
anyhow::bail!("Ollama API error ({}): {}", status, body_text);
}
let result: EmbedResponse = response
.json()
.await
.context("Failed to parse Ollama response")?;
Ok(result.embedding)
}
let result: EmbedResponse = response
.json()
.await
.context("Failed to parse Ollama response")?;
Ok(result.embedding)
}
pub async fn embed_chunk_content(&self, chunk: &crate::core::chunk::Chunk) -> Result<Vec<f32>> {