human hand off

This commit is contained in:
debu-2 2026-10-06 07:12:55 +05:30
parent d0fee5c8f7
commit 7af776196a
34 changed files with 2941 additions and 195 deletions

View file

@ -1,5 +1,6 @@
import base64
import json
import logging
import re
from datetime import date, datetime, time, timedelta, timezone
from typing import Annotated
@ -35,10 +36,13 @@ from app.services.thread_service import (
message_event_at,
)
from app.services.external_reply_service import build_external_reply_plan, log_smtp_message_sending
from app.services.handoff_mirror_policy import GENERATED_BY_AGENT, MESSAGE_ORIGIN_AGENT
from app.services.human_handoff_service import maybe_trigger_handoff
from app.services.mailbox_scope import apply_external_scope
from app.services.thread_resolver import ThreadResolution
MESSAGE_SCOPE_EXTERNAL = "EXTERNAL"
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/emails", tags=["emails"])
@ -191,6 +195,11 @@ async def create_email(
)
created_at = utc_now()
sender_name = " ".join(
part.strip()
for part in [account.first_name, account.last_name]
if part and part.strip()
)
subject = payload.subject
if parent_message:
reply_plan = build_external_reply_plan(
@ -213,10 +222,12 @@ async def create_email(
document = {
"direction": "outbound",
"message_scope": MESSAGE_SCOPE_EXTERNAL,
"message_origin": MESSAGE_ORIGIN_AGENT,
"generated_by": GENERATED_BY_AGENT,
"account_id": str(account.id),
"sender": address(
sender,
" ".join(part for part in [account.first_name, account.last_name] if part),
sender_name,
),
"to": [address(value) for value in recipients],
"cc": [address(value) for value in cc],
@ -251,6 +262,7 @@ async def create_email(
)
internet_message_id = await deliver_email(
sender=sender,
sender_name=sender_name,
recipients=recipients,
cc=cc,
bcc=bcc,
@ -324,6 +336,22 @@ async def create_email(
"deletion_state": None,
}
)
if document["status"] == "accepted":
try:
await maybe_trigger_handoff(
database,
account_id=str(account.id),
agent_email=sender,
external_message=document,
external_thread_id=thread_id,
)
except Exception:
logger.exception(
"handoff_trigger_failed account_id=%s thread_id=%s message_id=%s",
account.id,
thread_id,
document["_id"],
)
if document["status"] == "failed":
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,