diff --git a/app/models/assistant/function/search_family_files.rb b/app/models/assistant/function/search_family_files.rb index c9c917f0a8..3f5f914ff1 100644 --- a/app/models/assistant/function/search_family_files.rb +++ b/app/models/assistant/function/search_family_files.rb @@ -71,7 +71,10 @@ def call(params = {}) return { success: false, error: "provider_not_configured", - message: "No vector store is configured. Set VECTOR_STORE_PROVIDER or configure OpenAI." + message: "No vector store is configured. Set VECTOR_STORE_PROVIDER " \ + "(openai | pgvector | qdrant), configure OpenAI, or — for " \ + "Anthropic-only installs — enable the pgvector adapter and " \ + "point EMBEDDING_URI_BASE at an embeddings endpoint." } end diff --git a/app/models/vector_store/registry.rb b/app/models/vector_store/registry.rb index 10c73d770d..3a0becb48f 100644 --- a/app/models/vector_store/registry.rb +++ b/app/models/vector_store/registry.rb @@ -24,7 +24,14 @@ def adapter_name explicit = ENV["VECTOR_STORE_PROVIDER"].presence return explicit.to_sym if explicit && ADAPTERS.key?(explicit.to_sym) - # Default: use OpenAI when credentials are available + # Default routing: + # - When the configured LLM provider is Anthropic (which has no hosted + # vector store), fall back to the local pgvector adapter. The + # Embeddable concern still pulls embeddings from EMBEDDING_URI_BASE / + # OPENAI_ACCESS_TOKEN — Anthropic users typically point this at + # Voyage AI, a local Ollama instance, or OpenAI embeddings. + # - Otherwise, use OpenAI when credentials are available. + return :pgvector if Setting.llm_provider == "anthropic" :openai if openai_access_token.present? end diff --git a/test/models/vector_store/registry_test.rb b/test/models/vector_store/registry_test.rb index 514b30b24e..80c5d7be8b 100644 --- a/test/models/vector_store/registry_test.rb +++ b/test/models/vector_store/registry_test.rb @@ -50,6 +50,29 @@ class VectorStore::RegistryTest < ActiveSupport::TestCase end end + test "adapter_name defaults to pgvector when LLM_PROVIDER is anthropic" do + Setting.stubs(:llm_provider).returns("anthropic") + VectorStore::Registry.stubs(:openai_access_token).returns(nil) + ClimateControl.modify(VECTOR_STORE_PROVIDER: nil) do + assert_equal :pgvector, VectorStore::Registry.adapter_name + end + end + + test "adapter_name routes anthropic installs to pgvector even when OpenAI key is present" do + Setting.stubs(:llm_provider).returns("anthropic") + VectorStore::Registry.stubs(:openai_access_token).returns("sk-test") + ClimateControl.modify(VECTOR_STORE_PROVIDER: nil) do + assert_equal :pgvector, VectorStore::Registry.adapter_name + end + end + + test "explicit VECTOR_STORE_PROVIDER overrides anthropic default" do + Setting.stubs(:llm_provider).returns("anthropic") + ClimateControl.modify(VECTOR_STORE_PROVIDER: "qdrant") do + assert_equal :qdrant, VectorStore::Registry.adapter_name + end + end + test "configured? delegates to adapter presence" do VectorStore::Registry.stubs(:adapter).returns(nil) assert_not VectorStore.configured?