Team Ai
Apppublic

Yash030/claude-code-proxy

sourceHugging Faceupdated 5mo agoView on Hugging Face
2likes
request.py87 linesDownload Raw Back to web_tools
1"""Detect forced Anthropic web server tool requests."""2 3from __future__ import annotations4 5from api.models.anthropic import MessagesRequest, Tool6 7 8def request_text(request: MessagesRequest) -> str:9    """Join all user/assistant message content into one string for tool input parsing."""10    from .parsers import content_text11 12    return "\n".join(content_text(message.content) for message in request.messages)13 14 15def forced_tool_turn_text(request: MessagesRequest) -> str:16    """Text for parsing forced server-tool inputs: latest user turn only (avoids stale history)."""17    if not request.messages:18        return ""19 20    from .parsers import content_text21 22    for message in reversed(request.messages):23        if message.role == "user":24            return content_text(message.content)25    return ""26 27 28def forced_server_tool_name(request: MessagesRequest) -> str | None:29    """Return web_search or web_fetch only when tool_choice forces that server tool."""30    tc = request.tool_choice31    if not isinstance(tc, dict):32        return None33    if tc.get("type") != "tool":34        return None35    name = tc.get("name")36    if name in {"web_search", "web_fetch"}:37        return str(name)38    return None39 40 41def has_tool_named(request: MessagesRequest, name: str) -> bool:42    return any(tool.name == name for tool in request.tools or [])43 44 45def is_web_server_tool_request(request: MessagesRequest) -> bool:46    """True when the client forces a web server tool via tool_choice (not merely listed)."""47    forced = forced_server_tool_name(request)48    if forced is None:49        return False50    return has_tool_named(request, forced)51 52 53def is_anthropic_server_tool_definition(tool: Tool) -> bool:54    """Whether ``tool`` refers to an Anthropic server tool (web_search / web_fetch family)."""55    name = (tool.name or "").strip()56    if name in ("web_search", "web_fetch"):57        return True58    typ = tool.type59    if isinstance(typ, str):60        return typ.startswith("web_search") or typ.startswith("web_fetch")61    return False62 63 64def has_listed_anthropic_server_tools(request: MessagesRequest) -> bool:65    """True when tools include web_search / web_fetch-style entries (listed, forced or not)."""66    return any(is_anthropic_server_tool_definition(t) for t in (request.tools or []))67 68 69def openai_chat_upstream_server_tool_error(70    request: MessagesRequest, *, web_tools_enabled: bool71) -> str | None:72    """Return a user-facing error when OpenAI Chat upstream cannot satisfy server-tool semantics."""73    forced = forced_server_tool_name(request)74    if forced and not web_tools_enabled:75        return (76            f"tool_choice forces Anthropic server tool {forced!r}, but local web server tools are "77            "disabled (ENABLE_WEB_SERVER_TOOLS=false). Enable them to use this tool."78        )79    if not forced and has_listed_anthropic_server_tools(request):80        return (81            "OpenAI Chat upstreams (NVIDIA NIM) cannot use listed Anthropic server tools "82            "(web_search / web_fetch) without the local web server tool handler. "83            "Set ENABLE_WEB_SERVER_TOOLS=true and force the tool with "84            "tool_choice, or remove these tools from the request."85        )86    return None87