interrupts.py 1.4 KB

1234567891011121314151617181920212223242526272829303132333435
  1. """HTTP 中断适配:领域错误映射为状态码,执行层不依赖请求模型。"""
  2. from fastapi import HTTPException
  3. from runtime.events import EventBuilder
  4. from runtime.interrupts import pack, token_for, ResumeDecision, ResumeError
  5. from runtime.interrupts import interrupt_event, resume_value as resolve_resume, official_resume
  6. from api.sse_events import serialize_event
  7. def decision_from_request(request) -> ResumeDecision:
  8. return ResumeDecision(interrupt_token=request.interrupt_token or "", approved=request.approved,
  9. status=request.status, answers=request.answers, error=request.error)
  10. def interrupt_frame(writer, payload):
  11. builder = EventBuilder(writer.session_id, writer.trace_id, encode=lambda event: event)
  12. return serialize_event(interrupt_event(builder, payload))
  13. def resume_value(request, state):
  14. try:
  15. return resolve_resume(decision_from_request(request), state)
  16. except ResumeError as exc:
  17. raise _http_error(exc) from exc
  18. def to_official_resume(request, pending_count):
  19. try:
  20. return official_resume(decision_from_request(request), pending_count)
  21. except ResumeError as exc:
  22. raise _http_error(exc) from exc
  23. def _http_error(exc: ResumeError) -> HTTPException:
  24. status = 400 if exc.code in {"invalid_answers", "invalid_decision"} else 409
  25. return HTTPException(status_code=status, detail={"code": exc.code, "message": str(exc)})