Files
X-Financial/server/src/app/services/knowledge_ingest_status.py

70 lines
2.3 KiB
Python
Raw Normal View History

from __future__ import annotations
from datetime import UTC, datetime
from typing import Any
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.core.agent_enums import AgentRunStatus
from app.models.agent_run import AgentRun
from app.services.knowledge_constants import (
KNOWLEDGE_INGEST_STATUS_META,
KNOWLEDGE_INGEST_STATUS_PUBLISHED,
KNOWLEDGE_INGEST_SYNC_STALE_SECONDS,
)
def normalize_ingest_status_code(value: Any) -> int:
try:
status_code = int(value)
except (TypeError, ValueError):
return KNOWLEDGE_INGEST_STATUS_PUBLISHED
if status_code not in KNOWLEDGE_INGEST_STATUS_META:
return KNOWLEDGE_INGEST_STATUS_PUBLISHED
return status_code
def is_syncing_status_stale(entry: dict[str, Any]) -> bool:
raw_value = str(entry.get("ingest_status_updated_at") or "").strip()
if not raw_value:
return True
try:
updated_at = datetime.fromisoformat(raw_value)
except ValueError:
return True
if updated_at.tzinfo is None:
updated_at = updated_at.replace(tzinfo=UTC)
age_seconds = (datetime.now(UTC) - updated_at.astimezone(UTC)).total_seconds()
return age_seconds >= KNOWLEDGE_INGEST_SYNC_STALE_SECONDS
def should_preserve_syncing_status(entry: dict[str, Any], *, db: Session | None) -> bool:
agent_run_id = str(entry.get("ingest_agent_run_id") or "").strip()
if not agent_run_id or db is None:
return not is_syncing_status_stale(entry)
run = db.scalar(select(AgentRun).where(AgentRun.run_id == agent_run_id))
if run is None:
return not is_syncing_status_stale(entry)
if run.status != AgentRunStatus.RUNNING.value:
return False
heartbeat_at = str((run.route_json or {}).get("heartbeat_at") or "").strip()
if heartbeat_at:
probe_entry = {"ingest_status_updated_at": heartbeat_at}
return not is_syncing_status_stale(probe_entry)
return not is_syncing_status_stale(entry)
def resolve_linked_ingest_run_status(entry: dict[str, Any], *, db: Session | None) -> str:
agent_run_id = str(entry.get("ingest_agent_run_id") or "").strip()
if not agent_run_id or db is None:
return ""
run = db.scalar(select(AgentRun).where(AgentRun.run_id == agent_run_id))
if run is None:
return ""
return str(run.status or "").strip()