feat: add source-grounded evolution and Ollama assistant
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-15 06:45:56 +02:00
parent 0baa9b069c
commit beacdf2560
37 changed files with 2246 additions and 58 deletions
+71
View File
@@ -0,0 +1,71 @@
from __future__ import annotations
from datetime import datetime
from typing import Literal
from uuid import UUID
from pydantic import BaseModel, Field
from app.schemas.operations import VectorSelectionBBox
class AssistantChatMessage(BaseModel):
role: Literal["user", "assistant"]
content: str = Field(min_length=1, max_length=4_000)
class AssistantQueryRequest(BaseModel):
question: str = Field(min_length=2, max_length=2_000)
model: str | None = Field(default=None, max_length=255)
bbox: VectorSelectionBBox | None = None
area_id: UUID | None = None
history: list[AssistantChatMessage] = Field(default_factory=list, max_length=8)
class AssistantModelRead(BaseModel):
name: str
size_bytes: int | None = None
parameter_size: str | None = None
quantization_level: str | None = None
capabilities: list[str] = Field(default_factory=list)
class AssistantStatus(BaseModel):
enabled: bool
reachable: bool
status: str
base_url: str
default_model: str | None = None
model_count: int = 0
limitation_message: str
class AssistantContextMetric(BaseModel):
theme: str
label: str
value: float
unit: str
source: str
dataset_id: UUID
observed_at: datetime | None = None
is_estimate: bool = False
class AssistantTemporalSeries(BaseModel):
temporal_series_key: str
label: str
source: str
first_year: int
last_year: int
observation_count: int
class AssistantQueryResponse(BaseModel):
answer: str
model: str
scope_label: str
context_metrics: list[AssistantContextMetric]
temporal_series: list[AssistantTemporalSeries]
source_dataset_ids: list[UUID]
warnings: list[str]
generated_at: datetime
+20
View File
@@ -12,6 +12,7 @@ class TemporalComparisonRequest(BaseModel):
earlier_dataset_id: UUID
later_dataset_id: UUID
bbox: VectorSelectionBBox
area_id: UUID | None = None
preview_limit: int = Field(default=500, ge=1, le=1000)
@@ -23,6 +24,7 @@ class TemporalDatasetRef(BaseModel):
class TemporalMetricComparison(BaseModel):
metric_key: str = "primary"
label: str
unit: str
aggregation_method: str
@@ -31,6 +33,21 @@ class TemporalMetricComparison(BaseModel):
absolute_change: float
percent_change: float | None = None
is_estimate: bool = False
warning: str | None = None
class TemporalObservationMetric(BaseModel):
metric_key: str
label: str
value: float
unit: str
aggregation_method: str
is_estimate: bool = False
class TemporalObservation(BaseModel):
dataset: TemporalDatasetRef
metrics: list[TemporalObservationMetric]
class TemporalObjectChanges(BaseModel):
@@ -46,7 +63,10 @@ class TemporalComparisonResponse(BaseModel):
earlier: TemporalDatasetRef
later: TemporalDatasetRef
selection_bbox: VectorSelectionBBox
selection_area_id: UUID | None = None
metric: TemporalMetricComparison
metrics: list[TemporalMetricComparison] = Field(default_factory=list)
timeline: list[TemporalObservation] = Field(default_factory=list)
object_changes: TemporalObjectChanges
geojson: dict
warnings: list[str]