fix(pgvector, server): add rich filter operators and fix /search 502 (#5263)

This commit is contained in:
Kartik
2026-05-26 22:47:41 +05:30
committed by GitHub
parent 7f6d46050e
commit ad736d9a06
9 changed files with 723 additions and 100 deletions
+41 -19
View File
@@ -4,16 +4,10 @@ import os
import time
from typing import Any, Dict, List, Optional
from dotenv import load_dotenv
from fastapi import Depends, FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, RedirectResponse
from pydantic import BaseModel, Field
from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from sqlalchemy import func, select
import telemetry
from auth import ADMIN_API_KEY, AUTH_DISABLED, JWT_SECRET, verify_auth
from db import SessionLocal
from dotenv import load_dotenv
from errors import (
UpstreamError,
install_request_id_logging,
@@ -22,16 +16,27 @@ from errors import (
upstream_error,
upstream_error_handler,
)
from rate_limit import limiter
from db import SessionLocal
from fastapi import Depends, FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, RedirectResponse
from models import RequestLog, User
import telemetry
from routers import auth as auth_router
from pydantic import BaseModel, Field
from rate_limit import limiter
from routers import api_keys as api_keys_router
from routers import auth as auth_router
from routers import entities as entities_router
from routers import requests as requests_router
from schemas import MessageResponse
from server_state import get_current_config, get_memory_instance, initialize_state, set_session_factory, update_config
from server_state import (
get_current_config,
get_memory_instance,
initialize_state,
set_session_factory,
update_config,
)
from slowapi import _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from sqlalchemy import func, select
load_dotenv()
@@ -188,9 +193,9 @@ class MemoryUpdate(BaseModel):
class SearchRequest(BaseModel):
query: str = Field(..., description="Search query.")
user_id: Optional[str] = None
run_id: Optional[str] = None
agent_id: Optional[str] = None
user_id: Optional[str] = Field(None, description="Deprecated: pass inside `filters` instead.", deprecated=True)
run_id: Optional[str] = Field(None, description="Deprecated: pass inside `filters` instead.", deprecated=True)
agent_id: Optional[str] = Field(None, description="Deprecated: pass inside `filters` instead.", deprecated=True)
filters: Optional[Dict[str, Any]] = None
top_k: Optional[int] = Field(None, description="Maximum number of results to return.")
threshold: Optional[float] = Field(None, description="Minimum similarity score for results.")
@@ -416,8 +421,25 @@ def get_memory(memory_id: str, _auth=Depends(verify_auth)):
def search_memories(search_req: SearchRequest, _auth=Depends(verify_auth)):
"""Search for memories based on a query."""
try:
params = {k: v for k, v in search_req.model_dump().items() if v is not None and k != "query"}
return get_memory_instance().search(query=search_req.query, **params)
filters = search_req.filters or {}
deprecated_keys = []
for entity_key in ("user_id", "agent_id", "run_id"):
entity_val = getattr(search_req, entity_key, None)
if entity_val is not None:
filters[entity_key] = entity_val
deprecated_keys.append(entity_key)
if deprecated_keys:
logging.warning(
"Top-level %s in /search is deprecated. Use filters={%s} instead.",
", ".join(deprecated_keys),
", ".join(f'"{k}": "..."' for k in deprecated_keys),
)
params = {}
if search_req.top_k is not None:
params["top_k"] = search_req.top_k
if search_req.threshold is not None:
params["threshold"] = search_req.threshold
return get_memory_instance().search(query=search_req.query, filters=filters, **params)
except Exception:
raise upstream_error()