"""AI Steward 上下文缓存服务(Redis)与失效钩子。""" from __future__ import annotations import json import os import re from datetime import datetime, timezone from pathlib import Path from typing import Any, Optional from sqlalchemy import and_, case, event, func, inspect, or_, select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import Session from ...models import Project, ProjectSignalLink, Signal, Task, User, UserProject, UserWorkload from ...utils.timezone import now_cn_aware try: import redis.asyncio as redis_async from redis import Redis as RedisSync REDIS_AVAILABLE = True except Exception: # pragma: no cover REDIS_AVAILABLE = False redis_async = None RedisSync = None SYSTEM_SNAPSHOT_SCHEMA_VERSION = "2026-04-07.context-v2" SYSTEM_TTL_SECONDS = 30 * 60 USER_TTL_SECONDS = 5 * 60 SESSION_TTL_SECONDS = 60 * 60 PROJECT_LIST_TTL_SECONDS = 10 * 60 SIGNAL_PENDING_TTL_SECONDS = 5 * 60 SESSION_MAX_MESSAGES = 20 DONE_TASK_STATUSES = {"done", "completed", "closed", "resolved", "archived"} PENDING_SIGNAL_STATUSES = {"pending", "todo", "open", "待处理"} def _safe_int(value: Any, fallback: int = 0) -> int: try: return int(value) except Exception: return fallback def _json_loads(raw: Optional[str], default: Any) -> Any: if not raw: return default try: return json.loads(raw) except Exception: return default __all__ = [name for name in globals() if not name.startswith("__")]