Bug 1: LLM_API_BASE=https://api.riotpiao.com/v1 + code appends /v1/embeddings = https://api.riotpiao.com/v1/v1/embeddings (404). Fix: strip trailing /v1 from base URL in from_env(). Bug 2: embeddings client sent 'apikey' custom header, but gateway expects 'Authorization: Bearer <token>'. Fix: use Authorization Bearer header. Caused: 'expected ident at line 1 column 2' error on /memory/query (gateway returned HTML/text error, client tried to parse as JSON).
This commit is contained in:
@@ -64,9 +64,15 @@ impl EmbeddingsClient {
|
||||
/// - `LLM_API_BASE`: Gateway endpoint (default: https://api.riotpiao.com)
|
||||
/// - `LLM_API_KEY`: API key (optional)
|
||||
pub fn from_env() -> Result<Self> {
|
||||
let base_url = env::var("LLM_API_BASE")
|
||||
let mut base_url = env::var("LLM_API_BASE")
|
||||
.unwrap_or_else(|_| "https://api.riotpiao.com".to_string());
|
||||
|
||||
// Strip trailing /v1 to avoid double /v1/v1/embeddings
|
||||
base_url = base_url.trim_end_matches('/').to_string();
|
||||
if base_url.ends_with("/v1") {
|
||||
base_url = base_url[..base_url.len() - 3].to_string();
|
||||
}
|
||||
|
||||
let model = env::var("EMBEDDINGS_MODEL")
|
||||
.unwrap_or_else(|_| "nomic-ai/nomic-embed-text-v2-moe".to_string());
|
||||
|
||||
@@ -161,10 +167,9 @@ impl EmbeddingsClient {
|
||||
let url = format!("{}/v1/embeddings", self.base_url);
|
||||
let mut builder = self.http.post(&url);
|
||||
|
||||
// Send apikey header even though route currently doesn't require auth
|
||||
// This future-proofs for when the route's auth plugin gets enabled
|
||||
// Send as Bearer token (gateway expects Authorization: Bearer <key>)
|
||||
if !self.api_key.is_empty() {
|
||||
builder = builder.header("apikey", &self.api_key);
|
||||
builder = builder.header("Authorization", format!("Bearer {}", &self.api_key));
|
||||
}
|
||||
|
||||
let resp = builder.json(&req).send().await?;
|
||||
@@ -215,6 +220,28 @@ mod tests {
|
||||
assert_eq!(EMBEDDINGS_DIM, 768);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_strip_trailing_v1() {
|
||||
// Simulates LLM_API_BASE=https://api.riotpiao.com/v1
|
||||
let mut base = "https://api.riotpiao.com/v1".to_string();
|
||||
base = base.trim_end_matches('/').to_string();
|
||||
if base.ends_with("/v1") {
|
||||
base = base[..base.len() - 3].to_string();
|
||||
}
|
||||
assert_eq!(base, "https://api.riotpiao.com");
|
||||
assert_eq!(format!("{}/v1/embeddings", base), "https://api.riotpiao.com/v1/embeddings");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_strip_when_no_v1() {
|
||||
let mut base = "https://api.riotpiao.com".to_string();
|
||||
base = base.trim_end_matches('/').to_string();
|
||||
if base.ends_with("/v1") {
|
||||
base = base[..base.len() - 3].to_string();
|
||||
}
|
||||
assert_eq!(base, "https://api.riotpiao.com");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_real_embedding_response() {
|
||||
// Exact format returned by embeddings-predictor service
|
||||
|
||||
Reference in New Issue
Block a user