57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
"""ClientContext middleware — injects client/project background into state."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import logging
|
||
from pathlib import Path
|
||
|
||
from app.graph.state import ReportState
|
||
from .base import Middleware
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# Client profiles stored as JSON files
|
||
CLIENTS_DIR = Path(__file__).resolve().parent.parent.parent / "clients"
|
||
|
||
|
||
class ClientContextMiddleware(Middleware):
|
||
"""Loads client profile and injects background context into state.
|
||
|
||
Client profiles are JSON files in the `clients/` directory:
|
||
clients/<client_id>.json
|
||
{
|
||
"name": "某咨询公司",
|
||
"industry": "金融",
|
||
"preferences": "偏好简洁的执行摘要,数据驱动",
|
||
"previous_reports": ["report_001", "report_002"]
|
||
}
|
||
"""
|
||
|
||
name = "client_context"
|
||
|
||
async def before(self, state: ReportState) -> ReportState:
|
||
if not state.client_id:
|
||
return state
|
||
|
||
profile_path = CLIENTS_DIR / f"{state.client_id}.json"
|
||
if not profile_path.exists():
|
||
logger.info(f"[client_context] no profile for client '{state.client_id}'")
|
||
return state
|
||
|
||
try:
|
||
profile = json.loads(profile_path.read_text(encoding="utf-8"))
|
||
parts = []
|
||
if name := profile.get("name"):
|
||
parts.append(f"客户:{name}")
|
||
if industry := profile.get("industry"):
|
||
parts.append(f"行业:{industry}")
|
||
if prefs := profile.get("preferences"):
|
||
parts.append(f"偏好:{prefs}")
|
||
state.client_context = ";".join(parts)
|
||
logger.info(f"[client_context] loaded profile for '{state.client_id}'")
|
||
except Exception as e:
|
||
logger.warning(f"[client_context] failed to load profile: {e}")
|
||
|
||
return state
|