mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-01-22 19:13:10 +08:00
Merge #5234
Some checks failed
Test suite / Tests on ${{ matrix.os }} (macos-13) (push) Waiting to run
Run the indexing fuzzer / Setup the action (push) Failing after 15s
Test suite / Tests on ${{ matrix.os }} (windows-2022) (push) Failing after 12m54s
Test suite / Tests on macos-13 (push) Waiting to run
Indexing bench (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of indexing (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of search for geo (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of search for songs (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of search for Wikipedia articles (push) / Run and upload benchmarks (push) Has been cancelled
Publish binaries to GitHub release / Check the version validity (push) Successful in 11s
Publish binaries to GitHub release / Publish binary for macos-13 (push) Waiting to run
Publish binaries to GitHub release / Publish binary for macOS silicon (meilisearch-macos-apple-silicon, aarch64-apple-darwin) (push) Waiting to run
Publish binaries to GitHub release / Publish binary for Linux (push) Failing after 2s
Publish binaries to GitHub release / Publish binary for aarch64 (meilisearch-linux-aarch64, aarch64-unknown-linux-gnu) (push) Failing after 12s
Publish binaries to GitHub release / Publish binary for windows-2022 (push) Failing after 29s
Test suite / Tests almost all features (push) Failing after 0s
Test suite / Test disabled tokenization (push) Failing after 1s
Test suite / Run tests in debug (push) Failing after 1s
Test suite / Tests on ubuntu-20.04 (push) Failing after 12s
Test suite / Tests on windows-2022 (push) Failing after 24s
Test suite / Run Clippy (push) Failing after 12s
Test suite / Run Rustfmt (push) Successful in 1m36s
Some checks failed
Test suite / Tests on ${{ matrix.os }} (macos-13) (push) Waiting to run
Run the indexing fuzzer / Setup the action (push) Failing after 15s
Test suite / Tests on ${{ matrix.os }} (windows-2022) (push) Failing after 12m54s
Test suite / Tests on macos-13 (push) Waiting to run
Indexing bench (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of indexing (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of search for geo (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of search for songs (push) / Run and upload benchmarks (push) Has been cancelled
Benchmarks of search for Wikipedia articles (push) / Run and upload benchmarks (push) Has been cancelled
Publish binaries to GitHub release / Check the version validity (push) Successful in 11s
Publish binaries to GitHub release / Publish binary for macos-13 (push) Waiting to run
Publish binaries to GitHub release / Publish binary for macOS silicon (meilisearch-macos-apple-silicon, aarch64-apple-darwin) (push) Waiting to run
Publish binaries to GitHub release / Publish binary for Linux (push) Failing after 2s
Publish binaries to GitHub release / Publish binary for aarch64 (meilisearch-linux-aarch64, aarch64-unknown-linux-gnu) (push) Failing after 12s
Publish binaries to GitHub release / Publish binary for windows-2022 (push) Failing after 29s
Test suite / Tests almost all features (push) Failing after 0s
Test suite / Test disabled tokenization (push) Failing after 1s
Test suite / Run tests in debug (push) Failing after 1s
Test suite / Tests on ubuntu-20.04 (push) Failing after 12s
Test suite / Tests on windows-2022 (push) Failing after 24s
Test suite / Run Clippy (push) Failing after 12s
Test suite / Run Rustfmt (push) Successful in 1m36s
5234: Parse ollama URL to adapt configuration depending on the endpoint r=Kerollmops a=dureuill # Pull Request ## Related issue Fixes #5002 ## What does this PR do? - Parses `url` parameter of `ollama` to recognize supported endpoint and adapt the REST configuration to the recognized endpoint - Throws a new error if no endpoint is recognized - Add a test for the various recognized endpoints Thanks to `@Guikingone` for the original report and PR Co-authored-by: Louis Dureuil <louis@meilisearch.com>
This commit is contained in:
commit
0776217801
@ -255,3 +255,155 @@ async fn reset_embedder_documents() {
|
|||||||
}
|
}
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn ollama_url_checks() {
|
||||||
|
let server = super::get_server_vector().await;
|
||||||
|
let index = server.index("doggo");
|
||||||
|
|
||||||
|
let (response, code) = index
|
||||||
|
.update_settings(json!({
|
||||||
|
"embedders": { "ollama": {"source": "ollama", "model": "toto", "dimensions": 1, "url": "http://localhost:11434/api/embeddings"}},
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"202 Accepted");
|
||||||
|
let response = server.wait_task(response.uid()).await;
|
||||||
|
|
||||||
|
snapshot!(response, @r###"
|
||||||
|
{
|
||||||
|
"uid": "[uid]",
|
||||||
|
"batchUid": "[batch_uid]",
|
||||||
|
"indexUid": "doggo",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"embedders": {
|
||||||
|
"ollama": {
|
||||||
|
"source": "ollama",
|
||||||
|
"model": "toto",
|
||||||
|
"dimensions": 1,
|
||||||
|
"url": "[url]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
"###);
|
||||||
|
|
||||||
|
let (response, code) = index
|
||||||
|
.update_settings(json!({
|
||||||
|
"embedders": { "ollama": {"source": "ollama", "model": "toto", "dimensions": 1, "url": "http://localhost:11434/api/embed"}},
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"202 Accepted");
|
||||||
|
let response = server.wait_task(response.uid()).await;
|
||||||
|
|
||||||
|
snapshot!(response, @r###"
|
||||||
|
{
|
||||||
|
"uid": "[uid]",
|
||||||
|
"batchUid": "[batch_uid]",
|
||||||
|
"indexUid": "doggo",
|
||||||
|
"status": "succeeded",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"embedders": {
|
||||||
|
"ollama": {
|
||||||
|
"source": "ollama",
|
||||||
|
"model": "toto",
|
||||||
|
"dimensions": 1,
|
||||||
|
"url": "[url]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": null,
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
"###);
|
||||||
|
|
||||||
|
let (response, code) = index
|
||||||
|
.update_settings(json!({
|
||||||
|
"embedders": { "ollama": {"source": "ollama", "model": "toto", "dimensions": 1, "url": "http://localhost:11434/api/embedd"}},
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"202 Accepted");
|
||||||
|
let response = server.wait_task(response.uid()).await;
|
||||||
|
|
||||||
|
snapshot!(response, @r###"
|
||||||
|
{
|
||||||
|
"uid": "[uid]",
|
||||||
|
"batchUid": "[batch_uid]",
|
||||||
|
"indexUid": "doggo",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"embedders": {
|
||||||
|
"ollama": {
|
||||||
|
"source": "ollama",
|
||||||
|
"model": "toto",
|
||||||
|
"dimensions": 1,
|
||||||
|
"url": "[url]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "Index `doggo`: Error while generating embeddings: user error: unsupported Ollama URL.\n - For `ollama` sources, the URL must end with `/api/embed` or `/api/embeddings`\n - Got `http://localhost:11434/api/embedd`",
|
||||||
|
"code": "vector_embedding_error",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#vector_embedding_error"
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
"###);
|
||||||
|
|
||||||
|
let (response, code) = index
|
||||||
|
.update_settings(json!({
|
||||||
|
"embedders": { "ollama": {"source": "ollama", "model": "toto", "dimensions": 1, "url": "http://localhost:11434/v1/embeddings"}},
|
||||||
|
}))
|
||||||
|
.await;
|
||||||
|
snapshot!(code, @"202 Accepted");
|
||||||
|
let response = server.wait_task(response.uid()).await;
|
||||||
|
|
||||||
|
snapshot!(response, @r###"
|
||||||
|
{
|
||||||
|
"uid": "[uid]",
|
||||||
|
"batchUid": "[batch_uid]",
|
||||||
|
"indexUid": "doggo",
|
||||||
|
"status": "failed",
|
||||||
|
"type": "settingsUpdate",
|
||||||
|
"canceledBy": null,
|
||||||
|
"details": {
|
||||||
|
"embedders": {
|
||||||
|
"ollama": {
|
||||||
|
"source": "ollama",
|
||||||
|
"model": "toto",
|
||||||
|
"dimensions": 1,
|
||||||
|
"url": "[url]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"message": "Index `doggo`: Error while generating embeddings: user error: unsupported Ollama URL.\n - For `ollama` sources, the URL must end with `/api/embed` or `/api/embeddings`\n - Got `http://localhost:11434/v1/embeddings`",
|
||||||
|
"code": "vector_embedding_error",
|
||||||
|
"type": "invalid_request",
|
||||||
|
"link": "https://docs.meilisearch.com/errors#vector_embedding_error"
|
||||||
|
},
|
||||||
|
"duration": "[duration]",
|
||||||
|
"enqueuedAt": "[date]",
|
||||||
|
"startedAt": "[date]",
|
||||||
|
"finishedAt": "[date]"
|
||||||
|
}
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
@ -67,7 +67,7 @@ pub enum EmbedErrorKind {
|
|||||||
#[error("could not authenticate against {embedding} server{server_reply}{hint}", embedding=match *.1 {
|
#[error("could not authenticate against {embedding} server{server_reply}{hint}", embedding=match *.1 {
|
||||||
ConfigurationSource::User => "embedding",
|
ConfigurationSource::User => "embedding",
|
||||||
ConfigurationSource::OpenAi => "OpenAI",
|
ConfigurationSource::OpenAi => "OpenAI",
|
||||||
ConfigurationSource::Ollama => "ollama"
|
ConfigurationSource::Ollama => "Ollama"
|
||||||
},
|
},
|
||||||
server_reply=option_info(.0.as_deref(), "server replied with "),
|
server_reply=option_info(.0.as_deref(), "server replied with "),
|
||||||
hint=match *.1 {
|
hint=match *.1 {
|
||||||
@ -306,6 +306,10 @@ impl NewEmbedderError {
|
|||||||
fault: FaultSource::User,
|
fault: FaultSource::User,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ollama_unsupported_url(url: String) -> NewEmbedderError {
|
||||||
|
Self { kind: NewEmbedderErrorKind::OllamaUnsupportedUrl(url), fault: FaultSource::User }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
@ -369,6 +373,8 @@ pub enum NewEmbedderErrorKind {
|
|||||||
LoadModel(candle_core::Error),
|
LoadModel(candle_core::Error),
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
CouldNotParseTemplate(String),
|
CouldNotParseTemplate(String),
|
||||||
|
#[error("unsupported Ollama URL.\n - For `ollama` sources, the URL must end with `/api/embed` or `/api/embeddings`\n - Got `{0}`")]
|
||||||
|
OllamaUnsupportedUrl(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PossibleEmbeddingMistakes {
|
pub struct PossibleEmbeddingMistakes {
|
||||||
|
@ -38,26 +38,46 @@ impl EmbedderOptions {
|
|||||||
dimensions,
|
dimensions,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_rest_embedder_config(self) -> Result<RestEmbedderOptions, NewEmbedderError> {
|
||||||
|
let url = self.url.unwrap_or_else(get_ollama_path);
|
||||||
|
let model = self.embedding_model.as_str();
|
||||||
|
|
||||||
|
// **warning**: do not swap these two `if`s, as the second one is always true when the first one is.
|
||||||
|
let (request, response) = if url.ends_with("/api/embeddings") {
|
||||||
|
(
|
||||||
|
serde_json::json!({"model": model, "input": [super::rest::REQUEST_PLACEHOLDER, super::rest::REPEAT_PLACEHOLDER]}),
|
||||||
|
serde_json::json!({"embeddings": [super::rest::RESPONSE_PLACEHOLDER, super::rest::REPEAT_PLACEHOLDER]}),
|
||||||
|
)
|
||||||
|
} else if url.ends_with("/api/embed") {
|
||||||
|
(
|
||||||
|
serde_json::json!({
|
||||||
|
"model": model,
|
||||||
|
"prompt": super::rest::REQUEST_PLACEHOLDER,
|
||||||
|
}),
|
||||||
|
serde_json::json!({
|
||||||
|
"embedding": super::rest::RESPONSE_PLACEHOLDER,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return Err(NewEmbedderError::ollama_unsupported_url(url));
|
||||||
|
};
|
||||||
|
Ok(RestEmbedderOptions {
|
||||||
|
api_key: self.api_key,
|
||||||
|
dimensions: self.dimensions,
|
||||||
|
distribution: self.distribution,
|
||||||
|
url,
|
||||||
|
request,
|
||||||
|
response,
|
||||||
|
headers: Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Embedder {
|
impl Embedder {
|
||||||
pub fn new(options: EmbedderOptions) -> Result<Self, NewEmbedderError> {
|
pub fn new(options: EmbedderOptions) -> Result<Self, NewEmbedderError> {
|
||||||
let model = options.embedding_model.as_str();
|
|
||||||
let rest_embedder = match RestEmbedder::new(
|
let rest_embedder = match RestEmbedder::new(
|
||||||
RestEmbedderOptions {
|
options.into_rest_embedder_config()?,
|
||||||
api_key: options.api_key,
|
|
||||||
dimensions: options.dimensions,
|
|
||||||
distribution: options.distribution,
|
|
||||||
url: options.url.unwrap_or_else(get_ollama_path),
|
|
||||||
request: serde_json::json!({
|
|
||||||
"model": model,
|
|
||||||
"prompt": super::rest::REQUEST_PLACEHOLDER,
|
|
||||||
}),
|
|
||||||
response: serde_json::json!({
|
|
||||||
"embedding": super::rest::RESPONSE_PLACEHOLDER,
|
|
||||||
}),
|
|
||||||
headers: Default::default(),
|
|
||||||
},
|
|
||||||
super::rest::ConfigurationSource::Ollama,
|
super::rest::ConfigurationSource::Ollama,
|
||||||
) {
|
) {
|
||||||
Ok(embedder) => embedder,
|
Ok(embedder) => embedder,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user