File size: 1,891 Bytes
8d60e33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from __future__ import annotations

from typing import Optional, List, Literal
from pydantic import BaseModel, Field, ConfigDict

# ---------------------------
# Planning schema
# ---------------------------

class Health(BaseModel):
    score: Optional[float] = None
    status: Optional[str] = None
    last_checked: Optional[str] = None  # or use datetime if preferred


class RecentCheck(BaseModel):
    check: str
    result: str
    latency_ms: Optional[float] = None
    ts: Optional[str] = None  # or use datetime if preferred


class PlanContext(BaseModel):
    """
    Context is permissive: accept any extra keys from Guardian (or future sources).
    Known fields are typed below; unknown fields pass through.
    """
    model_config = ConfigDict(extra="allow")

    # Common identifiers
    app_id: Optional[str] = None
    entity_uid: Optional[str] = None

    # Known structured bits
    symptoms: Optional[List[str]] = None
    lkg: Optional[str] = None
    lkg_version: Optional[str] = None
    health: Optional[Health] = None
    recent_checks: Optional[List[RecentCheck]] = None


class PlanConstraints(BaseModel):
    max_steps: int = Field(default=3, ge=1, le=10)
    risk: Literal["low", "medium", "high"] = "low"


class PlanRequest(BaseModel):
    # default to "plan" and only allow that value for now
    mode: Literal["plan"] = "plan"
    context: PlanContext
    constraints: PlanConstraints = Field(default_factory=PlanConstraints)


class PlanResponse(BaseModel):
    plan_id: str
    steps: List[str]
    risk: str
    explanation: str


# ---------------------------
# Chat (kept for compatibility; router uses its own flexible model)
# ---------------------------

class ChatRequest(BaseModel):
    question: str = Field(..., min_length=3, max_length=512)


class ChatResponse(BaseModel):
    answer: str
    sources: List[str] = Field(default_factory=list)