From 0118b80b63ebfa8d6ffbf588c3d6da26631e1819 Mon Sep 17 00:00:00 2001 From: chihlasm Date: Fri, 20 Mar 2026 06:25:57 +0000 Subject: [PATCH] =?UTF-8?q?fix(flowpilot):=20fix=20session=20detail=20500?= =?UTF-8?q?=20=E2=80=94=20build=20AISessionDetail=20manually?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: AISessionDetail.model_validate(session) tried to validate the ORM relationship 'steps' which has field 'id', but AISessionStepResponse expects 'step_id'. This caused a Pydantic ValidationError on every session detail load. Fix: Construct AISessionDetail manually from ORM fields, passing the already-built step_responses list directly instead of relying on model_validate to serialize the ORM steps relationship. Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/app/api/endpoints/ai_sessions.py | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/backend/app/api/endpoints/ai_sessions.py b/backend/app/api/endpoints/ai_sessions.py index 7b80b935..891bbb92 100644 --- a/backend/app/api/endpoints/ai_sessions.py +++ b/backend/app/api/endpoints/ai_sessions.py @@ -645,16 +645,33 @@ async def get_session( confidence_score=step.confidence_at_step, )) - try: - detail = AISessionDetail.model_validate(session) - detail.steps = step_responses - return detail - except Exception as e: - logger.exception("Failed to serialize session %s: %s", session_id, e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail=f"Session serialization error: {type(e).__name__}: {str(e)[:200]}", - ) + # Build detail manually — AISessionDetail.model_validate(session) fails because + # the ORM relationship 'steps' has 'id' not 'step_id', causing validation errors. + # Instead, extract non-step fields from ORM and set step_responses separately. + detail = AISessionDetail( + id=session.id, + status=session.status, + intake_type=session.intake_type, + intake_content=session.intake_content or {}, + problem_summary=session.problem_summary, + problem_domain=session.problem_domain, + confidence_tier=session.confidence_tier, + step_count=session.step_count, + session_rating=session.session_rating, + psa_ticket_id=session.psa_ticket_id, + psa_connection_id=session.psa_connection_id, + escalation_reason=session.escalation_reason, + matched_flow_id=session.matched_flow_id, + match_score=getattr(session, 'match_score', None), + resolution_summary=session.resolution_summary, + resolution_action=getattr(session, 'resolution_action', None), + session_feedback=session.session_feedback, + ticket_data=session.ticket_data, + created_at=session.created_at, + resolved_at=session.resolved_at, + steps=step_responses, + ) + return detail # ── Documentation ──