Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llmstack/common/blocks/data/store/vectorstore/weaviate.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
DocumentQuery,
VectorStoreInterface,
)
from llmstack.processors.providers.weaviate import with_integration_header

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -136,7 +137,7 @@ def check_batch_result(
),
)

headers = configuration.additional_headers
headers = with_integration_header(configuration.additional_headers)
if configuration.openai_key is not None:
headers["X-OpenAI-Api-Key"] = configuration.openai_key
if configuration.cohere_api_key is not None:
Expand Down
3 changes: 3 additions & 0 deletions llmstack/data/destinations/vector_stores/weaviate.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
WeaviateCloudInstance,
WeaviateLocalInstance,
WeaviateProviderConfig,
with_integration_header,
)

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -124,6 +125,8 @@ def _create_weaviate_client(
weaviate_config: Union[WeaviateLocalInstance, WeaviateCloudInstance], auth=None, additional_headers=None
):
weaviate_client = None
# Passed at construction so the header reaches every REST request and the gRPC metadata.
additional_headers = with_integration_header(additional_headers)
if isinstance(weaviate_config, WeaviateLocalInstance):
weaviate_client = connect_to_custom(
http_host=weaviate_config.http_host,
Expand Down
27 changes: 26 additions & 1 deletion llmstack/processors/providers/weaviate/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Annotated, List, Optional, Union
import importlib.metadata
from typing import Annotated, Dict, List, Optional, Union

from pydantic import BaseModel, Field

Expand Down Expand Up @@ -93,3 +94,27 @@ class WeaviateProviderConfig(ProviderConfig):
@property
def additional_headers_dict(self):
return {header.key: header.value for header in self.additional_headers}


# Weaviate (1.38+) reads this header as `{name}/{version}` to attribute requests to
# the integration that sent them. Older servers ignore it.
INTEGRATION_HEADER = "X-Weaviate-Client-Integration"


def _integration_header_value() -> str:
try:
version = importlib.metadata.version("llmstack").strip() or "unknown"
except Exception:
version = "unknown"
return f"llmstack/{version}"


def with_integration_header(headers: Optional[Dict[str, str]]) -> Dict[str, str]:
"""Return a copy of `headers` with the X-Weaviate-Client-Integration header added.

A value already supplied by the user (any letter case) is kept as is.
"""
headers = dict(headers or {})
if not any(key.lower() == INTEGRATION_HEADER.lower() for key in headers):
headers[INTEGRATION_HEADER] = _integration_header_value()
return headers