feat(search): add semantic similar session matching via Voyage AI embeddings
Adds vector-based similar session discovery using the existing Voyage AI
embedding infrastructure and pgvector cosine similarity search.
- New AISessionEmbedding model with vector(1024) column
- session_embedding_service: generate + upsert embeddings, find similar sessions
- Embeddings generated on session create (from problem_summary/domain) and
updated on resolve (adds resolution_summary)
- GET /ai-sessions/{id}/similar endpoint returns top-N similar sessions
- Migration a7c9e3b1f402 creates ai_session_embeddings table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -493,6 +493,32 @@ async def search_sessions(
|
||||
]
|
||||
|
||||
|
||||
# ── Similar Sessions ──
|
||||
|
||||
@router.get("/{session_id}/similar")
|
||||
@limiter.limit("15/minute")
|
||||
async def get_similar_sessions(
|
||||
request: Request,
|
||||
session_id: UUID,
|
||||
current_user: Annotated[User, Depends(get_current_active_user)],
|
||||
db: Annotated[AsyncSession, Depends(get_db)],
|
||||
limit: int = Query(5, ge=1, le=20),
|
||||
):
|
||||
"""Find sessions semantically similar to this one using vector embeddings."""
|
||||
from app.services.session_embedding_service import find_similar_sessions
|
||||
|
||||
if not current_user.account_id:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="No account")
|
||||
|
||||
results = await find_similar_sessions(
|
||||
session_id=session_id,
|
||||
account_id=current_user.account_id,
|
||||
db=db,
|
||||
limit=limit,
|
||||
)
|
||||
return results
|
||||
|
||||
|
||||
# ── List sessions ──
|
||||
|
||||
@router.get("", response_model=list[AISessionSummary])
|
||||
|
||||
Reference in New Issue
Block a user