Auftragsbuch: 'feature/pydantic-response-models' angenommen (Ein-Klick-Gate)
This commit is contained in:
@@ -3,6 +3,8 @@ Quelle ist der persistente Melde-Briefkasten (services/announce.py): Health-Wäc
|
||||
Auto-Updates, Erinnerungen, Radar/Traum/Chef-Gutachter-Crons, Auftragsbuch — alle
|
||||
autonomen Kanäle laufen dort bereits durch. Hier wird nichts Neues erhoben, nur erzählt."""
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from services import announce
|
||||
@@ -10,6 +12,19 @@ from services import announce
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
|
||||
@router.get("/chronik")
|
||||
class ChronikItem(BaseModel):
|
||||
id: int
|
||||
ts: float
|
||||
subject: str
|
||||
text: str
|
||||
source: str
|
||||
priority: str
|
||||
|
||||
|
||||
class ChronikResponse(BaseModel):
|
||||
items: list[ChronikItem]
|
||||
|
||||
|
||||
@router.get("/chronik", response_model=ChronikResponse)
|
||||
def chronik(limit: int = 150) -> dict:
|
||||
return {"items": announce.list_recent(limit)}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
"""Eigenleben-Endpoints — „Von allein"-Ansicht (Skills + Vorschlags-Bilanz), read-only."""
|
||||
"""Eigenleben-Endpoints — „Von allein“-Ansicht (Skills + Vorschlags-Bilanz), read-only."""
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
@@ -7,7 +9,36 @@ from services import eigenleben
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
|
||||
@router.get("/eigenleben")
|
||||
class SkillItem(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
kategorie: str | None
|
||||
aktiv: bool | None
|
||||
beschreibung: str
|
||||
version: str
|
||||
autor: str
|
||||
herkunft: str
|
||||
herkunft_label: str
|
||||
genutzt: int
|
||||
zuletzt_genutzt: str | None
|
||||
erstellt: str | None
|
||||
status: str
|
||||
geaendert: float
|
||||
|
||||
|
||||
class EigenlebenOverviewResponse(BaseModel):
|
||||
available: bool
|
||||
skills: list[SkillItem]
|
||||
selbst_erstellt: int
|
||||
bilanz: dict
|
||||
|
||||
|
||||
class SkillTextResponse(BaseModel):
|
||||
id: str
|
||||
text: str
|
||||
|
||||
|
||||
@router.get("/eigenleben", response_model=EigenlebenOverviewResponse)
|
||||
def get_overview() -> dict:
|
||||
return eigenleben.overview()
|
||||
|
||||
@@ -17,7 +48,7 @@ def get_overview() -> dict:
|
||||
# fällt in den SPA-Fallback (index.html, Status 200) und die UI zeigt „Konnte den
|
||||
# Skill-Text nicht laden". Die Pfad-Validierung (max. eine Ebene, keine . /..) macht
|
||||
# services.eigenleben.skill_text.
|
||||
@router.get("/eigenleben/skill/{skill_id:path}")
|
||||
@router.get("/eigenleben/skill/{skill_id:path}", response_model=SkillTextResponse)
|
||||
def get_skill(skill_id: str) -> dict:
|
||||
text = eigenleben.skill_text(skill_id)
|
||||
if text is None:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Health-/Status-Endpoint — schlanker Lebenszeichen-Check für MC 2.0."""
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from config import VERSION
|
||||
@@ -8,7 +10,15 @@ from services import gateway, llamaswap
|
||||
router = APIRouter(prefix="/api")
|
||||
|
||||
|
||||
@router.get("/health")
|
||||
class HealthResponse(BaseModel):
|
||||
status: str
|
||||
version: str
|
||||
engine_reachable: bool
|
||||
gateway_reachable: bool
|
||||
brain: dict
|
||||
|
||||
|
||||
@router.get("/health", response_model=HealthResponse)
|
||||
def health() -> dict:
|
||||
return {
|
||||
"status": "ok",
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
Konsument ist v.a. der Hermes-Agent via mcp_mc.py (reminder_create/list/delete);
|
||||
LAN-only wie alle MC2-Endpoints."""
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from services import reminders
|
||||
|
||||
router = APIRouter(prefix="/api")
|
||||
@@ -16,7 +17,20 @@ class ReminderIn(BaseModel):
|
||||
repeat: str = "" # '' einmalig | daily | weekdays | weekly
|
||||
|
||||
|
||||
@router.get("/reminders")
|
||||
class ReminderOut(BaseModel):
|
||||
id: int
|
||||
text: str
|
||||
next_ts: float
|
||||
repeat: str
|
||||
created_ts: float
|
||||
when_local: str
|
||||
|
||||
|
||||
class ReminderListResponse(BaseModel):
|
||||
items: list[ReminderOut]
|
||||
|
||||
|
||||
@router.get("/reminders", response_model=ReminderListResponse)
|
||||
def list_reminders() -> dict:
|
||||
return {"items": reminders.list_all()}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
router = APIRouter(prefix="/api")
|
||||
@@ -30,7 +32,27 @@ def _title_of(p: Path) -> str:
|
||||
return p.stem
|
||||
|
||||
|
||||
@router.get("/wissen")
|
||||
class VaultFile(BaseModel):
|
||||
path: str
|
||||
name: str
|
||||
dir: str
|
||||
title: str
|
||||
mtime: float
|
||||
neu: bool
|
||||
|
||||
|
||||
class WissenListResponse(BaseModel):
|
||||
available: bool
|
||||
files: list[VaultFile]
|
||||
|
||||
|
||||
class WissenFileResponse(BaseModel):
|
||||
path: str
|
||||
content: str
|
||||
mtime: float
|
||||
|
||||
|
||||
@router.get("/wissen", response_model=WissenListResponse)
|
||||
def list_vault() -> dict:
|
||||
"""Alle Markdown-Notizen des Vaults (relativer Pfad, Titel, Ordner, Alter)."""
|
||||
if not _available():
|
||||
@@ -54,7 +76,7 @@ def list_vault() -> dict:
|
||||
return {"available": True, "files": files}
|
||||
|
||||
|
||||
@router.get("/wissen/datei")
|
||||
@router.get("/wissen/datei", response_model=WissenFileResponse)
|
||||
def read_file(pfad: str) -> dict:
|
||||
"""Inhalt einer Vault-Notiz — Traversal hart geblockt (resolve + is_relative_to)."""
|
||||
if not _available():
|
||||
|
||||
Reference in New Issue
Block a user