chore: add tbpuf secrets and testing (#4292)

* add tbpuf secret

* deploy tbpuf key to prod deploy for core

* add secrets in staging and ci

* rn turbopuff test and add to integration test suite

* add tbpuf

* rename all occurences to tpuf

* remove debug prints

* buffer-puf

* add letta prefix

* add debug

* fix tests
This commit is contained in:
Kian Jones
2025-08-29 16:44:15 -07:00
committed by GitHub
parent 5f9210b808
commit b28b59a49f
2 changed files with 26 additions and 15 deletions

View File

@@ -187,21 +187,21 @@ class TurbopufferClient:
from turbopuffer import AsyncTurbopuffer
from turbopuffer.types import QueryParam
# validate inputs based on search mode first
if search_mode == "vector" and query_embedding is None:
raise ValueError("query_embedding is required for vector search mode")
if search_mode == "fts" and query_text is None:
raise ValueError("query_text is required for FTS search mode")
if search_mode == "hybrid":
if query_embedding is None or query_text is None:
raise ValueError("Both query_embedding and query_text are required for hybrid search mode")
if search_mode not in ["vector", "fts", "hybrid", "timestamp"]:
raise ValueError(f"Invalid search_mode: {search_mode}. Must be 'vector', 'fts', 'hybrid', or 'timestamp'")
# Check if we should fallback to timestamp-based retrieval
if query_embedding is None and query_text is None:
if query_embedding is None and query_text is None and search_mode not in ["timestamp"]:
# Fallback to retrieving most recent passages when no search query is provided
search_mode = "timestamp"
else:
# validate inputs based on search mode
if search_mode == "vector" and query_embedding is None:
raise ValueError("query_embedding is required for vector search mode")
if search_mode == "fts" and query_text is None:
raise ValueError("query_text is required for FTS search mode")
if search_mode == "hybrid":
if query_embedding is None or query_text is None:
raise ValueError("Both query_embedding and query_text are required for hybrid search mode")
if search_mode not in ["vector", "fts", "hybrid"]:
raise ValueError(f"Invalid search_mode: {search_mode}. Must be 'vector', 'fts', or 'hybrid'")
namespace_name = self._get_namespace_name(archive_id)

View File

@@ -7,6 +7,7 @@ from letta.config import LettaConfig
from letta.helpers.tpuf_client import TurbopufferClient, should_use_tpuf
from letta.schemas.embedding_config import EmbeddingConfig
from letta.schemas.enums import TagMatchMode, VectorDBProvider
from letta.schemas.passage import Passage
from letta.server.server import SyncServer
from letta.settings import settings
@@ -374,17 +375,27 @@ class TestTurbopufferIntegration:
assert all(isinstance(score, float) for _, score in vector_heavy_results)
# Test error handling - missing embedding for vector mode
with pytest.raises(ValueError, match="query_embedding is required"):
with pytest.raises(ValueError, match="query_embedding is required for vector search mode"):
await client.query_passages(archive_id=archive_id, search_mode="vector", top_k=3)
# Test error handling - missing text for FTS mode
with pytest.raises(ValueError, match="query_text is required"):
with pytest.raises(ValueError, match="query_text is required for FTS search mode"):
await client.query_passages(archive_id=archive_id, search_mode="fts", top_k=3)
# Test error handling - missing both for hybrid mode
# Test error handling - missing text for hybrid mode (embedding provided but text missing)
with pytest.raises(ValueError, match="Both query_embedding and query_text are required"):
await client.query_passages(archive_id=archive_id, query_embedding=[1.0, 2.0, 3.0], search_mode="hybrid", top_k=3)
# Test error handling - missing embedding for hybrid mode (text provided but embedding missing)
with pytest.raises(ValueError, match="Both query_embedding and query_text are required"):
await client.query_passages(archive_id=archive_id, query_text="test", search_mode="hybrid", top_k=3)
# Test explicit timestamp mode
timestamp_results = await client.query_passages(archive_id=archive_id, search_mode="timestamp", top_k=3)
assert len(timestamp_results) <= 3
# Should return passages ordered by timestamp (most recent first)
assert all(isinstance(passage, Passage) for passage, _ in timestamp_results)
finally:
# Clean up
try: