feat(ai): default Anthropic installs to pgvector RAG (4/5)

The provider-agnostic vector store stack (VectorStore::Pgvector + the
Embeddable concern) already shipped to main. This PR closes the
Anthropic loop:

- VectorStore::Registry.adapter_name now returns :pgvector when
  Setting.llm_provider == "anthropic" and no explicit
  VECTOR_STORE_PROVIDER override is set. Anthropic has no hosted vector
  store, so falling back to the local pgvector adapter is the only
  correct default. Explicit VECTOR_STORE_PROVIDER still wins.
- SearchFamilyFiles surfaces a longer message when no adapter is wired
  up — calling out pgvector + EMBEDDING_URI_BASE as the supported
  Anthropic-only path so the user is not stuck with an "OpenAI required"
  hint that is no longer accurate.

The Embeddable concern already pulls embeddings from
EMBEDDING_URI_BASE / EMBEDDING_ACCESS_TOKEN (with OpenAI as fallback),
so Anthropic installs point this at Voyage AI, a local Ollama instance,
or OpenAI embeddings — independent of the chat provider.

Tests cover the new default routing, the existing OpenAI default
staying intact, and explicit VECTOR_STORE_PROVIDER overriding the
Anthropic default.

Stacked on #1985 (PR 3/5). 5/5 settings UI + retention disclosure next.
This commit is contained in:
Guillem Arias
2026-05-25 16:46:19 +02:00
parent 039b1fd8ee
commit 566dd75c27
3 changed files with 35 additions and 2 deletions

View File

@@ -71,7 +71,10 @@ class Assistant::Function::SearchFamilyFiles < Assistant::Function
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

View File

@@ -24,7 +24,14 @@ class VectorStore::Registry
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

View File

@@ -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?