Ctrl K
ComunidadGuías…

butler/mcp/github_tool_aliases.py

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

Archivo original ↗Preguntar a KiBot
"""Resolve common LLM mis-names for GitHub MCP tools (EXT-4)."""

from __future__ import annotations

import os
import re
from typing import Any

from butler.defaults.env_defaults import GITHUB_DEFAULT_OWNER_DEFAULT

_GITHUB_TOOL_ALIASES: dict[str, str] = {
    "mcp_github_get_issues": "mcp_github_lst_repo_issues",
    "mcp_github_list_issues": "mcp_github_lst_repo_issues",
    "mcp_github_list_repo_issues": "mcp_github_lst_repo_issues",
    "mcp_github_get_repository_issues": "mcp_github_lst_repo_issues",
    "mcp_github_list_repos": "mcp_github_lst_repos_authenticated_usr",
    "mcp_github_list_repositories": "mcp_github_lst_repos_authenticated_usr",
}


def resolve_github_mcp_tool_name(name: str) -> str:
    key = str(name or "").strip()
    if key in _GITHUB_TOOL_ALIASES:
        return _GITHUB_TOOL_ALIASES[key]
    from butler.mcp.github_tool_aliases_ops import resolve_mcp_tool_alias_safe

    resolved = resolve_mcp_tool_alias_safe(key)
    if resolved != key:
        return str(resolved)
    return key


def default_github_owner() -> str:
    return os.getenv("BUTLER_GITHUB_DEFAULT_OWNER", GITHUB_DEFAULT_OWNER_DEFAULT).strip() or GITHUB_DEFAULT_OWNER_DEFAULT


def parse_github_owner_repo(
    text: str,
    args: dict[str, Any] | None = None,
) -> tuple[str, str]:
    """Best-effort owner/repo from tool args or user text."""
    raw_args = dict(args or {})
    owner = str(raw_args.get("owner") or "").strip()
    repo = str(raw_args.get("repo") or raw_args.get("repository") or "").strip()
    if owner and repo:
        return owner, repo
    if repo and "/" in repo:
        left, right = repo.split("/", 1)
        return left.strip(), right.strip()
    user_text = str(text or "").strip()
    slash = re.search(r"([\w.-]+)/([\w.-]+)", user_text)
    if slash:
        return slash.group(1), slash.group(2)
    if not repo:
        m = re.search(
            r"(?:列出|list|查看|查|看看)\s*([\w.-]+)\s*的\s*issues?",
            user_text,
            re.IGNORECASE,
        )
        if m:
            repo = m.group(1)
        else:
            m2 = re.search(r"\b([\w.-]+)\s*的\s*issues?\b", user_text, re.IGNORECASE)
            if m2:
                repo = m2.group(1)
    if not owner:
        owner = default_github_owner()
    return owner, repo


def normalize_github_mcp_args(
    tool_name: str,
    args: dict[str, Any],
    *,
    user_text: str = "",
) -> dict[str, Any]:
    out = dict(args or {})
    resolved = resolve_github_mcp_tool_name(tool_name)
    if resolved == "mcp_github_lst_repo_issues":
        owner, repo = parse_github_owner_repo(user_text, out)
        if owner:
            out["owner"] = owner
        if repo:
            out["repo"] = repo
        out.pop("repository", None)
        state = str(out.get("state") or "").strip().lower()
        if not state:
            if any(k in str(user_text or "") for k in ("全部", "所有", "all", "关闭", "closed")):
                out["state"] = "all" if any(k in str(user_text or "").lower() for k in ("全部", "所有", "all")) else "closed"
            else:
                out["state"] = "open"
    return out