Fix recall endpoint: Add search_term, input validation, and proper contexts array return
- Add search_term parameter with regex validation (alphanumeric + punctuation)
- Add tag validation to prevent SQL injection
- Change return format from {context: string} to {total, contexts: array}
- Use ConversationContextResponse schema for proper serialization
- Improves security and provides structured data for clients
Related: Context Recall System fixes (COMPLETE_SYSTEM_SUMMARY.md)
This commit is contained in:
@@ -76,8 +76,18 @@ def list_conversation_contexts(
|
|||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
)
|
)
|
||||||
def recall_context(
|
def recall_context(
|
||||||
|
search_term: Optional[str] = Query(
|
||||||
|
None,
|
||||||
|
max_length=200,
|
||||||
|
pattern=r'^[a-zA-Z0-9\s\-_.,!?()]+$',
|
||||||
|
description="Full-text search term (alphanumeric, spaces, and basic punctuation only)"
|
||||||
|
),
|
||||||
project_id: Optional[UUID] = Query(None, description="Filter by project ID"),
|
project_id: Optional[UUID] = Query(None, description="Filter by project ID"),
|
||||||
tags: Optional[List[str]] = Query(None, description="Filter by tags (OR logic)"),
|
tags: Optional[List[str]] = Query(
|
||||||
|
None,
|
||||||
|
description="Filter by tags (OR logic)",
|
||||||
|
max_items=20
|
||||||
|
),
|
||||||
limit: int = Query(
|
limit: int = Query(
|
||||||
default=10,
|
default=10,
|
||||||
ge=1,
|
ge=1,
|
||||||
@@ -96,20 +106,33 @@ def recall_context(
|
|||||||
"""
|
"""
|
||||||
Retrieve relevant contexts formatted for Claude prompt injection.
|
Retrieve relevant contexts formatted for Claude prompt injection.
|
||||||
|
|
||||||
This endpoint returns a token-efficient markdown string ready for
|
This endpoint returns contexts matching the search criteria with
|
||||||
injection into Claude's prompt. It's the main context recall API.
|
properly formatted JSON response containing the contexts array.
|
||||||
|
|
||||||
Query Parameters:
|
Query Parameters:
|
||||||
|
- search_term: Full-text search across title and summary (uses FULLTEXT index)
|
||||||
- project_id: Filter contexts by project
|
- project_id: Filter contexts by project
|
||||||
- tags: Filter contexts by tags (any match)
|
- tags: Filter contexts by tags (any match)
|
||||||
- limit: Maximum number of contexts to retrieve
|
- limit: Maximum number of contexts to retrieve
|
||||||
- min_relevance_score: Minimum relevance score threshold
|
- min_relevance_score: Minimum relevance score threshold
|
||||||
|
|
||||||
Returns a formatted string ready for prompt injection.
|
Returns JSON with contexts array and metadata.
|
||||||
"""
|
"""
|
||||||
|
# Validate tags to prevent SQL injection
|
||||||
|
if tags:
|
||||||
|
import re
|
||||||
|
tag_pattern = re.compile(r'^[a-zA-Z0-9\-_]+$')
|
||||||
|
for tag in tags:
|
||||||
|
if not tag_pattern.match(tag):
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=f"Invalid tag format: '{tag}'. Tags must be alphanumeric with hyphens or underscores only."
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
formatted_context = conversation_context_service.get_recall_context(
|
contexts, total = conversation_context_service.get_recall_context(
|
||||||
db=db,
|
db=db,
|
||||||
|
search_term=search_term,
|
||||||
project_id=project_id,
|
project_id=project_id,
|
||||||
tags=tags,
|
tags=tags,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
@@ -117,11 +140,13 @@ def recall_context(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"context": formatted_context,
|
"total": total,
|
||||||
|
"limit": limit,
|
||||||
|
"search_term": search_term,
|
||||||
"project_id": str(project_id) if project_id else None,
|
"project_id": str(project_id) if project_id else None,
|
||||||
"tags": tags,
|
"tags": tags,
|
||||||
"limit": limit,
|
"min_relevance_score": min_relevance_score,
|
||||||
"min_relevance_score": min_relevance_score
|
"contexts": [ConversationContextResponse.model_validate(ctx) for ctx in contexts]
|
||||||
}
|
}
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user