Skip to content
Merged
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
10 changes: 0 additions & 10 deletions docker/standalone/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,6 @@ RUN chown -R hindsight:hindsight /app

USER hindsight

# Create pg0 data directory as hindsight user so that Docker seeds new named
# volumes with correct ownership (UID 1000) on first use, avoiding the
# "Permission denied" error when mounting a fresh root-owned volume.
RUN mkdir -p /home/hindsight/.pg0

ENV PATH="/app/api/.venv/bin:${PATH}"

# Pre-download tiktoken encoding (ALWAYS - required for token counting even in air-gapped envs)
Expand Down Expand Up @@ -322,11 +317,6 @@ RUN chown -R hindsight:hindsight /app

USER hindsight

# Create pg0 data directory as hindsight user so that Docker seeds new named
# volumes with correct ownership (UID 1000) on first use, avoiding the
# "Permission denied" error when mounting a fresh root-owned volume.
RUN mkdir -p /home/hindsight/.pg0

ENV PATH="/app/api/.venv/bin:${PATH}"

# Pre-download tiktoken encoding (ALWAYS - required for token counting even in air-gapped envs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,28 @@ def _detect_text_search_extension() -> str:

if text_search_extension == "vchord":
# Create vchord_bm25 extension if not exists
conn = op.get_bind()
try:
conn.execute(text("SAVEPOINT create_ext_vchord_bm25"))
op.execute("CREATE EXTENSION IF NOT EXISTS vchord_bm25 CASCADE")
conn.execute(text("RELEASE SAVEPOINT create_ext_vchord_bm25"))
except Exception:
# Extension might already exist or user lacks permissions - verify it exists
conn = op.get_bind()
conn.execute(text("ROLLBACK TO SAVEPOINT create_ext_vchord_bm25"))
result = conn.execute(text("SELECT 1 FROM pg_extension WHERE extname = 'vchord_bm25'")).fetchone()
if not result:
# Extension truly doesn't exist - re-raise the error
raise
return "vchord"
elif text_search_extension == "pg_textsearch":
# Create pg_textsearch extension if not exists
conn = op.get_bind()
try:
conn.execute(text("SAVEPOINT create_ext_pg_textsearch"))
op.execute("CREATE EXTENSION IF NOT EXISTS pg_textsearch CASCADE")
conn.execute(text("RELEASE SAVEPOINT create_ext_pg_textsearch"))
except Exception:
# Extension might already exist or user lacks permissions - verify it exists
conn = op.get_bind()
conn.execute(text("ROLLBACK TO SAVEPOINT create_ext_pg_textsearch"))
result = conn.execute(text("SELECT 1 FROM pg_extension WHERE extname = 'pg_textsearch'")).fetchone()
if not result:
# Extension truly doesn't exist - re-raise the error
raise
return "pg_textsearch"
elif text_search_extension == "native":
Expand All @@ -121,14 +123,15 @@ def upgrade() -> None:

# We keep this here as a fallback for backwards compatibility
# This may fail if user lacks permissions, which is fine if extension already exists
conn = op.get_bind()
try:
conn.execute(text("SAVEPOINT create_ext_vector"))
op.execute("CREATE EXTENSION IF NOT EXISTS vector")
conn.execute(text("RELEASE SAVEPOINT create_ext_vector"))
except Exception:
# Extension might already exist or user lacks permissions - verify it exists
conn = op.get_bind()
conn.execute(text("ROLLBACK TO SAVEPOINT create_ext_vector"))
result = conn.execute(text("SELECT 1 FROM pg_extension WHERE extname = 'vector'")).fetchone()
if not result:
# Extension truly doesn't exist - re-raise the error
raise

# Create banks table
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,26 +89,28 @@ def _detect_text_search_extension() -> str:

if text_search_extension == "vchord":
# Create vchord_bm25 extension if not exists
conn = op.get_bind()
try:
conn.execute(text("SAVEPOINT create_ext_vchord_bm25"))
op.execute("CREATE EXTENSION IF NOT EXISTS vchord_bm25 CASCADE")
conn.execute(text("RELEASE SAVEPOINT create_ext_vchord_bm25"))
except Exception:
# Extension might already exist or user lacks permissions - verify it exists
conn = op.get_bind()
conn.execute(text("ROLLBACK TO SAVEPOINT create_ext_vchord_bm25"))
result = conn.execute(text("SELECT 1 FROM pg_extension WHERE extname = 'vchord_bm25'")).fetchone()
if not result:
# Extension truly doesn't exist - re-raise the error
raise
return "vchord"
elif text_search_extension == "pg_textsearch":
# Create pg_textsearch extension if not exists
conn = op.get_bind()
try:
conn.execute(text("SAVEPOINT create_ext_pg_textsearch"))
op.execute("CREATE EXTENSION IF NOT EXISTS pg_textsearch CASCADE")
conn.execute(text("RELEASE SAVEPOINT create_ext_pg_textsearch"))
except Exception:
# Extension might already exist or user lacks permissions - verify it exists
conn = op.get_bind()
conn.execute(text("ROLLBACK TO SAVEPOINT create_ext_pg_textsearch"))
result = conn.execute(text("SELECT 1 FROM pg_extension WHERE extname = 'pg_textsearch'")).fetchone()
if not result:
# Extension truly doesn't exist - re-raise the error
raise
return "pg_textsearch"
elif text_search_extension == "native":
Expand Down
10 changes: 9 additions & 1 deletion hindsight-api/hindsight_api/pg0.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import asyncio
import logging

from pg0 import Pg0
try:
from pg0 import Pg0
except ImportError:
Pg0 = None

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -30,6 +33,11 @@ def __init__(
self._pg0: Pg0 | None = None

def _get_pg0(self) -> Pg0:
if Pg0 is None:
raise RuntimeError(
"pg0-embedded is not installed. Set HINDSIGHT_API_DATABASE_URL "
"to a postgresql:// connection string for an external PostgreSQL server."
)
if self._pg0 is None:
kwargs = {
"name": self.name,
Expand Down
1 change: 0 additions & 1 deletion hindsight-api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ dependencies = [
"httpx>=0.27.0",
"PyJWT[crypto]>=2.8.0",
"fastmcp>=2.14.0", # CVE-2025-66416
"pg0-embedded>=0.11.0",
"python-dateutil>=2.8.0",
"opentelemetry-api>=1.20.0",
"opentelemetry-sdk>=1.20.0",
Expand Down
15 changes: 0 additions & 15 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.