Spaces:
Paused
Paused
File size: 6,317 Bytes
0127c21 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | """
Specialist tool registry.
Phase 4 (P0). Satisfies PS requirement: "select one or more models or
tools from a predefined registry."
This registry is deliberately just data — no model code lives here yet.
Each entry describes what a task NEEDS (image count / modality / role)
and WHICH tool would be invoked once Phases 5-8 wire in real specialist
models. The router (router.py) uses this to validate inputs and to
report a selected_tool name in the execution trace.
Do not add model inference code to this file — it's a lookup table.
"""
from __future__ import annotations
from enum import Enum
from typing import Optional, TypedDict
class TaskType(str, Enum):
vqa = "vqa"
captioning = "captioning"
grounding = "grounding"
change_detection = "change_detection"
change_vqa = "change_vqa"
optical_sar = "optical_sar"
# Phase 16: follow-up chain hops 2 and 3 (uisuggestions.docx "Ask
# Follow-up" / LEFT.md §3). NOT independently PS-mandatory — these
# only ever get selected via agent/followup.py's followup_intent(),
# never via agent/router.py's keyword classifier, because they only
# make sense as a continuation of a previous grounding/change turn.
area_estimate = "area_estimate"
sar_cross_check = "sar_cross_check"
class TaskSpec(TypedDict):
label: str
ps_requirement: str
min_images: int
max_images: int
allowed_roles: set[str]
allowed_modalities: set[str]
required_modalities: Optional[set[str]] # if set, ALL of these must be present across inputs
tool: str
TASK_REGISTRY: dict[TaskType, TaskSpec] = {
TaskType.vqa: {
"label": "Visual Question Answering",
"ps_requirement": "Single-image VQA (mandatory baseline)",
"min_images": 1,
# Phase 9: up to 2 allowed (optical + SAR of the same scene) so the
# Evidence Sufficiency Engine can pick whichever is usable — the
# model itself still only ever looks at ONE image per call.
"max_images": 2,
"allowed_roles": {"single"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": None,
"tool": "vqa_model (BLIP-VQA-base, BigEarthNet-adapted where available) — Phase 5",
},
TaskType.captioning: {
"label": "Scene Captioning",
"ps_requirement": "Additional single-image task: captioning/scene description",
"min_images": 1,
"max_images": 2, # Phase 9: same optical+SAR allowance as VQA, see above
"allowed_roles": {"single"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": None,
"tool": "captioning_model — not yet integrated (Phase 5)",
},
TaskType.grounding: {
"label": "Text-Guided Region Grounding",
"ps_requirement": "Additional single-image task: text-guided region grounding",
"min_images": 1,
"max_images": 2, # Phase 9: same optical+SAR allowance as VQA, see above
"allowed_roles": {"single"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": None,
"tool": "grounding_model (OWL-ViT open-vocabulary detector) — Phase 6",
},
TaskType.change_detection: {
"label": "Bi-Temporal Change Detection",
"ps_requirement": "Multi-image change analysis (mandatory): change description/change map",
"min_images": 2,
# Phase 12: up to 4 allowed — one optical Before/After pair PLUS
# one SAR Before/After pair — so the Evidence Sufficiency Engine
# can fail over to the SAR pair when the optical pair is cloudy,
# the same way VQA/grounding already fail over to a single SAR
# image. The model itself still only ever runs on ONE pair per
# call (see evidence/sufficiency.py decide_temporal_evidence()).
"max_images": 4,
"allowed_roles": {"before", "after"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": None,
"tool": "change_model (pixel-diff z-score change map + rule-based description) — Phase 7",
},
TaskType.change_vqa: {
"label": "Change-Based Visual Question Answering",
"ps_requirement": "Multi-image change analysis (mandatory): change-based VQA",
"min_images": 2,
"max_images": 4, # Phase 12: same optical+SAR before/after allowance as above
"allowed_roles": {"before", "after"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": None,
"tool": "change_vqa_model (composite before|after image through BLIP-VQA + change map) — Phase 7",
},
TaskType.optical_sar: {
"label": "Optical–SAR Cross-Modal Analysis",
"ps_requirement": "Cross-modal pair analysis (mandatory): optical+SAR complementary extraction",
"min_images": 2,
"max_images": 2,
"allowed_roles": {"single"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": {"optical", "sar"},
"tool": "optical_sar_fusion_model (percentile-threshold agreement fusion) — Phase 8",
},
TaskType.area_estimate: {
"label": "Follow-up: Area Estimate",
"ps_requirement": (
"NOT PS-mandatory — hop 2 of the follow-up chain "
"(uisuggestions.docx 'Ask Follow-up'), only reachable via "
"agent/followup.py after a prior grounding turn"
),
"min_images": 1,
"max_images": 2,
"allowed_roles": {"single"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": None,
"tool": "area_from_geotiff_gsd (pixel-box -> km\u00b2 via source GeoTIFF georeferencing) — Phase 16",
},
TaskType.sar_cross_check: {
"label": "Follow-up: SAR Cross-Check",
"ps_requirement": (
"NOT PS-mandatory — hop 3 of the follow-up chain "
"(uisuggestions.docx 'Ask Follow-up'), only reachable via "
"agent/followup.py after a prior grounding turn"
),
"min_images": 1,
"max_images": 2,
"allowed_roles": {"single"},
"allowed_modalities": {"optical", "sar"},
"required_modalities": {"sar"},
"tool": "grounding_model (google/owlvit-base-patch32), re-run on the SAR image — Phase 16",
},
}
|