65 lines
2.0 KiB
Python
65 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Any, Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
|
|
|
|
ReasoningStatus = Literal[
|
|
"avoid",
|
|
"watch",
|
|
"wait_for_trigger",
|
|
"actionable_if_confirmed",
|
|
"manage_open_position",
|
|
"reduce",
|
|
"exit",
|
|
"insufficient_evidence",
|
|
]
|
|
|
|
|
|
class EvidenceItem(BaseModel):
|
|
model_config = ConfigDict(extra="allow")
|
|
|
|
type: str = Field(min_length=1)
|
|
value: Any
|
|
source: str | None = None
|
|
observed_at: datetime | None = None
|
|
|
|
|
|
class FinancialReasoningRequest(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
ticker: str = Field(min_length=1, max_length=32)
|
|
as_of: datetime
|
|
horizon: str = "swing"
|
|
market_context: dict[str, Any] = Field(default_factory=dict)
|
|
portfolio_context: dict[str, Any] = Field(default_factory=dict)
|
|
evidence: list[EvidenceItem] = Field(min_length=1)
|
|
question: str = "Evaluate the evidence and state what would change the view."
|
|
|
|
|
|
class FinancialReasoningResponse(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
status: ReasoningStatus
|
|
thesis: str = Field(min_length=1)
|
|
bull_case: list[str] = Field(default_factory=list)
|
|
bear_case: list[str] = Field(default_factory=list)
|
|
risks: list[str] = Field(default_factory=list)
|
|
invalidation_conditions: list[str] = Field(default_factory=list)
|
|
confidence: float = Field(ge=0, le=100)
|
|
what_would_change_the_view: list[str] = Field(min_length=1)
|
|
|
|
@model_validator(mode="after")
|
|
def require_risk_definition_for_actionable_states(self) -> "FinancialReasoningResponse":
|
|
actionable = {
|
|
"actionable_if_confirmed",
|
|
"manage_open_position",
|
|
"reduce",
|
|
"exit",
|
|
}
|
|
if self.status in actionable and (not self.risks or not self.invalidation_conditions):
|
|
raise ValueError("Actionable states require risks and invalidation conditions.")
|
|
return self
|