(self, prep_res)
| 452 | ) # Return use_cache |
| 453 | |
| 454 | def exec(self, prep_res): |
| 455 | ( |
| 456 | abstraction_listing, |
| 457 | context, |
| 458 | num_abstractions, |
| 459 | project_name, |
| 460 | list_lang_note, |
| 461 | use_cache, |
| 462 | ) = prep_res # Unpack use_cache |
| 463 | print("Determining chapter order using LLM...") |
| 464 | # No language variation needed here in prompt instructions, just ordering based on structure |
| 465 | # The input names might be translated, hence the note. |
| 466 | prompt = f""" |
| 467 | Given the following project abstractions and their relationships for the project ```` {project_name} ````: |
| 468 | |
| 469 | Abstractions (Index # Name){list_lang_note}: |
| 470 | {abstraction_listing} |
| 471 | |
| 472 | Context about relationships and project summary: |
| 473 | {context} |
| 474 | |
| 475 | If you are going to make a tutorial for ```` {project_name} ````, what is the best order to explain these abstractions, from first to last? |
| 476 | Ideally, first explain those that are the most important or foundational, perhaps user-facing concepts or entry points. Then move to more detailed, lower-level implementation details or supporting concepts. |
| 477 | |
| 478 | Output the ordered list of abstraction indices, including the name in a comment for clarity. Use the format `idx # AbstractionName`. |
| 479 | |
| 480 | ```yaml |
| 481 | - 2 # FoundationalConcept |
| 482 | - 0 # CoreClassA |
| 483 | - 1 # CoreClassB (uses CoreClassA) |
| 484 | - ... |
| 485 | ``` |
| 486 | |
| 487 | Now, provide the YAML output: |
| 488 | """ |
| 489 | response = call_llm(prompt, use_cache=(use_cache and self.cur_retry == 0)) # Use cache only if enabled and not retrying |
| 490 | |
| 491 | # --- Validation --- |
| 492 | yaml_str = response.strip().split("```yaml")[1].split("```")[0].strip() |
| 493 | ordered_indices_raw = yaml.safe_load(yaml_str) |
| 494 | |
| 495 | if not isinstance(ordered_indices_raw, list): |
| 496 | raise ValueError("LLM output is not a list") |
| 497 | |
| 498 | ordered_indices = [] |
| 499 | seen_indices = set() |
| 500 | for entry in ordered_indices_raw: |
| 501 | try: |
| 502 | if isinstance(entry, int): |
| 503 | idx = entry |
| 504 | elif isinstance(entry, str) and "#" in entry: |
| 505 | idx = int(entry.split("#")[0].strip()) |
| 506 | else: |
| 507 | idx = int(str(entry).strip()) |
| 508 | |
| 509 | if not (0 <= idx < num_abstractions): |
| 510 | raise ValueError( |
| 511 | f"Invalid index {idx} in ordered list. Max index is {num_abstractions-1}." |
nothing calls this directly
no test coverage detected