From 476da53cf1a93bfd43f2198dafe035b69b3ab05c Mon Sep 17 00:00:00 2001 From: lxfight <1686540385@qq.com> Date: Wed, 2 Sep 2026 14:23:20 +0800 Subject: [PATCH] fix: add missing KB parser routes for mdx/mkd/html/htm/csv select_parser and the MarkdownChunker whitelist in kb_helper were inconsistent: .mdx/.mkd were accepted by the chunker but had no parser route, so uploads failed at the parsing stage with a generic unsupported format error. .html/.htm/.csv were not routed at all although the bundled markitdown-no-magika version ships HtmlConverter and CsvConverter. Route .mdx/.mkd to TextParser (plain markdown variants, no extra dependency) and .html/.htm/.csv to MarkitdownParser. .rtf intentionally stays unsupported: markitdown-no-magika 0.1.2 registers no RTF converter (verified: conversion raises UnsupportedFormatException). --- astrbot/core/knowledge_base/parsers/util.py | 23 ++++++++++- tests/test_kb_parser_routing.py | 45 +++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/test_kb_parser_routing.py diff --git a/astrbot/core/knowledge_base/parsers/util.py b/astrbot/core/knowledge_base/parsers/util.py index a98ed60ed2..4d3eb53854 100644 --- a/astrbot/core/knowledge_base/parsers/util.py +++ b/astrbot/core/knowledge_base/parsers/util.py @@ -2,7 +2,28 @@ async def select_parser(ext: str) -> BaseParser: - if ext in {".md", ".txt", ".markdown", ".rst", ".adoc", ".xlsx", ".docx", ".xls"}: + # Markdown variants that the MarkdownChunker whitelist in kb_helper + # already accepts; parse them as plain text without extra dependencies. + if ext in {".mdx", ".mkd"}: + from .text_parser import TextParser + + return TextParser() + # Formats supported by markitdown-no-magika (verified converters: + # HtmlConverter, CsvConverter, PlainTextConverter; note it has no + # RTF converter, so .rtf stays unsupported). + if ext in { + ".csv", + ".html", + ".htm", + ".md", + ".txt", + ".markdown", + ".rst", + ".adoc", + ".xlsx", + ".docx", + ".xls", + }: from .markitdown_parser import MarkitdownParser return MarkitdownParser() diff --git a/tests/test_kb_parser_routing.py b/tests/test_kb_parser_routing.py new file mode 100644 index 0000000000..99a21d82a6 --- /dev/null +++ b/tests/test_kb_parser_routing.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +import pytest + +from astrbot.core.knowledge_base.parsers.markitdown_parser import MarkitdownParser +from astrbot.core.knowledge_base.parsers.text_parser import TextParser +from astrbot.core.knowledge_base.parsers.util import select_parser + + +@pytest.mark.parametrize("ext", [".mdx", ".mkd"]) +@pytest.mark.asyncio +async def test_markdown_variants_use_text_parser(ext: str) -> None: + # These extensions are accepted by the MarkdownChunker whitelist in + # kb_helper but previously had no parser route, so uploads always + # failed with "暂时不支持的文件格式". + parser = await select_parser(ext) + + assert isinstance(parser, TextParser) + + +@pytest.mark.parametrize("ext", [".html", ".htm", ".csv"]) +@pytest.mark.asyncio +async def test_html_csv_use_markitdown_parser(ext: str) -> None: + parser = await select_parser(ext) + + assert isinstance(parser, MarkitdownParser) + + +@pytest.mark.asyncio +async def test_markitdown_parses_html_and_csv() -> None: + html = b"

Title

Hello world

" + result = await MarkitdownParser().parse(html, "a.html") + assert "Title" in result.text and "Hello **world**" in result.text + + csv = b"name,age\nalice,1\n" + result = await MarkitdownParser().parse(csv, "a.csv") + assert "alice" in result.text + + +@pytest.mark.asyncio +async def test_rtf_still_unsupported() -> None: + # markitdown-no-magika 0.1.2 has no RTF converter, so .rtf must keep + # raising instead of being routed to a parser that cannot handle it. + with pytest.raises(ValueError, match="暂时不支持的文件格式"): + await select_parser(".rtf")