Ctrl K
ComunidadGuías…

butler/orchestrator/memory_bridge_ops.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Memory bridge best-effort helpers (P0-A)."""

from __future__ import annotations

import logging
from pathlib import Path
from typing import TYPE_CHECKING, Any

from butler.core.best_effort import safe_best_effort

if TYPE_CHECKING:
    from butler.orchestrator import ButlerOrchestrator

logger = logging.getLogger(__name__)


def refresh_project_facts_safe(project_memory: Any) -> None:
    def _run() -> None:
        project_memory.refresh_facts()

    safe_best_effort(_run, label="memory_bridge.refresh_facts", default=None)


def close_tenant_memory_safe(mem: Any) -> None:
    def _run() -> None:
        mem.close()

    safe_best_effort(_run, label="memory_bridge.close_tenant_memory", default=None)


def clear_memory_degradation_safe() -> None:
    def _run() -> None:
        from butler.ops.degradation_registry import clear_degradation

        clear_degradation("memory")

    safe_best_effort(_run, label="memory_bridge.clear_degradation", default=None)


def register_memory_degradation_safe(detail: str) -> None:
    def _run() -> None:
        from butler.ops.degradation_registry import register_degradation

        register_degradation("memory", "初始化失败", detail=detail[:200])

    safe_best_effort(_run, label="memory_bridge.register_degradation", default=None)


def initialize_memory_provider_loud(orch: ButlerOrchestrator) -> None:
    """Initialize memory provider; on failure set orch offline and register degradation."""
    try:
        from butler.memory.facade import ButlerMemoryService

        provider = ButlerMemoryService()
        provider.link_orchestrator(orch)
        provider.initialize(
            session_id=f"{orch.channel}:{orch.user_id}",
            user_id=orch.user_id,
        )
        orch.memory_provider = provider
        orch.memory_offline = False
        orch._memory_init_error = ""
        clear_memory_degradation_safe()
    except Exception as exc:
        logger.error(
            "Butler memory provider unavailable: %s",
            exc,
            exc_info=exc,
        )
        orch.memory_provider = None
        orch.memory_offline = True
        orch._memory_init_error = f"{type(exc).__name__}: {exc}"
        register_memory_degradation_safe(orch._memory_init_error)


def refresh_memory_provider_branches_safe(provider: Any) -> None:
    def _run() -> None:
        if hasattr(provider, "_turn_buffer"):
            provider._turn_buffer.clear()
        if hasattr(provider, "_reload_butler_global"):
            provider._reload_butler_global()
        if hasattr(provider, "_reload_project_branch"):
            provider._reload_project_branch()

    safe_best_effort(_run, label="memory_bridge.refresh_provider", default=None)


def design_context_block_safe(
    workspace: Path,
    *,
    design_preset: str = "",
) -> str:
    def _run() -> str:
        from butler.core.design_md_sections import build_design_context_block

        return str(
            build_design_context_block(workspace, design_preset=design_preset) or ""
        ).strip()

    result = safe_best_effort(_run, label="memory_bridge.design_context", default="")
    return str(result or "").strip()


def outcome_context_block_safe(workspace: Path, *, project: str) -> str:
    def _run() -> str:
        from butler.experiments.outcomes import format_context_for_prompt

        return str(format_context_for_prompt(workspace, project=project) or "").strip()

    result = safe_best_effort(_run, label="memory_bridge.outcome_context", default="")
    return str(result or "").strip()