mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 05:06:59 +00:00
fix(uploads): preserve separate bold spans in outline titles (#7150)
This commit is contained in:
parent
d288935865
commit
1ce0b765de
@ -2638,6 +2638,8 @@ removing the worker's temporary source. Automatic conversion remains off by defa
|
||||
|
||||
Uploaded Markdown outlines recognize ATX heading syntax, clean closing markers with a linear suffix scan, and skip HTML comment blocks and fenced and indented code examples, so hashtags and code comments do not
|
||||
crowd out real document sections from the agent's heading preview. Indented bold examples are also excluded; PDF-style bold headings with up to three leading spaces remain supported.
|
||||
Whole-title bold wrappers and adjacent PDF bold spans are cleaned; separate bold
|
||||
spans joined by ordinary text retain their markers instead of losing only the outer pair.
|
||||
Split-bold numeric table rows, including parenthesized years, signed values, and
|
||||
currency-prefixed amounts, are excluded when any block after the section number
|
||||
is a numeric column, so they do not consume the outline's heading budget.
|
||||
|
||||
@ -73,7 +73,8 @@ def _clean_bold_title(raw: str) -> str:
|
||||
|
||||
pymupdf4llm sometimes emits adjacent bold spans as ``**A** **B**`` instead
|
||||
of a single ``**A B**`` block. This helper merges those fragments and then
|
||||
strips the outermost ``**...**`` wrapper so the caller gets plain text.
|
||||
strips a whole-title ``**...**`` wrapper. Mixed bold/plain text keeps its
|
||||
delimiters rather than losing the ends of separate spans.
|
||||
|
||||
Examples::
|
||||
|
||||
@ -83,9 +84,10 @@ def _clean_bold_title(raw: str) -> str:
|
||||
"""
|
||||
# Merge adjacent bold spans: "** **" → " "
|
||||
merged = re.sub(r"\*\*\s*\*\*", " ", raw).strip()
|
||||
# Strip outermost **...** if the whole string is wrapped
|
||||
# Strip one whole-title wrapper, not the ends of separate bold spans.
|
||||
if m := re.fullmatch(r"\*\*(.+?)\*\*", merged, re.DOTALL):
|
||||
return m.group(1).strip()
|
||||
if "**" not in m.group(1):
|
||||
return m.group(1).strip()
|
||||
return merged
|
||||
|
||||
|
||||
|
||||
37
backend/tests/test_file_outline_bold_wrappers.py
Normal file
37
backend/tests/test_file_outline_bold_wrappers.py
Normal file
@ -0,0 +1,37 @@
|
||||
"""Mixed bold spans must not be mistaken for a whole-title wrapper."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from deerflow.uploads.companions import register_companion
|
||||
from deerflow.utils.file_outline import extract_outline_for_file
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("heading", "title"),
|
||||
[
|
||||
("**Revenue** and **Profit**", "**Revenue** and **Profit**"),
|
||||
("**收入**与**利润**", "**收入**与**利润**"),
|
||||
("**Before** / **After**", "**Before** / **After**"),
|
||||
("**Overview**", "Overview"),
|
||||
("**UNITED STATES** **SECURITIES**", "UNITED STATES SECURITIES"),
|
||||
("**A**\t**B**", "A B"),
|
||||
("Revenue and **Profit**", "Revenue and **Profit**"),
|
||||
("**Revenue** and Profit", "**Revenue** and Profit"),
|
||||
("Plain title", "Plain title"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("converted", [False, True])
|
||||
def test_upload_outline_only_unwraps_a_whole_bold_title(tmp_path: Path, heading: str, title: str, converted: bool) -> None:
|
||||
markdown = tmp_path / "report.md"
|
||||
original = f"Introduction\r\n\r\n## {heading} ###\r\n# Next section\r\n".encode()
|
||||
markdown.write_bytes(original)
|
||||
source = markdown
|
||||
if converted:
|
||||
source = tmp_path / "report.pdf"
|
||||
source.write_bytes(b"synthetic source; conversion not invoked")
|
||||
register_companion(source, markdown)
|
||||
|
||||
assert extract_outline_for_file(source) == ([{"title": title, "line": 3}, {"title": "Next section", "line": 4}], [])
|
||||
assert markdown.read_bytes() == original
|
||||
@ -83,6 +83,14 @@ class TestFormatOmittedSummary:
|
||||
|
||||
|
||||
class TestListUploadedFiles:
|
||||
def test_outline_preserves_separate_bold_spans(self, tmp_path):
|
||||
uploads_dir = _uploads_dir(tmp_path)
|
||||
(uploads_dir / "report.md").write_text("# **Revenue** and **Profit**\n", encoding="utf-8")
|
||||
|
||||
result = _list_uploaded_files_impl(include_outline=True, runtime=_runtime(), _paths=_paths(tmp_path))
|
||||
|
||||
assert result["files"][0]["outline"] == [{"title": "**Revenue** and **Profit**", "line": 1}]
|
||||
|
||||
def test_no_runtime_returns_empty(self):
|
||||
result = _list_uploaded_files_impl(runtime=None)
|
||||
assert result["files"] == []
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user