Files
repo-scoping/src/repo_scoping/web_api/schemas.py
tegwick 084159e51c chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-05-15:
  - update .custodian-brief.md for repo-scoping
2026-05-15 21:14:21 +02:00

1239 lines
35 KiB
Python

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 ErrorResponse(BaseModel):
detail: str
model_config = {
"json_schema_extra": {
"examples": [
{"detail": "repository 999 was not found"},
{"detail": "target candidate must be different from source"},
]
}
}
class RepositoryCreate(BaseModel):
url: str
name: str | None = None
description: str | None = None
branch: str = "main"
access_username: str | None = None
access_password: str | None = Field(default=None, repr=False)
model_config = {
"json_schema_extra": {
"examples": [
{
"url": "https://github.com/example/repository.git",
"name": "Example Repository",
"description": "Optional human-readable repository summary.",
"branch": "main",
"access_username": None,
"access_password": None,
}
]
}
}
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"
target_kind: str = "capability"
target_id: int | None = None
reference_kind: str = "source"
reference_id: int | None = None
model_config = {
"json_schema_extra": {
"examples": [
{
"capability_id": 1,
"type": "unit_test",
"reference": "tests/test_email_classification.py",
"strength": "strong",
"target_kind": "capability",
"reference_kind": "source",
}
]
}
}
class EvidenceUpdate(BaseModel):
type: str | None = None
reference: str | None = None
strength: str | None = None
target_kind: str | None = None
target_id: int | None = None
reference_kind: str | None = None
reference_id: int | None = None
class AnalysisRunCreate(BaseModel):
source_path: str | None = None
use_cached_checkout: bool = False
use_llm_assistance: bool = True
agentic_review: bool = Field(
default=False,
description=(
"Request configured agentic review after analysis; candidates remain "
"pending when no reviewer is configured."
),
)
trusted_auto_approve: bool = Field(
default=False,
description=(
"Deprecated compatibility input. Requests are routed to agentic "
"review and do not deterministically approve candidates."
),
)
access_username: str | None = None
access_password: str | None = Field(default=None, repr=False)
model_config = {
"json_schema_extra": {
"examples": [
{},
{"source_path": "/path/to/local/repository"},
{"use_cached_checkout": True},
{"use_llm_assistance": False},
{"agentic_review": True},
{
"access_username": "git-user",
"access_password": "access-token",
},
]
}
}
class ExpectationGapCreate(BaseModel):
analysis_run_id: int | None = None
expected_type: str
expected_name: str
source: str = "human"
notes: str = ""
model_config = {
"json_schema_extra": {
"examples": [
{
"analysis_run_id": 1,
"expected_type": "capability",
"expected_name": "Use OpenRouter Models",
"source": "human",
"notes": "Expected from README/provider config but absent from candidates.",
}
]
}
}
class ExpectationGapResponse(BaseModel):
id: int
repository_id: int
analysis_run_id: int | None
expected_type: str
expected_name: str
source: str
notes: str
status: str
created_at: str
class CandidateGraphApproval(BaseModel):
notes: str = ""
model_config = {
"json_schema_extra": {
"examples": [{"notes": "Approved after curator review."}]
}
}
class AnalysisRunChangeApproval(BaseModel):
notes: str = ""
model_config = {
"json_schema_extra": {
"examples": [{"notes": "Accept target run changes after review."}]
}
}
class CharacteristicRebuildRequest(BaseModel):
dry_run: bool = True
confirm: bool = False
source_path: str | None = None
use_cached_checkout: bool = False
use_llm_assistance: bool = True
class CharacteristicRebuildResponse(BaseModel):
repository: RepositoryResponse
analysis_run: AnalysisRunResponse
dry_run: bool
confirmed: bool
cleared_approved: bool
previous_counts: dict[str, int]
previous_ids: dict[str, list[int]]
candidate_counts: dict[str, int]
class DependencyGraphRule(BaseModel):
action: str
name: str | None = None
match: dict[str, Any] = Field(default_factory=dict)
class DependencyGraphAdHocFilters(BaseModel):
rules: list[dict[str, Any]] = Field(default_factory=list)
manual_overrides: dict[str, str] = Field(default_factory=dict)
class DependencyGraphProfileCreate(BaseModel):
name: str
description: str = ""
default_mode: str = "full"
filter_rules: list[dict[str, Any]] = Field(default_factory=list)
manual_overrides: dict[str, str] = Field(default_factory=dict)
class DependencyGraphProfileUpdate(BaseModel):
name: str | None = None
description: str | None = None
default_mode: str | None = None
filter_rules: list[dict[str, Any]] | None = None
manual_overrides: dict[str, str] | None = None
class DependencyGraphProfileDuplicate(BaseModel):
name: str | None = None
class DependencyGraphProfileResponse(BaseModel):
id: int
repository_id: int
name: str
description: str
default_mode: str
filter_rules: list[dict[str, Any]]
manual_overrides: dict[str, str]
created_at: str
updated_at: str
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
reviewer_type: str = "unknown"
reviewer_id: str = ""
policy_version: str = ""
criteria_version: str = ""
criterion_ids: list[str] = Field(default_factory=list)
evidence_refs: list[str] = Field(default_factory=list)
rationale: str = ""
accepted_after_edits: bool = False
decision_kind: str = "other"
class TrustedAutoApprovalMigrationRecordResponse(BaseModel):
repository_id: int
repository_name: str
repository_url: str
repository_status: str
analysis_run_id: int | None
analysis_run_status: str
scanner_version: str
review_decision_id: int
decision_created_at: str
notes: str
current_approved_ability_count: int
recommended_next_step: str
class QualityCriterionResponse(BaseModel):
id: str
title: str
category: str
severity: str
applies_to: list[str]
description: str
deterministic_action: str
deterministic_action_when: str
reviewer_guidance: str
agentic_guidance: str = ""
examples: list[str] = Field(default_factory=list)
model_config = {
"json_schema_extra": {
"examples": [
{
"id": "RREG-QC-002",
"title": "Native Utility Is Repo-Owned",
"category": "native-utility",
"severity": "high",
"applies_to": ["ability", "capability"],
"description": "Owned claims require product evidence.",
"deterministic_action": "downgraded",
"deterministic_action_when": "Evidence is dependency-only.",
"reviewer_guidance": "Check whether the repo owns the utility.",
"agentic_guidance": "Approve only with product and source evidence.",
"examples": ["Dependency use is not native product behavior."],
}
]
}
}
class QualityCriteriaRegistryResponse(BaseModel):
schema_version: str
criteria_version: str
status: str
updated_at: str
criteria: list[QualityCriterionResponse]
class QualityGateOverrideCreate(BaseModel):
criterion_id: str
element_type: str
element_id: int
reason: str
notes: 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
metadata: dict[str, Any]
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]
target_kind: str = "capability"
target_id: int | None = None
reference_kind: str = "source"
reference_id: int | None = None
class CandidateFeatureResponse(BaseModel):
id: int
name: str
type: str
primary_class: str
attributes: list[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]
primary_class: str
attributes: 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
primary_class: str
attributes: list[str]
confidence: float
status: str
source_refs: list[SourceReferenceResponse]
confidence_label: str
capabilities: list[CandidateCapabilityResponse]
class QualityGateOutcomeResponse(BaseModel):
criteria_version: str
criterion_id: str
criterion_title: str
severity: str
outcome: str
element_type: str
element_id: int
element_name: str
reason: str
class CandidateGraphResponse(BaseModel):
repository: RepositoryResponse
analysis_run: AnalysisRunResponse
abilities: list[CandidateAbilityResponse]
quality_gate_outcomes: list[QualityGateOutcomeResponse] = Field(default_factory=list)
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],
}
],
}
],
}
],
"quality_gate_outcomes": [],
}
]
}
}
class AnalysisRunDiffItemResponse(BaseModel):
change_type: str
item_type: str
key: str
base: dict[str, Any] | None = None
target: dict[str, Any] | None = None
class AnalysisRunDiffSectionResponse(BaseModel):
added: list[AnalysisRunDiffItemResponse]
removed: list[AnalysisRunDiffItemResponse]
changed: list[AnalysisRunDiffItemResponse]
weakened: list[AnalysisRunDiffItemResponse]
class AnalysisRunDiffResponse(BaseModel):
repository: RepositoryResponse
base_run: AnalysisRunResponse
target_run: AnalysisRunResponse
facts: AnalysisRunDiffSectionResponse
chunks: AnalysisRunDiffSectionResponse
candidates: AnalysisRunDiffSectionResponse
approved_entries: AnalysisRunDiffSectionResponse
model_config = {
"json_schema_extra": {
"examples": [
{
"repository": REPOSITORY_EXAMPLE,
"base_run": {**ANALYSIS_RUN_EXAMPLE, "id": 1},
"target_run": {**ANALYSIS_RUN_EXAMPLE, "id": 2},
"facts": {
"added": [
{
"change_type": "added",
"item_type": "fact",
"key": "api_route:src/routes/status.py:GET /status",
"target": {
"kind": "api_route",
"path": "src/routes/status.py",
"name": "GET /status",
},
}
],
"removed": [],
"changed": [],
"weakened": [],
},
"chunks": {
"added": [],
"removed": [],
"changed": [],
"weakened": [],
},
"candidates": {
"added": [],
"removed": [],
"changed": [],
"weakened": [
{
"change_type": "weakened",
"item_type": "capability",
"key": "classify incoming email",
"base": {"confidence": 0.9},
"target": {"confidence": 0.62},
}
],
},
"approved_entries": {
"added": [],
"removed": [],
"changed": [],
"weakened": [],
},
}
]
}
}
class EvidenceResponse(BaseModel):
id: int
type: str
reference: str
strength: str
source_refs: list[SourceReferenceResponse]
target_kind: str = "capability"
target_id: int | None = None
reference_kind: str = "source"
reference_id: int | None = None
class FeatureResponse(BaseModel):
id: int
name: str
type: str
primary_class: str
attributes: list[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]
primary_class: str
attributes: list[str]
confidence: float
confidence_label: str
features: list[FeatureResponse]
evidence: list[EvidenceResponse]
class AbilityResponse(BaseModel):
id: int
name: str
description: str
primary_class: str
attributes: list[str]
confidence: float
confidence_label: str
capabilities: list[CapabilityResponse]
class ScopeResponse(BaseModel):
id: int
name: str
description: str
confidence: float
confidence_label: str
class RepositoryAbilityMapResponse(BaseModel):
repository: RepositoryResponse
scope: ScopeResponse
abilities: list[AbilityResponse]
model_config = {
"json_schema_extra": {
"examples": [
{
"repository": REPOSITORY_EXAMPLE,
"scope": {
"id": 1,
"name": "MailRouter",
"description": "Scope root for the MailRouter repository.",
"confidence": 1.0,
"confidence_label": "high",
},
"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 RepositoryScopeContextResponse(BaseModel):
repo_slug: str = Field(
description="Slug requested by the caller after normal slugification."
)
capabilities: list[str] = Field(
description="Approved capability names from the repository ability map."
)
tags: list[str] = Field(
description=(
"Sorted union of approved ability and capability primary classes "
"plus their attributes."
)
)
scope_md_exists: bool = Field(
description=(
"True when repo-scoping can inspect a local or cached checkout and "
"root SCOPE.md exists."
)
)
scope_summary: str | None = Field(
description=(
"First non-empty paragraph of root SCOPE.md when available, "
"otherwise registry metadata."
)
)
model_config = {
"extra": "forbid",
"json_schema_extra": {
"examples": [
{
"repo_slug": "repo-scoping",
"capabilities": ["Generate SCOPE.md"],
"tags": ["api", "generation", "scope"],
"scope_md_exists": True,
"scope_summary": (
"Repository Scoping maps repositories into reviewable "
"scope graphs."
),
}
]
},
}
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
text_score: float = 0.0
vector_score: float = 0.0
hybrid_score: float = 0.0
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,
"text_score": 1.0,
"vector_score": 0.0,
"hybrid_score": 0.88,
}
]
}
}
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
class CapabilityGapRequest(BaseModel):
desired_ability: str
desired_capabilities: list[str]
repository_ids: list[int] | None = None
model_config = {
"json_schema_extra": {
"examples": [
{
"desired_ability": "Business Email Routing",
"desired_capabilities": [
"Classify Incoming Email",
"Route Email to Team",
],
"repository_ids": [1, 2],
}
]
}
}
class ComparedCapabilityResponse(BaseModel):
name: str
confidence: float
confidence_label: str
evidence_count: int
class ComparedAbilityRepositoryResponse(BaseModel):
repository_id: int
repository_name: str
confidence: float
confidence_label: str
capabilities: list[ComparedCapabilityResponse]
class ComparedAbilityResponse(BaseModel):
name: str
repositories: list[ComparedAbilityRepositoryResponse]
class UniqueCapabilityResponse(BaseModel):
repository_id: int
repository_name: str
ability_name: str
capability_name: str
class RepositoryComparisonResponse(BaseModel):
repositories: list[RepositoryResponse]
abilities: list[ComparedAbilityResponse]
unique_capabilities: list[UniqueCapabilityResponse]
model_config = {
"json_schema_extra": {
"examples": [
{
"repositories": [
REPOSITORY_EXAMPLE,
{**REPOSITORY_EXAMPLE, "id": 2, "name": "InboxWorker"},
],
"abilities": [
{
"name": "Business Email Routing",
"repositories": [
{
"repository_id": 1,
"repository_name": "MailRouter",
"confidence": 0.92,
"confidence_label": "high",
"capabilities": [
{
"name": "Classify Incoming Email",
"confidence": 0.88,
"confidence_label": "high",
"evidence_count": 2,
}
],
}
],
}
],
"unique_capabilities": [
{
"repository_id": 1,
"repository_name": "MailRouter",
"ability_name": "Business Email Routing",
"capability_name": "Classify Incoming Email",
}
],
}
]
}
}
class CapabilityGapMatchResponse(BaseModel):
capability: str
repositories: list[str]
class WeakCapabilityEvidenceResponse(BaseModel):
capability: str
repository_id: int
repository_name: str
evidence_count: int
strongest_evidence: str | None = None
confidence: float
confidence_label: str
class DuplicateCapabilityResponse(BaseModel):
capability: str
repositories: list[str]
class CapabilityGapResponse(BaseModel):
desired_ability: str
matched_capabilities: list[CapabilityGapMatchResponse]
missing_capabilities: list[str]
weakly_evidenced_capabilities: list[WeakCapabilityEvidenceResponse]
duplicate_capabilities: list[DuplicateCapabilityResponse]
model_config = {
"json_schema_extra": {
"examples": [
{
"desired_ability": "Business Email Routing",
"matched_capabilities": [
{
"capability": "Classify Incoming Email",
"repositories": ["MailRouter"],
}
],
"missing_capabilities": ["Route Email to Team"],
"weakly_evidenced_capabilities": [
{
"capability": "Classify Incoming Email",
"repository_id": 1,
"repository_name": "MailRouter",
"evidence_count": 0,
"strongest_evidence": None,
"confidence": 0.62,
"confidence_label": "medium",
}
],
"duplicate_capabilities": [
{
"capability": "Classify Incoming Email",
"repositories": ["MailRouter", "InboxWorker"],
}
],
}
]
}
}