From b8a2b7f0b0758b3cf8f7841d9f4ae9b1472711cd Mon Sep 17 00:00:00 2001 From: Yufeng He <40085740+universeplayer@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:11:49 +0800 Subject: [PATCH 1/2] fix: guard trafilatura import to prevent cascading tool load failure on Python 3.13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Python 3.13, charset-normalizer ships mypyc-compiled binaries that are incompatible, causing trafilatura to fail at import time. Since web/__init__.py unconditionally imports FetchURL (which imports trafilatura at module level), the entire web package fails to load — taking SearchWeb down with it even though SearchWeb has no trafilatura dependency. Wrap the trafilatura import in try/except and fall back to returning raw page content when it's unavailable. This keeps both tools loadable regardless of the trafilatura situation. Fixes #1572 --- src/kimi_cli/tools/web/fetch.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/kimi_cli/tools/web/fetch.py b/src/kimi_cli/tools/web/fetch.py index dbe3fe5f5..bd8ec0280 100644 --- a/src/kimi_cli/tools/web/fetch.py +++ b/src/kimi_cli/tools/web/fetch.py @@ -2,7 +2,6 @@ from typing import override import aiohttp -import trafilatura from kosong.tooling import CallableTool2, ToolReturnValue from pydantic import BaseModel, Field @@ -14,6 +13,13 @@ from kimi_cli.utils.aiohttp import new_client_session from kimi_cli.utils.logging import logger +try: + import trafilatura + + _has_trafilatura = True +except Exception: + _has_trafilatura = False + class Params(BaseModel): url: str = Field(description="The URL to fetch content from.") @@ -92,6 +98,14 @@ async def fetch_with_http_get(params: Params) -> ToolReturnValue: brief="Empty response body", ) + if not _has_trafilatura: + # trafilatura unavailable (e.g. charset-normalizer binary + # incompatible with current Python), return raw HTML trimmed + builder.write(resp_text[:50000]) + return builder.ok( + "trafilatura is not available; returning raw page content." + ) + extracted_text = trafilatura.extract( resp_text, include_comments=True, From d78db0cc0428b0c2b23c62dd46a2820a2b4cd4e1 Mon Sep 17 00:00:00 2001 From: Yufeng He <40085740+universeplayer@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:54:59 +0800 Subject: [PATCH 2/2] style: fix ruff format for fetch.py --- src/kimi_cli/tools/web/fetch.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/kimi_cli/tools/web/fetch.py b/src/kimi_cli/tools/web/fetch.py index bd8ec0280..7c01302a1 100644 --- a/src/kimi_cli/tools/web/fetch.py +++ b/src/kimi_cli/tools/web/fetch.py @@ -102,9 +102,7 @@ async def fetch_with_http_get(params: Params) -> ToolReturnValue: # trafilatura unavailable (e.g. charset-normalizer binary # incompatible with current Python), return raw HTML trimmed builder.write(resp_text[:50000]) - return builder.ok( - "trafilatura is not available; returning raw page content." - ) + return builder.ok("trafilatura is not available; returning raw page content.") extracted_text = trafilatura.extract( resp_text,