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
13 changes: 12 additions & 1 deletion hindsight-api/hindsight_api/api/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -1410,13 +1410,19 @@ async def lifespan(app: FastAPI):
poll_interval_ms=config.worker_poll_interval_ms,
max_retries=config.worker_max_retries,
schema=schema,
tenant_extension=getattr(memory, "_tenant_extension", None),
tenant_extension=memory.tenant_extension,
max_slots=config.worker_max_slots,
consolidation_max_slots=config.worker_consolidation_max_slots,
)
poller_task = asyncio.create_task(poller.run())
logging.info(f"Worker poller started (worker_id={worker_id})")

# Call tenant extension startup hook (e.g. JWKS fetch for Supabase)
tenant_extension = memory.tenant_extension
if tenant_extension:
await tenant_extension.on_startup()
logging.info("Tenant extension started")

# Call HTTP extension startup hook
if http_extension:
await http_extension.on_startup()
Expand All @@ -1435,6 +1441,11 @@ async def lifespan(app: FastAPI):
pass
logging.info("Worker poller stopped")

# Call tenant extension shutdown hook
if tenant_extension:
await tenant_extension.on_shutdown()
logging.info("Tenant extension stopped")

# Call HTTP extension shutdown hook
if http_extension:
await http_extension.on_shutdown()
Expand Down
5 changes: 5 additions & 0 deletions hindsight-api/hindsight_api/engine/memory_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,11 @@ def __init__(
# Store tenant extension (optional)
self._tenant_extension = tenant_extension

@property
def tenant_extension(self) -> "TenantExtension | None":
"""The configured tenant extension, if any."""
return self._tenant_extension

async def _validate_operation(self, validation_coro) -> None:
"""
Run validation if an operation validator is configured.
Expand Down
3 changes: 2 additions & 1 deletion hindsight-api/hindsight_api/extensions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"""

from hindsight_api.extensions.base import Extension
from hindsight_api.extensions.builtin import ApiKeyTenantExtension
from hindsight_api.extensions.builtin import ApiKeyTenantExtension, SupabaseTenantExtension
from hindsight_api.extensions.context import DefaultExtensionContext, ExtensionContext
from hindsight_api.extensions.http import HttpExtension
from hindsight_api.extensions.loader import load_extension
Expand Down Expand Up @@ -75,6 +75,7 @@
"MentalModelRefreshResult",
# Tenant/Auth
"ApiKeyTenantExtension",
"SupabaseTenantExtension",
"AuthenticationError",
"RequestContext",
"Tenant",
Expand Down
4 changes: 4 additions & 0 deletions hindsight-api/hindsight_api/extensions/builtin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@

Available built-in extensions:
- ApiKeyTenantExtension: Simple API key validation with public schema
- SupabaseTenantExtension: Supabase JWT validation with per-user schema isolation

Example usage:
HINDSIGHT_API_TENANT_EXTENSION=hindsight_api.extensions.builtin.tenant:ApiKeyTenantExtension
HINDSIGHT_API_TENANT_EXTENSION=hindsight_api.extensions.builtin.supabase_tenant:SupabaseTenantExtension
"""

from hindsight_api.extensions.builtin.supabase_tenant import SupabaseTenantExtension
from hindsight_api.extensions.builtin.tenant import ApiKeyTenantExtension

__all__ = [
"ApiKeyTenantExtension",
"SupabaseTenantExtension",
]
Loading