grantforge-api / backend /schemas.py
GrantForge Bot
Deploy to Hugging Face
3b7f713
# ruff: noqa: E402
from typing import List, Optional, Dict, Any, Annotated
from pydantic import BaseModel, Field
import operator
from datetime import datetime
class UserUsageData(BaseModel):
user_id: str
wizard_iterations_today: int = 0
tokens_used_month: int = 0
last_reset_daily: Optional[datetime] = None
last_reset_monthly: Optional[datetime] = None
class FinancialData(BaseModel):
revenue: float = Field(0.0, description="Przychody za ostatni rok obrotowy")
net_profit: float = Field(0.0, description="Zysk netto")
employment: int = Field(
0, description="Liczba pe艂nych etat贸w (Roczna Jednostka Pracy)"
)
assets: float = Field(0.0, description="Suma bilansowa")
class InvestmentPlan(BaseModel):
description: str
estimated_cost: float
br_evidence: bool = False
green_transform: bool = False
digitalization: bool = False
goz_dnsh: bool = False
class CompanyProfile(BaseModel):
nip: str
pkd_codes: List[str] = Field(default_factory=list)
voivodeship: str
size: str = "M艢P" # Mikro, Ma艂a, 艢rednia, Du偶a
financials: Optional[FinancialData] = None
innovation_focus: List[str] = Field(default_factory=list)
is_in_difficulty: bool = False
br_evidence: bool = False # Dowody B+R
investment_plans: List[InvestmentPlan] = Field(default_factory=list)
class GrantCall(BaseModel):
id: str = ""
title: str
institution: str = ""
deadline: str
max_amount: float
description: str = ""
relevance_score: float = 0.0
poetic_match: str = "" # Dodane dla wirtualnego poety funduszowego
explanation: Optional[Dict[str, Any]] = None # Explainable AI Match
url: str = Field(default="", pattern=r"^(https://.*)?$", description="Link do dokumentacji naboru (musi zaczyna膰 si臋 od https://)")
status: str = ""
last_verified: str = ""
is_outdated_warning: bool = False
from typing import Literal
class CriticFeedback(BaseModel):
is_approved: bool
feedback: str
severity: Literal["low", "medium", "high"]
class AgentState(BaseModel):
messages: Annotated[list, operator.add]
profile: Optional[CompanyProfile] = None
eligible_grants: Optional[List[GrantCall]] = Field(default_factory=list)
checklist: Optional[Dict[str, bool]] = Field(default_factory=dict)
verification_results: Optional[Dict[str, Any]] = Field(default_factory=dict)
timeline_events: Optional[List[Dict]] = Field(default_factory=list)
wizard_step: int = 0
current_nabor: Optional[GrantCall] = None
current_agent: str = "supervisor"
user_id: str
tenant_id: str
program_name: Optional[str] = None
# 2026 Architecture Upgrades
blackboard: Optional[Dict[str, Any]] = Field(
default_factory=dict, description="Wsp贸lna pami臋膰 fakt贸w o firmie"
)
task_plan: Optional[List[str]] = Field(
default_factory=list, description="Lista krok贸w z Planner Agent"
)
interrupt_history: Optional[List[Dict[str, Any]]] = Field(
default_factory=list, description="Historia przerw Human-in-the-Loop"
)
document_versions: Optional[Dict[str, List[str]]] = Field(
default_factory=dict, description="Wersjonowanie generowanych fragment贸w"
)
guard_block: bool = False
# Dodatkowe pola do obs艂ugi cyklu oceny i HitL
critic_evaluation: Optional[CriticFeedback] = None
critic_iterations: int = 0
max_critic_iterations: int = 2
risk_score: Optional[Dict[str, Any]] = None
verification_status: str = "pending"
approved_by_human: bool = False
class SupervisorDecision(BaseModel):
next_agent: str
reason: Optional[str] = None
class PlanOutput(BaseModel):
steps: List[str]
class RiskScoreOutput(BaseModel):
score: int
risks: List[str]
class MatchExplanation(BaseModel):
reason: str
criteria: List[str]
risks: str
class MatchOutput(BaseModel):
relevance_score: float
poetic_match: str
explanation: Optional[MatchExplanation] = None
class ProjectQAResponse(BaseModel):
answer: str = Field(
description="Twoja odpowied藕 na pytanie poparta faktami. Tak/Nie z wyja艣nieniem, w膮tpliwo艣ciami itp."
)
sources: List[str] = Field(
default_factory=list,
description="Lista 藕r贸de艂, np. Nazwa dokumentu (paragraf/strona) lub Inne zidentyfikowane 藕r贸d艂o",
)
confidence: float = Field(
0.0, description="Poziom pewno艣ci we wnioskowaniu, od 0.0 do 1.0"
)
recommendation: str = Field(
description="Konkretna akcja dla u偶ytkownika, np. 'Skoryguj wydatek w bud偶ecie' lub 'To wymaga aneksu'."
)