Download src/graph_rag_service/api/models.py from anky2002/graph-rag: direct link, hf CLI and curl.
- Browser
- Download file 12.3 kB
-
https://huggingface.co/spaces/anky2002/graph-rag/resolve/main/src/graph_rag_service/api/models.py
- Command line
-
hf download hf://spaces/anky2002/graph-rag/src/graph_rag_service/api/models.py
-
curl -L -o models.py https://huggingface.co/spaces/anky2002/graph-rag/resolve/main/src/graph_rag_service/api/models.py
12.3 kB
| """ | |
| API models and schemas for requests/responses | |
| Extended with: confidence judgment, eval, temporal, GoT, community endpoints | |
| """ | |
| from pydantic import BaseModel, Field | |
| from typing import Optional, List, Dict, Any, Literal | |
| from datetime import datetime | |
| # Authentication | |
| class LoginRequest(BaseModel): | |
| username: str | |
| password: str | |
| class RegisterRequest(BaseModel): | |
| username: str | |
| password: str | |
| email: Optional[str] = None | |
| full_name: Optional[str] = None | |
| scopes: List[str] = ["read", "write"] | |
| tenant_id: Optional[str] = None # Gap #7 | |
| class TokenResponse(BaseModel): | |
| access_token: str | |
| token_type: str = "bearer" | |
| # Document Upload | |
| class DocumentUploadResponse(BaseModel): | |
| document_id: str | |
| filename: str | |
| size_bytes: int | |
| task_id: Optional[str] = None | |
| message: str | |
| class ScrapeRequest(BaseModel): | |
| url: str | |
| class CrawlRequest(BaseModel): | |
| url: str | |
| max_depth: Optional[int] = 1 | |
| max_pages: Optional[int] = 10 | |
| # Ingestion | |
| class IngestionStatusResponse(BaseModel): | |
| task_id: str | |
| status: str | |
| progress: Optional[Dict[str, Any]] = None | |
| result: Optional[Dict[str, Any]] = None | |
| # Document List | |
| class DocumentInfo(BaseModel): | |
| id: str | |
| filename: str | |
| file_type: str | |
| size_bytes: int | |
| upload_date: str | |
| class DocumentListResponse(BaseModel): | |
| documents: List[DocumentInfo] | |
| total: int | |
| # ββ Query βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class QueryRequest(BaseModel): | |
| query: str = Field(..., min_length=1, max_length=10000, description="User query") | |
| top_k: Optional[int] = Field(5, description="Number of results to retrieve") | |
| streaming: Optional[bool] = Field(False, description="Enable streaming responses") | |
| document_id: Optional[str] = Field(None, description="Filter query to a specific document") | |
| conversation_id: Optional[str] = Field(None, description="Persist memory in a conversation thread") | |
| mode: Optional[str] = Field("auto", description="Retrieval mode: auto, naive, hybrid, local_graph, global_community, hippo, cypher") | |
| use_got: Optional[bool] = Field(False, description="Enable Graph-of-Thought parallel exploration (deprecated: use mode='got')") | |
| at_time: Optional[datetime] = Field(None, description="Query knowledge graph state at this time") | |
| class ConfidenceJudgmentResponse(BaseModel): | |
| """Gap #4 β LLM-as-a-Judge response shape""" | |
| score: float | |
| reasoning: str | |
| grounded_claims: int | |
| ungrounded_claims: int | |
| hallucination_risk: Literal["low", "medium", "high"] | |
| class QueryResponse(BaseModel): | |
| answer: str | |
| sources: List[Dict[str, Any]] | |
| reasoning_chain: List[str] | |
| confidence: float | |
| # Gap #4 β real confidence breakdown | |
| confidence_judgment: Optional[ConfidenceJudgmentResponse] = None | |
| retrieval_method: str | |
| processing_time_seconds: float | |
| conversation_id: Optional[str] = None | |
| # Gap #3 β DRIFT metadata | |
| drift_expanded: Optional[bool] = False | |
| total_sub_queries: Optional[int] = 1 | |
| # Conversations Memory | |
| class Message(BaseModel): | |
| id: str | |
| role: str | |
| content: str | |
| reasoning: Optional[List[str]] = None | |
| sources: Optional[List[Dict[str, Any]]] = None | |
| confidence: Optional[float] = None | |
| hallucination_risk: Optional[str] = None | |
| created_at: str | |
| class Conversation(BaseModel): | |
| id: str | |
| title: str | |
| created_at: str | |
| updated_at: str | |
| messages: Optional[List[Message]] = [] | |
| class ConversationListResponse(BaseModel): | |
| conversations: List[Conversation] | |
| # Ontology | |
| class OntologyResponse(BaseModel): | |
| version: str | |
| entity_types: List[str] | |
| relationship_types: List[str] | |
| properties: Dict[str, List[str]] | |
| created_at: datetime | |
| approved: bool | |
| class OntologyUpdateRequest(BaseModel): | |
| entity_types: Optional[List[str]] = None | |
| relationship_types: Optional[List[str]] = None | |
| properties: Optional[Dict[str, List[str]]] = None | |
| approved: Optional[bool] = None | |
| # Graph Visualization | |
| class GraphNode(BaseModel): | |
| id: str | |
| label: str | |
| type: str | |
| description: Optional[str] = None | |
| properties: Dict[str, Any] = {} | |
| community_id: Optional[str] = None # Gap #2 | |
| valid_from: Optional[str] = None # Gap #5 | |
| valid_until: Optional[str] = None # Gap #5 | |
| class GraphEdge(BaseModel): | |
| source: str | |
| target: str | |
| type: str | |
| properties: Dict[str, Any] = {} | |
| valid_from: Optional[str] = None # Gap #5 | |
| confidence: Optional[float] = None | |
| class EntityUpdateRequest(BaseModel): | |
| name: str | |
| class GraphVisualizationResponse(BaseModel): | |
| nodes: List[GraphNode] | |
| edges: List[GraphEdge] | |
| # System Status | |
| class SystemHealthResponse(BaseModel): | |
| status: str | |
| version: str | |
| neo4j_connected: bool | |
| redis_connected: bool | |
| workers_active: int | |
| gds_version: Optional[str] = None | |
| timestamp: datetime | |
| class SystemStatsResponse(BaseModel): | |
| documents_count: int | |
| entities_count: int | |
| relationships_count: int | |
| chunks_count: int | |
| ontology_version: str | |
| # Ontology refinement | |
| class OntologyRefineRequest(BaseModel): | |
| feedback: Optional[str] = Field(None, description="Human feedback to guide LLM refinement") | |
| document_id: Optional[str] = Field(None, description="Specific document ID to source chunks from") | |
| class OntologyRefineResponse(BaseModel): | |
| version: str | |
| entity_types: List[str] | |
| relationship_types: List[str] | |
| properties: Dict[str, List[str]] | |
| created_at: datetime | |
| approved: bool | |
| changes: Optional[str] = None | |
| # Entity deduplication | |
| class DeduplicateResponse(BaseModel): | |
| merged_count: int | |
| groups: List[List[str]] | |
| # ββ Gap #8: Eval / Quality Dashboard βββββββββββββββββββββββββββββββββββββββββ | |
| class EvalRequest(BaseModel): | |
| """Request to run quality evaluation on a Q&A pair""" | |
| question: str = Field(..., description="The question that was asked") | |
| answer: str = Field(..., description="The answer that was generated") | |
| contexts: List[str] = Field(..., description="Retrieved chunk texts used to answer") | |
| ground_truth: Optional[str] = Field(None, description="Known correct answer (optional)") | |
| document_id: Optional[str] = None | |
| class EvalResponse(BaseModel): | |
| """Evaluation metrics for a Q&A pair""" | |
| question: str | |
| faithfulness: float = Field(..., description="0-1: Is answer grounded in contexts?") | |
| answer_relevancy: float = Field(..., description="0-1: Does answer address the question?") | |
| context_precision: float = Field(..., description="0-1: Are retrieved chunks relevant?") | |
| context_recall: float = Field(default=0.0, description="0-1: Did we retrieve enough info?") | |
| overall_score: float = Field(..., description="0-1: Weighted overall quality score") | |
| hallucination_detected: bool | |
| eval_id: Optional[str] = None # Neo4j node ID for trending | |
| class EvalTrendPoint(BaseModel): | |
| """Single data point for eval trending chart""" | |
| timestamp: str | |
| overall_score: float | |
| faithfulness: float | |
| answer_relevancy: float | |
| hallucination_detected: bool | |
| document_id: Optional[str] = None | |
| class EvalDashboardResponse(BaseModel): | |
| """Full eval dashboard data""" | |
| total_evaluations: int | |
| avg_overall_score: float | |
| avg_faithfulness: float | |
| avg_relevancy: float | |
| hallucination_rate: float | |
| trend_data: List[EvalTrendPoint] | |
| # ββ Gap #2: Community endpoints βββββββββββββββββββββββββββββββββββββββββββββββ | |
| class CommunityAssignResponse(BaseModel): | |
| """Response from community assignment task""" | |
| communities_found: int | |
| message: str | |
| class CommunitySummaryResponse(BaseModel): | |
| """Summary of a graph community""" | |
| community_id: str | |
| entity_count: int | |
| entities: List[str] | |
| summary: str | |
| themes: List[str] = [] | |
| # ββ Gap #9: Extended format upload βββββββββββββββββββββββββββββββββββββββββββ | |
| class SupportedFormatsResponse(BaseModel): | |
| """List of supported ingestion file formats""" | |
| formats: List[str] | |
| descriptions: Dict[str, str] | |
| # ββ MiroFish Point 1: Graph Memory Updater ββββββββββββββββββββββββββββββββββββ | |
| class GraphUpdateRequest(BaseModel): | |
| """Request to merge text directly into the live knowledge graph""" | |
| text: str = Field(..., description="Raw text to extract entities/relationships from") | |
| source_label: Optional[str] = Field( | |
| "api_push", | |
| description="Traceability tag e.g. 'api_push', 'chat:conv_123'" | |
| ) | |
| valid_from: Optional[datetime] = Field( | |
| None, | |
| description="Timestamp for temporal graph edges (default: now)" | |
| ) | |
| class GraphUpdateResponse(BaseModel): | |
| """Response from a graph memory update operation""" | |
| entities_added: int | |
| relationships_added: int | |
| entities_merged: int | |
| source_label: str | |
| timestamp: datetime | |
| message: str | |
| # ββ MiroFish Point 2: Entity Enricher ββββββββββββββββββββββββββββββββββββββββ | |
| class EnrichmentStatusResponse(BaseModel): | |
| """Response from entity enrichment task""" | |
| entities_enriched: int | |
| entities_skipped: int | |
| errors: int | |
| duration_seconds: float | |
| message: str | |
| class EntitySummaryResponse(BaseModel): | |
| """Entity profile summary returned from the graph""" | |
| entity_name: str | |
| entity_type: Optional[str] = None | |
| summary: Optional[str] = None | |
| summary_updated_at: Optional[str] = None | |
| has_summary: bool = False | |
| # ββ MiroFish Point 3: Report Agent βββββββββββββββββββββββββββββββββββββββββββ | |
| class ReportRequest(BaseModel): | |
| """Request to generate an analytical report""" | |
| topic: str = Field(..., description="High-level topic or question for analysis") | |
| report_type: Optional[Literal["executive", "detailed", "entity_focus"]] = Field( | |
| "detailed", | |
| description="'executive' (short), 'detailed' (full), 'entity_focus' (scoped to one entity)" | |
| ) | |
| target_entity: Optional[str] = Field( | |
| None, | |
| description="For entity_focus β name of the entity to focus the report on" | |
| ) | |
| class ReportResponse(BaseModel): | |
| """Analytical report generated by the ReACT ReportAgent""" | |
| topic: str | |
| executive_summary: str | |
| sections: Dict[str, str] | |
| key_entities: List[str] | |
| confidence: float | |
| tool_calls_made: int | |
| generated_at: datetime | |
| markdown: str | |
| # ββ MiroFish Point 3b: Entity Interview ββββββββββββββββββββββββββββββββββββββ | |
| class EntityChatRequest(BaseModel): | |
| """Request to chat with a single entity's knowledge neighborhood""" | |
| message: str = Field(..., description="Question to ask about the entity") | |
| conversation_id: Optional[str] = Field( | |
| None, description="Optional conversation ID for multi-turn context" | |
| ) | |
| class EntityChatResponse(BaseModel): | |
| """Response from entity-scoped chat""" | |
| response: str | |
| entity_name: str | |
| neighborhood_size: int | |
| conversation_id: str | |
| # ββ MiroFish Point 4: Ontology Drift Detection βββββββββββββββββββββββββββββββ | |
| class DriftReportResponse(BaseModel): | |
| """Schema drift report from OntologyDriftDetector""" | |
| id: str | |
| detected_at: datetime | |
| new_entity_types: List[str] | |
| new_relationship_types: List[str] | |
| removed_entity_types: List[str] | |
| removed_relationship_types: List[str] | |
| sample_size: int | |
| drift_score: float | |
| status: str | |
| approved_by: Optional[str] = None | |
| approved_at: Optional[datetime] = None | |
| class DriftListResponse(BaseModel): | |
| """List of drift reports""" | |
| reports: List[DriftReportResponse] | |
| total: int | |