diff --git a/src/aggregate.py b/src/aggregate.py index 6302b84..6db5e33 100644 --- a/src/aggregate.py +++ b/src/aggregate.py @@ -12,15 +12,15 @@ Instead of sending every file to the AI raw (which blows up tokens), this uses a This is essential for keeping prompt tokens low while giving the AI enough structural info to use the MCP tools to fetch only what it needs. """ -import tomllib -import re import glob import os +import re +import tomllib from pathlib import Path, PureWindowsPath from typing import Any, cast -from src import summarize -from src import project_manager from src import beads_client +from src import project_manager +from src import summarize from src.file_cache import ASTParser from src.performance_monitor import get_monitor @@ -101,11 +101,8 @@ def compute_file_stats(abs_path: str) -> dict[str, int]: def build_discussion_section(history: list[Any]) -> str: """ - - - - Builds a markdown section for discussion history. - Handles both legacy list[str] and new list[dict]. + Builds a markdown section for discussion history. + Handles both legacy list[str] and new list[dict]. """ sections = [] for i, entry in enumerate(history, start=1): @@ -118,7 +115,6 @@ def build_discussion_section(history: list[Any]) -> str: sections.append(f"### Discussion Excerpt {i}\n\n{text}") return "\n\n---\n\n".join(sections) - def build_screenshots_section(base_dir: Path, screenshots: list[str]) -> str: sections = [] for entry in screenshots: @@ -138,22 +134,19 @@ def build_screenshots_section(base_dir: Path, screenshots: list[str]) -> str: def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[dict[str, Any]]: """ - - - - Return a list of dicts describing each file, for use by ai_client when it - wants to upload individual files rather than inline everything as markdown. - - Each dict has: - path : Path (resolved absolute path) - entry : str (original config entry string) - content : str (file text, or error string) - error : bool - mtime : float (last modification time, for skip-if-unchanged optimization) - tier : int | None (optional tier for context management) - auto_aggregate : bool - force_full : bool - view_mode : str (summary, full, skeleton, outline, none) + Return a list of dicts describing each file, for use by ai_client when it + wants to upload individual files rather than inline everything as markdown. + + Each dict has: + path : Path (resolved absolute path) + entry : str (original config entry string) + content : str (file text, or error string) + error : bool + mtime : float (last modification time, for skip-if-unchanged optimization) + tier : int | None (optional tier for context management) + auto_aggregate : bool + force_full : bool + view_mode : str (summary, full, skeleton, outline, none) [C: src/app_controller.py:AppController._bg_task, src/orchestrator_pm.py:module, tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_context_composition_phase6.py:test_view_mode_custom, tests/test_context_composition_phase6.py:test_view_mode_custom_empty_default_to_summary, tests/test_context_composition_phase6.py:test_view_mode_default_summary, tests/test_context_composition_phase6.py:test_view_mode_full, tests/test_context_composition_phase6.py:test_view_mode_none, tests/test_context_composition_phase6.py:test_view_mode_outline, tests/test_context_composition_phase6.py:test_view_mode_skeleton, tests/test_context_composition_phase6.py:test_view_mode_summary, tests/test_tiered_context.py:test_build_file_items_with_tiers, tests/test_tiered_context.py:test_build_files_section_with_dicts] """ with get_monitor().scope("build_file_items"): @@ -249,12 +242,9 @@ def build_file_items(base_dir: Path, files: list[str | dict[str, Any]]) -> list[ items.append({"path": path, "entry": entry, "content": content, "error": error, "mtime": mtime, "tier": tier, "auto_aggregate": auto_aggregate, "force_full": force_full, "view_mode": view_mode, "ast_signatures": ast_signatures, "ast_definitions": ast_definitions, "ast_mask": ast_mask, "custom_slices": custom_slices}) return items - def _build_files_section_from_items(file_items: list[dict[str, Any]]) -> str: """ - - - Build the files markdown section from pre-read file items (avoids double I/O). + Build the files markdown section from pre-read file items (avoids double I/O). [C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_context_composition_phase6.py:test_files_section_rendering, tests/test_tiered_context.py:test_build_files_section_with_dicts, tests/test_ui_summary_only_removal.py:test_aggregate_from_items_respects_auto_aggregate] """ sections = [] @@ -331,8 +321,6 @@ def build_markdown_from_items(file_items: list[dict[str, Any]], screenshot_base_ def build_markdown_no_history(file_items: list[dict[str, Any]], screenshot_base_dir: Path, screenshots: list[str], summary_only: bool = False, aggregation_strategy: str = "auto") -> str: """ - - Build markdown with only files + screenshots (no history). Used for stable caching. [C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_blacklist] """ @@ -340,8 +328,6 @@ def build_markdown_no_history(file_items: list[dict[str, Any]], screenshot_base_ def build_discussion_text(history: list[str]) -> str: """ - - Build just the discussion history section text. Returns empty string if no history. [C: src/app_controller.py:AppController._do_generate, tests/test_history_management.py:test_aggregate_includes_segregated_history] """ @@ -351,11 +337,8 @@ def build_discussion_text(history: list[str]) -> str: def build_tier3_context(file_items: list[dict[str, Any]], screenshot_base_dir: Path, screenshots: list[str], history: list[str], focus_files: list[str]) -> str: """ - - - - Tier 3 Context: Execution/Worker. - Full content for focus_files and files with tier=3, summaries/skeletons for others. + Tier 3 Context: Execution/Worker. + Full content for focus_files and files with tier=3, summaries/skeletons for others. [C: tests/test_aggregate_flags.py:test_auto_aggregate_skip, tests/test_aggregate_flags.py:test_force_full, tests/test_ast_masking_core.py:test_ast_masking_gencpp_samples, tests/test_gencpp_full_suite.py:test_gencpp_full_suite, tests/test_perf_aggregate.py:test_build_tier3_context_scaling, tests/test_tiered_context.py:test_build_tier3_context_ast_skeleton, tests/test_tiered_context.py:test_build_tier3_context_exists, tests/test_tiered_context.py:test_tiered_context_by_tier_field] """ with get_monitor().scope("build_tier3_context"): @@ -506,4 +489,5 @@ def main() -> None: print(f"Written: {output_file}") if __name__ == "__main__": - main() \ No newline at end of file + main() + \ No newline at end of file