import json
import os
import subprocess
import sys
import zipfile
from pathlib import Path
from infospace_bench.generator import (
init_generation_infospace,
plan_generation,
plan_generation_summary,
)
CONTAINER_XML = """
The narrator describes chapter {label} events with stocks and traders. " + " ".join(f"sentence{n}" for n in range(40)) + "
", ) def _build_plan_infospace(tmp_path: Path) -> Path: book = tmp_path / "book.epub" _write_four_chapter_epub(book) infospace = init_generation_infospace( tmp_path, book, "plan-test", name="Plan Test", profile="general-knowledge" ) return infospace.root def test_plan_summary_is_compact_and_does_not_dump_prompts(tmp_path: Path) -> None: root = _build_plan_infospace(tmp_path) summary = plan_generation(root) serialized = json.dumps(summary) assert '"prompt":' not in serialized, "compact plan must not embed full prompts" assert summary["source_chunk_count"] == 4 assert summary["selected_chunk_count"] == 4 assert summary["selected_chapter_numbers"] == [1, 2, 3, 4] assert summary["total_provider_calls_estimate"] > 0 assert summary["total_prompt_tokens_estimate"] > 0 assert summary["estimated_cost_usd"] is None assert "workflows" not in summary def test_plan_chapter_filter_selects_subset(tmp_path: Path) -> None: root = _build_plan_infospace(tmp_path) by_label = plan_generation_summary(root, chapter_filter=["I"]) by_number = plan_generation_summary(root, chapter_filter=["2"]) by_range = plan_generation_summary(root, from_chapter=2, to_chapter=3) by_chunk = plan_generation_summary(root, chunk_filter=["chapter-04"]) assert by_label["selected_chapter_numbers"] == [1] assert by_number["selected_chapter_numbers"] == [2] assert by_range["selected_chapter_numbers"] == [2, 3] assert by_chunk["selected_chunk_ids"] == ["chapter-04"] def test_plan_caps_flag_when_estimate_exceeds_budget(tmp_path: Path) -> None: root = _build_plan_infospace(tmp_path) summary = plan_generation_summary( root, max_calls=2, cost_cap=0.01, cost_per_1k_tokens=1.0, ) assert summary["total_provider_calls_estimate"] > 2 assert summary["exceeds_max_calls"] is True assert summary["estimated_cost_usd"] is not None and summary["estimated_cost_usd"] > 0.01 assert summary["exceeds_cost_cap"] is True def test_plan_full_mode_includes_workflow_plans(tmp_path: Path) -> None: root = _build_plan_infospace(tmp_path) full_plan = plan_generation(root, full=True) assert "workflows" in full_plan assert len(full_plan["workflows"]) >= 1 def test_plan_cli_compact_default_and_filters(tmp_path: Path) -> None: root = _build_plan_infospace(tmp_path) env = os.environ.copy() env["PYTHONPATH"] = "src:/home/worsch/markitect-tool/src" result = subprocess.run( [ sys.executable, "-m", "infospace_bench", "generate", "plan", str(root), "--from-chapter", "2", "--to-chapter", "3", "--cost-per-1k", "0.5", "--max-calls", "1", ], check=False, env=env, text=True, capture_output=True, ) assert result.returncode == 0, result.stderr payload = json.loads(result.stdout) assert payload["selected_chapter_numbers"] == [2, 3] assert payload["estimated_cost_usd"] is not None assert payload["exceeds_max_calls"] is True assert "workflows" not in payload assert '"prompt":' not in result.stdout