Skip to content

aaa.tools.builtin

http_fetch_tool

http_fetch_tool(
    policy: FetchPolicy | None = None,
    *,
    fetcher: SafeFetcher | None = None,
    max_chars: int = 20000,
    name: str = "http_fetch",
) -> Tool

Fetch a URL (GET) and return its text. SSRF-hardened: see aaa.tools.builtin.net.

FetchPolicy dataclass

FetchPolicy(
    allowed_hosts: tuple[str, ...] = (),
    denied_hosts: tuple[str, ...] = (),
    allowed_ports: tuple[int, ...] = (80, 443),
    allow_http: bool = True,
    max_redirects: int = 5,
    max_bytes: int = 1000000,
    timeout_s: float = 20.0,
    connect_timeout_s: float = 5.0,
    content_types: tuple[str, ...] = DEFAULT_CONTENT_TYPES,
    user_agent: str = "aaa-http-fetch/1.0",
    allow_private_networks: bool = False,
    extra: Mapping[str, str] = dict(),
)

What http_fetch may reach. With no allowed_hosts every PUBLIC host is reachable: set it in production.

strict classmethod

strict(
    allowed_hosts: tuple[str, ...] | list[str], **kw: object
) -> FetchPolicy

https only, to the listed hosts only.

SafeFetcher

SafeFetcher(
    policy: FetchPolicy | None = None,
    *,
    resolver: Resolver | None = None,
    transport: AsyncBaseTransport | None = None,
    verify: SSLContext | bool = True,
)

FetchBlocked

Bases: ToolError

The request was refused by policy (said plainly, without echoing internal addresses).

read_file_tool

read_file_tool(
    root: str | Path | FileAccess,
    *,
    name: str = "read_file",
) -> Tool

list_files_tool

list_files_tool(
    root: str | Path | FileAccess,
    *,
    name: str = "list_files",
) -> Tool

FileAccess dataclass

FileAccess(
    root: Path,
    max_bytes: int = 200000,
    allow_hidden: bool = False,
    deny: tuple[str, ...] = DENY,
)

A confined view of a directory. Every path is resolved against root and must stay inside it after resolution (symlinks included).

Hidden files and directories (.git, .env) are refused unless allow_hidden, and names matching deny (keys, credentials) are refused always.

read

read(
    path: str, *, offset: int = 0, limit: int | None = None
) -> dict[str, object]

offset/limit are line numbers (0-based start, count). The result says whether it was cut.

web_search_tool

web_search_tool(
    provider: SearchProvider,
    *,
    max_results: int = 5,
    name: str = "web_search",
) -> Tool

SearchProvider

Bases: Protocol

SearXNGSearch

SearXNGSearch(
    base_url: str,
    *,
    categories: str | None = None,
    language: str | None = None,
    safesearch: int | None = None,
    timeout_s: float = 10.0,
    transport: AsyncBaseTransport | None = None,
)

A SearXNG instance you run (GET /search?q=...&format=json). The instance must have json in search.formats of its settings.yml, otherwise it answers 403.

BraveSearch

BraveSearch(
    api_key: str | None = None,
    *,
    base_url: str = "https://api.search.brave.com",
    safesearch: str = "moderate",
    country: str | None = None,
    timeout_s: float = 10.0,
    transport: AsyncBaseTransport | None = None,
)

Brave Search API (GET https://api.search.brave.com/res/v1/web/search, header X-Subscription-Token). Built from Brave's published request/response description and tested with a mock transport; not run against a live account.