from __future__ import annotations from typing import Any from pydantic import BaseModel, Field REPOSITORY_EXAMPLE = { "id": 1, "name": "MailRouter", "url": "https://github.com/example/mail-router.git", "description": "Routes incoming customer email.", "branch": "main", "status": "indexed", } ANALYSIS_RUN_EXAMPLE = { "id": 1, "repository_id": 1, "snapshot_id": 1, "status": "completed", "started_at": "2026-04-26T09:00:00Z", "completed_at": "2026-04-26T09:00:03Z", "error_message": None, "scanner_version": "deterministic-v1", } SOURCE_REFERENCE_EXAMPLE = { "fact_id": 12, "path": "src/routes/classify_email.py", "kind": "api_route", "name": "POST /api/classify-email", "line": 42, } class RepositoryCreate(BaseModel): url: str name: str | None = None description: str | None = None branch: str = "main" model_config = { "json_schema_extra": { "examples": [ { "url": "https://github.com/example/repository.git", "name": "Example Repository", "description": "Optional human-readable repository summary.", "branch": "main", } ] } } class RepositoryUpdate(BaseModel): name: str | None = None description: str | None = None branch: str | None = None model_config = { "json_schema_extra": { "examples": [ { "name": "Renamed Repository", "description": "Updated curator-facing summary.", "branch": "main", } ] } } class AbilityCreate(BaseModel): name: str description: str = "" confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "name": "Business Email Routing", "description": "Route inbound messages to the right team.", "confidence": 0.92, } ] } } class AbilityUpdate(BaseModel): name: str | None = None description: str | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class CapabilityCreate(BaseModel): ability_id: int name: str description: str = "" inputs: list[str] = Field(default_factory=list) outputs: list[str] = Field(default_factory=list) confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "ability_id": 1, "name": "Classify Incoming Email", "description": "Classify messages by intent.", "inputs": ["subject", "body"], "outputs": ["intent", "confidence"], "confidence": 0.88, } ] } } class CapabilityUpdate(BaseModel): name: str | None = None description: str | None = None inputs: list[str] | None = None outputs: list[str] | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class FeatureCreate(BaseModel): capability_id: int name: str type: str location: str = "" confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "capability_id": 1, "name": "POST /api/classify-email", "type": "REST endpoint", "location": "src/routes/classify_email.py", "confidence": 0.84, } ] } } class FeatureUpdate(BaseModel): name: str | None = None type: str | None = None location: str | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class EvidenceCreate(BaseModel): capability_id: int type: str reference: str strength: str = "medium" model_config = { "json_schema_extra": { "examples": [ { "capability_id": 1, "type": "unit_test", "reference": "tests/test_email_classification.py", "strength": "strong", } ] } } class EvidenceUpdate(BaseModel): type: str | None = None reference: str | None = None strength: str | None = None class AnalysisRunCreate(BaseModel): source_path: str | None = None model_config = { "json_schema_extra": { "examples": [ {}, {"source_path": "/path/to/local/repository"}, ] } } class CandidateGraphApproval(BaseModel): notes: str = "" model_config = { "json_schema_extra": { "examples": [{"notes": "Approved after curator review."}] } } class CandidateRejection(BaseModel): notes: str = "" model_config = { "json_schema_extra": { "examples": [{"notes": "Rejected because the claim is too generic."}] } } class CandidateEdit(BaseModel): name: str description: str = "" confidence: float = Field(default=0.5, ge=0.0, le=1.0) notes: str = "" model_config = { "json_schema_extra": { "examples": [ { "name": "Service Health Monitoring", "description": "Expose health state for operational checks.", "confidence": 0.9, "notes": "Renamed from generated review seed.", } ] } } class CandidateCapabilityRelink(BaseModel): target_ability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_ability_id": 2, "notes": "Move under operational ability."} ] } } class CandidateLeafRelink(BaseModel): target_capability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ { "target_capability_id": 3, "notes": "Evidence supports a different capability.", } ] } } class CandidateAbilityMerge(BaseModel): target_ability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_ability_id": 2, "notes": "Duplicate ability wording."} ] } } class CandidateCapabilityMerge(BaseModel): target_capability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_capability_id": 3, "notes": "Duplicate capability."} ] } } class CandidateFeatureMerge(BaseModel): target_feature_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [{"target_feature_id": 4, "notes": "Duplicate route."}] } } class CandidateEvidenceMerge(BaseModel): target_evidence_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [{"target_evidence_id": 5, "notes": "Duplicate evidence."}] } } class RepositoryResponse(BaseModel): id: int name: str url: str description: str | None branch: str status: str model_config = { "json_schema_extra": { "examples": [REPOSITORY_EXAMPLE], } } class RepositorySnapshotResponse(BaseModel): id: int repository_id: int commit_hash: str branch: str source_path: str file_count: int class AnalysisRunResponse(BaseModel): id: int repository_id: int snapshot_id: int | None status: str started_at: str completed_at: str | None error_message: str | None scanner_version: str class ReviewDecisionResponse(BaseModel): id: int repository_id: int analysis_run_id: int | None action: str notes: str created_at: str class ObservedFactResponse(BaseModel): id: int repository_id: int analysis_run_id: int snapshot_id: int | None kind: str path: str name: str value: str metadata: dict[str, Any] class ContentChunkResponse(BaseModel): id: int repository_id: int analysis_run_id: int snapshot_id: int | None path: str kind: str start_line: int end_line: int text: str class ScanSummaryResponse(BaseModel): analysis_run: AnalysisRunResponse snapshot: RepositorySnapshotResponse | None facts: list[ObservedFactResponse] class SourceReferenceResponse(BaseModel): fact_id: int | None path: str kind: str name: str line: int | None = None class CandidateEvidenceResponse(BaseModel): id: int type: str reference: str strength: str status: str source_refs: list[SourceReferenceResponse] class CandidateFeatureResponse(BaseModel): id: int name: str type: str location: str confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str class CandidateCapabilityResponse(BaseModel): id: int name: str description: str inputs: list[str] outputs: list[str] confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str features: list[CandidateFeatureResponse] evidence: list[CandidateEvidenceResponse] class CandidateAbilityResponse(BaseModel): id: int name: str description: str confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str capabilities: list[CandidateCapabilityResponse] class CandidateGraphResponse(BaseModel): repository: RepositoryResponse analysis_run: AnalysisRunResponse abilities: list[CandidateAbilityResponse] model_config = { "json_schema_extra": { "examples": [ { "repository": { **REPOSITORY_EXAMPLE, "status": "reviewing", }, "analysis_run": ANALYSIS_RUN_EXAMPLE, "abilities": [ { "id": 1, "name": "Business Email Routing", "description": "Route inbound messages to the right team.", "confidence": 0.82, "confidence_label": "high", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], "capabilities": [ { "id": 1, "name": "Classify Incoming Email", "description": "Classify messages by intent.", "inputs": ["subject", "body"], "outputs": ["intent", "confidence"], "confidence": 0.78, "confidence_label": "medium", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], "features": [ { "id": 1, "name": "POST /api/classify-email", "type": "REST endpoint", "location": "src/routes/classify_email.py", "confidence": 0.84, "confidence_label": "high", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], "evidence": [ { "id": 1, "type": "unit_test", "reference": "tests/test_email_classification.py", "strength": "strong", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], } ], } ], } ] } } class EvidenceResponse(BaseModel): id: int type: str reference: str strength: str source_refs: list[SourceReferenceResponse] class FeatureResponse(BaseModel): id: int name: str type: str location: str confidence: float confidence_label: str source_refs: list[SourceReferenceResponse] class CapabilityResponse(BaseModel): id: int name: str description: str inputs: list[str] outputs: list[str] confidence: float confidence_label: str features: list[FeatureResponse] evidence: list[EvidenceResponse] class AbilityResponse(BaseModel): id: int name: str description: str confidence: float confidence_label: str capabilities: list[CapabilityResponse] class RepositoryAbilityMapResponse(BaseModel): repository: RepositoryResponse abilities: list[AbilityResponse] model_config = { "json_schema_extra": { "examples": [ { "repository": REPOSITORY_EXAMPLE, "abilities": [ { "id": 1, "name": "Business Email Routing", "description": "Route inbound messages to the right team.", "confidence": 0.92, "confidence_label": "high", "capabilities": [ { "id": 1, "name": "Classify Incoming Email", "description": "Classify messages by intent.", "inputs": ["subject", "body"], "outputs": ["intent", "confidence"], "confidence": 0.88, "confidence_label": "high", "features": [ { "id": 1, "name": "POST /api/classify-email", "type": "REST endpoint", "location": "src/routes/classify_email.py", "confidence": 0.84, "confidence_label": "high", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], "evidence": [ { "id": 1, "type": "unit_test", "reference": "tests/test_email_classification.py", "strength": "strong", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], } ], } ], } ] } } class IdResponse(BaseModel): id: int class SearchResultResponse(BaseModel): repository_id: int repository_name: str match_type: str match_name: str confidence: float confidence_label: str match_description: str matched_field: str ability_id: int | None = None ability_name: str | None = None capability_id: int | None = None capability_name: str | None = None evidence_level: str | None = None source_reference: str | None = None model_config = { "json_schema_extra": { "examples": [ { "repository_id": 1, "repository_name": "MailRouter", "match_type": "capability", "match_name": "Classify Incoming Email", "confidence": 0.88, "confidence_label": "high", "match_description": "Classify messages by intent.", "matched_field": "capability.description", "ability_id": 1, "ability_name": "Business Email Routing", "capability_id": 1, "capability_name": "Classify Incoming Email", "evidence_level": None, "source_reference": None, } ] } } class AbilitySummaryResponse(BaseModel): id: int repository_id: int repository_name: str name: str description: str confidence: float confidence_label: str class CapabilitySummaryResponse(BaseModel): id: int repository_id: int repository_name: str ability_id: int ability_name: str name: str description: str confidence: float confidence_label: str