Create a new chapter in the report.
(
title: Annotated[str, ParamMeta(description="Chapter title (supports 'Parent/NewChild' to insert into existing). Use '|' to specify insertion point e.g. 'Prev|New' to insert after 'Prev', or '|New' to insert at start.")],
level: Annotated[int, ParamMeta(description="Header level (1-6)")],
content: Annotated[str, ParamMeta(description="Content of the chapter")],
_context: Dict[str, Any] | None = None,
)
| 299 | |
| 300 | |
| 301 | def report_create_chapter( |
| 302 | title: Annotated[str, ParamMeta(description="Chapter title (supports 'Parent/NewChild' to insert into existing). Use '|' to specify insertion point e.g. 'Prev|New' to insert after 'Prev', or '|New' to insert at start.")], |
| 303 | level: Annotated[int, ParamMeta(description="Header level (1-6)")], |
| 304 | content: Annotated[str, ParamMeta(description="Content of the chapter")], |
| 305 | _context: Dict[str, Any] | None = None, |
| 306 | ) -> str: |
| 307 | """ |
| 308 | Create a new chapter in the report. |
| 309 | """ |
| 310 | ctx = FileToolContext(_context) |
| 311 | _, report_file = _get_files(ctx) |
| 312 | _, report_lock = _get_locks(ctx) |
| 313 | |
| 314 | with FileLock(report_lock): |
| 315 | lines = _read_report_lines(report_file) |
| 316 | |
| 317 | # Check for routing path |
| 318 | parent_path = None |
| 319 | display_title = title |
| 320 | p_start, p_end = -1, len(lines) |
| 321 | |
| 322 | if "/" in title: |
| 323 | # Handle recursive "Parent/Child" structure, where Child might contain "|" |
| 324 | parent_path, new_title = title.rsplit("/", 1) |
| 325 | p_start, p_end = _find_chapter_range(lines, parent_path) |
| 326 | |
| 327 | if p_start == -1: |
| 328 | return f"Parent chapter '{parent_path}' not found. Cannot create '{new_title}' inside it." |
| 329 | |
| 330 | display_title = new_title |
| 331 | |
| 332 | # Check for "|" syntax in the leaf title |
| 333 | insert_after_target = None # None means append, "" means start, "str" means after that chapter |
| 334 | if "|" in display_title: |
| 335 | target, real_title = display_title.split("|", 1) |
| 336 | display_title = real_title |
| 337 | insert_after_target = target |
| 338 | |
| 339 | # Determine insertion index |
| 340 | insert_idx = -1 |
| 341 | |
| 342 | if insert_after_target is not None: |
| 343 | if insert_after_target == "": |
| 344 | # Insert at the beginning of the context |
| 345 | if parent_path: |
| 346 | # Inside parent: Insert after parent header (and its intro text), before first subchapter |
| 347 | insert_idx = p_end # Default to appending if no subchapters found |
| 348 | |
| 349 | # Scan for first header inside parent |
| 350 | for idx in range(p_start + 1, len(lines)): |
| 351 | if idx >= p_end: |
| 352 | break |
| 353 | lvl, _ = _parse_header(lines[idx]) |
| 354 | if lvl > 0: |
| 355 | insert_idx = idx |
| 356 | break |
| 357 | else: |
| 358 | # Top level: Insert at start of file |
nothing calls this directly
no test coverage detected