Ctrl K
ComunidadGuías…

butler/tools/toolset_profiles.py

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

Archivo original ↗Preguntar a KiBot
"""Global runtime toolset profiles (complements per-project allowlists)."""

from __future__ import annotations

import os
from typing import Any

TOOLSET_FULL = "full"
TOOLSET_WECHAT_MINIMAL = "wechat_minimal"
TOOLSET_CRON = "cron"

_PROFILES: dict[str, frozenset[str] | None] = {
    TOOLSET_FULL: None,
    TOOLSET_WECHAT_MINIMAL: frozenset({
        "read_file",
        "search_files",
        "list_directory",
        "terminal",
        "web_search",
        "butler_recall",
        "butler_remember",
        "search_transcript",
        "skills_list",
        "skill_view",
        "delegate_task",
        "run_workflow",
        "list_runtime_jobs",
    }),
    TOOLSET_CRON: frozenset({
        "read_file",
        "butler_recall",
        "list_runtime_jobs",
        "run_runtime_job",
        "search_transcript",
    }),
}


def active_toolset() -> str:
    raw = os.getenv("BUTLER_TOOLSET", TOOLSET_FULL).strip().lower()
    if raw in _PROFILES:
        return raw
    return TOOLSET_FULL


def toolset_allowed_names(toolset: str | None = None) -> frozenset[str] | None:
    """Return allowed tool names for profile, or None for no global filter."""
    key = (toolset or active_toolset()).strip().lower()
    return _PROFILES.get(key, _PROFILES[TOOLSET_FULL])


def filter_definitions_by_toolset(
    definitions: list[dict[str, Any]],
    *,
    toolset: str | None = None,
) -> list[dict[str, Any]]:
    from butler.execution_context import get_current_loop_role

    if get_current_loop_role() == "butler":
        return definitions
    allowed = toolset_allowed_names(toolset)
    if allowed is None:
        return definitions
    out: list[dict[str, Any]] = []
    for spec in definitions:
        fn_raw = spec.get("function")
        fn = fn_raw if isinstance(fn_raw, dict) else spec
        name = str(fn.get("name") or spec.get("name") or "")
        if name in allowed or name.startswith("mcp_"):
            out.append(spec)
    return out


__all__ = [
    "TOOLSET_CRON",
    "TOOLSET_FULL",
    "TOOLSET_WECHAT_MINIMAL",
    "active_toolset",
    "filter_definitions_by_toolset",
    "toolset_allowed_names",
]