feat(ai-onboarding): enhance conversation flow, prompt rules & update Postman environment port to 8001
This commit is contained in:
@@ -260,7 +260,8 @@ async def voice_turn(
|
||||
user_message=patient_transcript,
|
||||
)
|
||||
|
||||
# 6. Update Structured Clinical State
|
||||
# 6. Update Structured Clinical State using shared intelligent merge
|
||||
from app.ai.orchestrator import merge_state_updates
|
||||
current_state = json.loads(state.state_json)
|
||||
updates = ai_response.get("state_updates", {})
|
||||
if hasattr(updates, "model_dump"):
|
||||
@@ -268,16 +269,12 @@ async def voice_turn(
|
||||
elif not isinstance(updates, dict):
|
||||
updates = {}
|
||||
|
||||
for k, v in updates.items():
|
||||
if v is not None:
|
||||
if isinstance(v, list) and len(v) == 0:
|
||||
continue
|
||||
current_state[k] = v
|
||||
merged_state = merge_state_updates(current_state, updates)
|
||||
|
||||
onboarding_service.update_state(
|
||||
db=db,
|
||||
state=state,
|
||||
data=current_state,
|
||||
data=merged_state,
|
||||
)
|
||||
|
||||
# 7. Update session stage, status & auto-assigned specialty
|
||||
@@ -376,98 +373,106 @@ async def complete_voice_onboarding(
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
start_time = time.time()
|
||||
onboarding_service = OnboardingService()
|
||||
completion_service = CompletionService()
|
||||
result_service = ResultExtractionService()
|
||||
submission_service = PatientSubmissionService()
|
||||
try:
|
||||
onboarding_service = OnboardingService()
|
||||
completion_service = CompletionService()
|
||||
result_service = ResultExtractionService()
|
||||
submission_service = PatientSubmissionService()
|
||||
|
||||
session = onboarding_service.get_session(db, session_id)
|
||||
if not session:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Voice onboarding session not found",
|
||||
session = onboarding_service.get_session(db, session_id)
|
||||
if not session:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="Voice onboarding session not found",
|
||||
)
|
||||
|
||||
# 1b. Verify Session Ownership (IDOR Prevention)
|
||||
verify_session_ownership(session.patient_id, auth, detail="Forbidden: You do not have authorization to complete this voice session.")
|
||||
|
||||
state = onboarding_service.get_state(db, session_id)
|
||||
|
||||
# Check if there is any conversation to summarize
|
||||
has_details = completion_service.is_complete(session, state)
|
||||
|
||||
messages = (
|
||||
db.query(OnboardingMessage)
|
||||
.filter(OnboardingMessage.session_id == session_id)
|
||||
.order_by(OnboardingMessage.created_at.asc())
|
||||
.all()
|
||||
)
|
||||
conversation_history = [
|
||||
{"role": m.role, "message": m.message, "stage": m.stage}
|
||||
for m in messages
|
||||
]
|
||||
|
||||
result = await result_service.extract_result(
|
||||
session=session,
|
||||
state=state,
|
||||
conversation_history=conversation_history,
|
||||
)
|
||||
|
||||
# 1b. Verify Session Ownership (IDOR Prevention)
|
||||
verify_session_ownership(session.patient_id, auth, detail="Forbidden: You do not have authorization to complete this voice session.")
|
||||
elapsed = time.time() - start_time
|
||||
resp_ms = round(elapsed * 1000, 2)
|
||||
resp_sec = round(elapsed, 3)
|
||||
|
||||
state = onboarding_service.get_state(db, session_id)
|
||||
if isinstance(result, dict):
|
||||
result["onboarding_completed"] = True
|
||||
|
||||
# Check if there is any conversation to summarize
|
||||
has_details = completion_service.is_complete(session, state)
|
||||
if session.status == "completed":
|
||||
return CompleteOnboardingResponse(
|
||||
success=True,
|
||||
session_id=session_id,
|
||||
status="completed",
|
||||
result=result,
|
||||
message="Voice onboarding session is already completed.",
|
||||
response_time_ms=resp_ms,
|
||||
response_time_sec=resp_sec,
|
||||
)
|
||||
|
||||
messages = (
|
||||
db.query(OnboardingMessage)
|
||||
.filter(OnboardingMessage.session_id == session_id)
|
||||
.order_by(OnboardingMessage.created_at.asc())
|
||||
.all()
|
||||
)
|
||||
conversation_history = [
|
||||
{"role": m.role, "message": m.message, "stage": m.stage}
|
||||
for m in messages
|
||||
]
|
||||
if not request.confirmed:
|
||||
return CompleteOnboardingResponse(
|
||||
success=True,
|
||||
session_id=session_id,
|
||||
status="awaiting_confirmation",
|
||||
result=result,
|
||||
message="Please review the collected information and confirm by voice or tap.",
|
||||
response_time_ms=resp_ms,
|
||||
response_time_sec=resp_sec,
|
||||
)
|
||||
|
||||
result = await result_service.extract_result(
|
||||
session=session,
|
||||
state=state,
|
||||
conversation_history=conversation_history,
|
||||
)
|
||||
submission = await submission_service.submit(result)
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
resp_ms = round(elapsed * 1000, 2)
|
||||
resp_sec = round(elapsed, 3)
|
||||
if submission.get("success"):
|
||||
session.status = "completed"
|
||||
session.stage = "confirmation"
|
||||
db.commit()
|
||||
|
||||
if isinstance(result, dict):
|
||||
result["onboarding_completed"] = True
|
||||
return CompleteOnboardingResponse(
|
||||
success=True,
|
||||
session_id=session_id,
|
||||
status="completed",
|
||||
result=result,
|
||||
message="Voice onboarding successfully saved to patient record.",
|
||||
response_time_ms=resp_ms,
|
||||
response_time_sec=resp_sec,
|
||||
)
|
||||
|
||||
if session.status == "completed":
|
||||
return CompleteOnboardingResponse(
|
||||
success=True,
|
||||
session_id=session_id,
|
||||
status="completed",
|
||||
result=result,
|
||||
message="Voice onboarding session is already completed.",
|
||||
response_time_ms=resp_ms,
|
||||
response_time_sec=resp_sec,
|
||||
)
|
||||
|
||||
if not request.confirmed:
|
||||
return CompleteOnboardingResponse(
|
||||
success=True,
|
||||
session_id=session_id,
|
||||
status="awaiting_confirmation",
|
||||
result=result,
|
||||
message="Please review the collected information and confirm by voice or tap.",
|
||||
response_time_ms=resp_ms,
|
||||
response_time_sec=resp_sec,
|
||||
)
|
||||
|
||||
submission = await submission_service.submit(result)
|
||||
|
||||
if submission.get("success"):
|
||||
session.status = "completed"
|
||||
session.stage = "confirmation"
|
||||
session.status = "submission_pending_retry"
|
||||
db.commit()
|
||||
|
||||
return CompleteOnboardingResponse(
|
||||
success=True,
|
||||
success=False,
|
||||
session_id=session_id,
|
||||
status="completed",
|
||||
status="submission_pending_retry",
|
||||
result=result,
|
||||
message="Voice onboarding successfully saved to patient record.",
|
||||
message="Patient API submission failed. Session preserved for retry.",
|
||||
response_time_ms=resp_ms,
|
||||
response_time_sec=resp_sec,
|
||||
)
|
||||
|
||||
session.status = "submission_pending_retry"
|
||||
db.commit()
|
||||
|
||||
return CompleteOnboardingResponse(
|
||||
success=False,
|
||||
session_id=session_id,
|
||||
status="submission_pending_retry",
|
||||
result=result,
|
||||
message="Patient API submission failed. Session preserved for retry.",
|
||||
response_time_ms=resp_ms,
|
||||
response_time_sec=resp_sec,
|
||||
)
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as err:
|
||||
import traceback
|
||||
print(f"[CompleteVoiceOnboarding Error]: {err}")
|
||||
traceback.print_exc()
|
||||
raise HTTPException(status_code=500, detail=str(err))
|
||||
|
||||
Reference in New Issue
Block a user