This commit is contained in:
2026-03-26 06:10:19 -03:00
parent 731964ca10
commit e27cb5bcc3
41 changed files with 2079 additions and 95 deletions

88
core/api/detect_config.py Normal file
View File

@@ -0,0 +1,88 @@
"""
Runtime config endpoint for the detection pipeline.
GET /detect/config — read current config
PUT /detect/config — update config (takes effect on next run)
GET /detect/config/stages — list stage palette with config fields
"""
from __future__ import annotations
import logging
from fastapi import APIRouter
from pydantic import BaseModel
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/detect", tags=["detect"])
# In-memory config — persists until server restart.
# Phase 12+ moves this to DB.
_runtime_config: dict = {}
class ConfigUpdate(BaseModel):
detection: dict | None = None
ocr: dict | None = None
resolver: dict | None = None
escalation: dict | None = None
preprocessing: dict | None = None
class StageConfigInfo(BaseModel):
name: str
label: str
description: str
category: str
config_fields: list[dict]
reads: list[str]
writes: list[str]
@router.get("/config")
def read_config():
return _runtime_config
@router.put("/config")
def write_config(update: ConfigUpdate):
changes = update.model_dump(exclude_none=True)
for section, values in changes.items():
if section not in _runtime_config:
_runtime_config[section] = {}
_runtime_config[section].update(values)
logger.info("Config updated: %s", list(changes.keys()))
return _runtime_config
@router.get("/config/stages", response_model=list[StageConfigInfo])
def list_stage_configs():
"""Return the stage palette with config field metadata for the editor."""
from detect.stages import list_stages
result = []
for stage in list_stages():
info = StageConfigInfo(
name=stage.name,
label=stage.label,
description=stage.description,
category=stage.category,
config_fields=[
{
"name": f.name,
"type": f.type,
"default": f.default,
"description": f.description,
"min": f.min,
"max": f.max,
"options": f.options,
}
for f in stage.config_fields
],
reads=stage.io.reads,
writes=stage.io.writes,
)
result.append(info)
return result

View File

@@ -26,6 +26,7 @@ from strawberry.fastapi import GraphQLRouter
from core.api.chunker_sse import router as chunker_router
from core.api.detect_sse import router as detect_router
from core.api.detect_replay import router as detect_replay_router
from core.api.detect_config import router as detect_config_router
from core.api.graphql import schema as graphql_schema
CALLBACK_API_KEY = os.environ.get("CALLBACK_API_KEY", "")
@@ -60,6 +61,9 @@ app.include_router(detect_router)
# Detection replay/retry
app.include_router(detect_replay_router)
# Detection config
app.include_router(detect_config_router)
@app.get("/health")
def health():