From 94e441c5f7eca6cce323e1feb6d15fde1bbab91c Mon Sep 17 00:00:00 2001 From: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com> Date: Thu, 1 Oct 2026 09:24:20 -0400 Subject: [PATCH] fix(markdown): resolve optional token threshold defaults Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com> --- pageindex/page_index_md.py | 4 +++ tests/test_page_index_md.py | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/pageindex/page_index_md.py b/pageindex/page_index_md.py index 86ef2a145..2e2bc5982 100644 --- a/pageindex/page_index_md.py +++ b/pageindex/page_index_md.py @@ -243,6 +243,10 @@ def clean_tree_for_output(tree_nodes): async def md_to_tree(md_path, if_thinning=False, min_token_threshold=None, if_add_node_summary='no', summary_token_threshold=None, model=None, if_add_doc_description='no', if_add_node_text='no', if_add_node_id='yes', summary_model=None): + if min_token_threshold is None: + min_token_threshold = 5000 + if summary_token_threshold is None: + summary_token_threshold = 200 with open(md_path, 'r', encoding='utf-8') as f: markdown_content = f.read() line_count = markdown_content.count('\n') + 1 diff --git a/tests/test_page_index_md.py b/tests/test_page_index_md.py index 0f4581090..9335e09cd 100644 --- a/tests/test_page_index_md.py +++ b/tests/test_page_index_md.py @@ -101,5 +101,74 @@ def test_md_cli_summary_model_drives_summary_calls(self): ["SUMMARY-SENTINEL"], res.stdout.decode()) +class MarkdownOptionalThresholdTest(unittest.TestCase): + def setUp(self): + import tempfile + from pathlib import Path + self.directory = tempfile.TemporaryDirectory() + self.addCleanup(self.directory.cleanup) + self.path = Path(self.directory.name) / "note.md" + self.path.write_text( + "# Title\n\nShort body.\n\n## Child\n\nShort child body.\n", + encoding="utf-8", + ) + + def test_summaries_without_threshold_use_short_node_text(self): + import asyncio + from unittest.mock import patch + from pageindex import md_to_tree + for kwargs in ({}, {"summary_token_threshold": None}): + with self.subTest(kwargs=kwargs), patch( + "pageindex.page_index_md.generate_node_summary", + side_effect=AssertionError("Short default summaries need no model"), + ): + result = asyncio.run(md_to_tree( + self.path, if_add_node_summary="yes", + if_add_node_text="yes", **kwargs)) + parent = result["structure"][0] + self.assertEqual(parent["prefix_summary"], parent["text"]) + child = parent["nodes"][0] + self.assertEqual(child["summary"], child["text"]) + + def test_thinning_without_threshold_preserves_merged_content(self): + import asyncio + from pageindex import md_to_tree + for kwargs in ({}, {"min_token_threshold": None}): + with self.subTest(kwargs=kwargs): + result = asyncio.run(md_to_tree( + self.path, if_thinning=True, if_add_node_text="yes", **kwargs)) + parent = result["structure"][0] + self.assertNotIn("nodes", parent) + self.assertIn("Short body.", parent["text"]) + self.assertIn("Short child body.", parent["text"]) + + def test_explicit_zero_summary_threshold_calls_model_for_short_nodes(self): + import asyncio + from unittest.mock import patch + from pageindex import md_to_tree + async def fake_summary(node, model=None): + return "Summary of " + node["title"] + with patch("pageindex.page_index_md.generate_node_summary", + side_effect=fake_summary) as generate: + result = asyncio.run(md_to_tree( + self.path, if_add_node_summary="yes", summary_token_threshold=0)) + parent = result["structure"][0] + self.assertEqual(generate.call_count, 2) + self.assertEqual(parent["prefix_summary"], "Summary of Title") + self.assertEqual(parent["nodes"][0]["summary"], "Summary of Child") + + def test_explicit_thinning_threshold_keeps_larger_nodes(self): + import asyncio + from pageindex import md_to_tree + for threshold in (0, 1): + with self.subTest(threshold=threshold): + result = asyncio.run(md_to_tree( + self.path, if_thinning=True, min_token_threshold=threshold, + if_add_node_text="yes")) + parent = result["structure"][0] + self.assertEqual(parent["nodes"][0]["title"], "Child") + self.assertNotIn("Short child body.", parent["text"]) + + if __name__ == "__main__": unittest.main()