agentbond-api / app /services /context_manager.py
Karan6124's picture
feat(api): filter cases by authenticated user and protect endpoints
1ba28b2
Raw
History Blame Contribute Delete
8.42 kB
import uuid
from datetime import datetime
from typing import Optional, List, Dict, Any
from sqlalchemy.orm import Session
from app.models.schemas import CaseContext, Fact, Hypothesis, Evidence, Verification, CaseStatus
from app.models.database_models import CaseContextModel, FactModel, HypothesisModel, EvidenceModel, VerificationModel
class ContextManager:
@staticmethod
def create_context(db: Session, problem_statement: str, constraints: List[str] = None, user_id: str = None) -> CaseContext:
"""
Creates a new case context row in the database and returns the Pydantic schema representation.
"""
case_id = str(uuid.uuid4())
# 1. Create the base case model
case_db = CaseContextModel(
case_id=case_id,
user_id=user_id,
problem_statement=problem_statement,
status=CaseStatus.PENDING,
metadata_json={},
updated_at=datetime.utcnow()
)
db.add(case_db)
# 2. Add constraints as initial Facts (or keep as metadata if preferred; here we save them as string metadata list)
# We can also add default constraints
if constraints:
case_db.metadata_json = {"constraints": constraints}
db.commit()
db.refresh(case_db)
return ContextManager.get_context(db, case_id)
@staticmethod
def get_context(db: Session, case_id: str) -> Optional[CaseContext]:
"""
Retrieves a fully populated CaseContext by reading the relational database schemas.
"""
case_db = db.query(CaseContextModel).filter(CaseContextModel.case_id == case_id).first()
if not case_db:
return None
# Build list of Facts
facts = [
Fact(
id=f.id,
source=f.source,
content=f.content,
created_at=f.created_at
) for f in case_db.facts
]
# Build list of Hypotheses
hypotheses = [
Hypothesis(
id=h.id,
statement=h.statement,
status=h.status,
assigned_investigator=h.assigned_investigator,
created_at=h.created_at
) for h in case_db.hypotheses
]
# Build list of Evidence
evidence = [
Evidence(
id=e.id,
hypothesis_id=e.hypothesis_id,
source=e.source,
content=e.content,
confidence=e.confidence,
created_at=e.created_at
) for e in case_db.evidence
]
# Build list of Verifications
verifications = [
Verification(
id=v.id,
evidence_id=v.evidence_id,
valid=v.valid,
confidence_score=v.confidence_score,
context_alignment_score=v.context_alignment_score,
reason=v.reason,
created_at=v.created_at
) for v in case_db.verifications
]
# Read constraints from metadata
constraints = case_db.metadata_json.get("constraints", []) if case_db.metadata_json else []
return CaseContext(
case_id=case_db.case_id,
problem_statement=case_db.problem_statement,
status=case_db.status,
constraints=constraints,
facts=facts,
hypotheses=hypotheses,
evidence=evidence,
verifications=verifications,
metadata=case_db.metadata_json or {},
updated_at=case_db.updated_at
)
@staticmethod
def update_status(db: Session, case_id: str, status: CaseStatus) -> Optional[CaseContext]:
"""
Updates the execution status of a case.
"""
case_db = db.query(CaseContextModel).filter(CaseContextModel.case_id == case_id).first()
if not case_db:
return None
case_db.status = status.value if hasattr(status, 'value') else status
case_db.updated_at = datetime.utcnow()
db.commit()
return ContextManager.get_context(db, case_id)
@staticmethod
def add_facts(db: Session, case_id: str, new_facts: List[Dict[str, Any]]) -> Optional[CaseContext]:
"""
Appends facts to the shared case context database record.
"""
for fact_data in new_facts:
fact_db = FactModel(
id=str(uuid.uuid4()),
case_id=case_id,
source=fact_data.get("source", "system"),
content=fact_data["content"],
created_at=datetime.utcnow()
)
db.add(fact_db)
db.commit()
return ContextManager.get_context(db, case_id)
@staticmethod
def add_hypotheses(db: Session, case_id: str, new_hypotheses: List[Dict[str, Any]]) -> Optional[CaseContext]:
"""
Appends hypotheses to the shared case context database record.
"""
for hyp_data in new_hypotheses:
hyp_db = HypothesisModel(
id=str(uuid.uuid4()),
case_id=case_id,
statement=hyp_data["statement"],
status=hyp_data.get("status", "pending"),
assigned_investigator=hyp_data.get("assigned_investigator"),
created_at=datetime.utcnow()
)
db.add(hyp_db)
db.commit()
return ContextManager.get_context(db, case_id)
@staticmethod
def add_evidence(db: Session, case_id: str, new_evidence: List[Dict[str, Any]]) -> Optional[CaseContext]:
"""
Appends evidence to the shared case context database record.
"""
for ev_data in new_evidence:
ev_db = EvidenceModel(
id=str(uuid.uuid4()),
case_id=case_id,
hypothesis_id=ev_data["hypothesis_id"],
source=ev_data["source"],
content=ev_data["content"],
confidence=ev_data["confidence"],
created_at=datetime.utcnow()
)
db.add(ev_db)
db.commit()
return ContextManager.get_context(db, case_id)
@staticmethod
def add_verifications(db: Session, case_id: str, new_verifications: List[Dict[str, Any]]) -> Optional[CaseContext]:
"""
Appends verification metrics to the shared case context database record.
"""
for ver_data in new_verifications:
ver_db = VerificationModel(
id=str(uuid.uuid4()),
case_id=case_id,
evidence_id=ver_data["evidence_id"],
valid=ver_data["valid"],
confidence_score=ver_data["confidence_score"],
context_alignment_score=ver_data["context_alignment_score"],
reason=ver_data["reason"],
created_at=datetime.utcnow()
)
db.add(ver_db)
db.commit()
return ContextManager.get_context(db, case_id)
@staticmethod
def update_hypothesis(db: Session, hypothesis_id: str, status: str, assigned_investigator: Optional[str]= None) -> Optional[HypothesisModel]:
"""
Updates the execution status and assigned investigator of a specific hypothesis.
"""
hyp_db= db.query(HypothesisModel).filter(HypothesisModel.id == hypothesis_id).first()
if hyp_db:
hyp_db.status= status
if assigned_investigator:
hyp_db.assigned_investigator= assigned_investigator
db.commit()
db.refresh(hyp_db)
return hyp_db
@staticmethod
def get_all_contexts(db: Session, limit: int = 20, user_id: Optional[str] = None) -> List[CaseContext]:
"""
Retrieves a list of all case contexts in the database.
"""
query = db.query(CaseContextModel)
if user_id:
query = query.filter(CaseContextModel.user_id == user_id)
cases_db = query.order_by(CaseContextModel.updated_at.desc()).limit(limit).all()
result = []
for case_db in cases_db:
ctx = ContextManager.get_context(db, case_db.case_id)
if ctx:
result.append(ctx)
return result