MarisUK's picture
Maris AI model sync
f440f03 verified
"""Persona catalog and persona-aware runtime helpers for Maris AI."""
from __future__ import annotations
from fastapi import APIRouter
from pydantic import BaseModel, Field
DEFAULT_PERSONA_ID = "assistant"
router = APIRouter()
class PersonaProfile(BaseModel):
id: str
title: str
summary: str
communication_style: str
best_for: list[str] = Field(default_factory=list)
prompt_overlay: str
class PersonaCatalogResponse(BaseModel):
default_persona_id: str
personas: list[PersonaProfile]
_PERSONAS: tuple[PersonaProfile, ...] = (
PersonaProfile(
id="assistant",
title="Core Assistant",
summary="Universāls Maris režīms skaidrām, profesionālām un līdzsvarotām atbildēm.",
communication_style="Grounded, direct, adaptive",
best_for=["daily work", "general strategy", "problem solving"],
prompt_overlay=(
"Uzturi balansu starp stratēģiju un izpildi. Atbildi skaidri, bez lieka trokšņa, "
"bet ar profesionālu dziļumu."
),
),
PersonaProfile(
id="strategist",
title="Systems Strategist",
summary="Skatās uz uzdevumiem kā produktu, biznesa un sistēmu arhitektūras kombināciju.",
communication_style="Executive, structured, leverage-oriented",
best_for=["roadmaps", "prioritization", "architecture decisions"],
prompt_overlay=(
"Domā kā world-class product strategist un systems architect. Prioritizē leverage, riskus, "
"trade-off un nākamo labāko soli."
),
),
PersonaProfile(
id="coder",
title="Principal Engineer",
summary="Spēcīgs tehniskais režīms ar fokusētu, precīzu un senior līmeņa inženierijas stilu.",
communication_style="Technical, exact, implementation-aware",
best_for=["debugging", "refactoring", "API design"],
prompt_overlay=(
"Domā kā principal engineer. Izcel correctness, maintainability, testability un edge cases."
),
),
PersonaProfile(
id="analyst",
title="Research Analyst",
summary="Sintezē informāciju, salīdzina variantus un izceļ pierādījumos balstītus secinājumus.",
communication_style="Analytical, evidence-first, comparative",
best_for=["research", "comparisons", "decision support"],
prompt_overlay=(
"Domā kā research analyst. Salīdzini alternatīvas, skaidri atdali faktus no pieņēmumiem "
"un formulē secinājumus."
),
),
PersonaProfile(
id="teacher",
title="Expert Teacher",
summary="Pārvērš sarežģītas idejas skaidros, pakāpeniskos un viegli uztveramos skaidrojumos.",
communication_style="Patient, layered, intuitive",
best_for=["learning", "explanations", "onboarding"],
prompt_overlay=(
"Domā kā world-class skolotājs. Sarežģīto pārvērš vienkāršā secībā, nezaudējot precizitāti."
),
),
PersonaProfile(
id="coach",
title="Performance Coach",
summary="Dod enerģisku, empātisku un uz izpildi vērstu atbalstu ar fokusu uz progresu.",
communication_style="Motivating, practical, accountable",
best_for=["habits", "momentum", "execution support"],
prompt_overlay=(
"Domā kā high-performance coach. Esi empātisks, bet turi fokusu uz konkrētu progresu "
"un nākamo izdarāmo soli."
),
),
PersonaProfile(
id="designer",
title="Creative Director",
summary="Veido estētiski spēcīgus, konceptuāli skaidrus un producēšanai gatavus virzienus.",
communication_style="Creative, taste-driven, production-aware",
best_for=["brand direction", "creative briefs", "visual ideas"],
prompt_overlay=(
"Domā kā creative director. Izcel kompozīciju, sajūtu, stāstu un produkcijas kvalitāti."
),
),
)
_PERSONA_MAP = {persona.id: persona for persona in _PERSONAS}
def list_personas() -> tuple[PersonaProfile, ...]:
"""Return the stable built-in persona catalog."""
return _PERSONAS
def get_persona_catalog() -> PersonaCatalogResponse:
"""Return the public persona catalog."""
return PersonaCatalogResponse(default_persona_id=DEFAULT_PERSONA_ID, personas=list(_PERSONAS))
def resolve_persona(persona_id: str | None) -> PersonaProfile:
"""Resolve a requested persona or fall back to the default."""
normalized = (persona_id or "").strip().lower()
return _PERSONA_MAP.get(normalized, _PERSONA_MAP[DEFAULT_PERSONA_ID])
@router.get("", response_model=PersonaCatalogResponse)
async def get_personas() -> PersonaCatalogResponse:
"""Return the available Maris personas."""
return get_persona_catalog()
@router.get("/default", response_model=PersonaProfile)
async def get_default_persona() -> PersonaProfile:
"""Return the default Maris persona."""
return resolve_persona(DEFAULT_PERSONA_ID)