|
69 | 69 | Return ONLY valid JSON array, no fences, no explanation. |
70 | 70 | """ |
71 | 71 |
|
| 72 | +_CONCEPTS_PLAN_USER = """\ |
| 73 | +Based on the summary above, decide how to update the wiki's concept pages. |
| 74 | +
|
| 75 | +Existing concept pages: |
| 76 | +{concept_briefs} |
| 77 | +
|
| 78 | +Return a JSON object with three keys: |
| 79 | +
|
| 80 | +1. "create" — new concepts not covered by any existing page. Array of objects: |
| 81 | + {{"name": "concept-slug", "title": "Human-Readable Title"}} |
| 82 | +
|
| 83 | +2. "update" — existing concepts that have significant new information from \ |
| 84 | +this document worth integrating. Array of objects: |
| 85 | + {{"name": "existing-slug", "title": "Existing Title"}} |
| 86 | +
|
| 87 | +3. "related" — existing concepts tangentially related to this document but \ |
| 88 | +not needing content changes, just a cross-reference link. Array of slug strings. |
| 89 | +
|
| 90 | +Rules: |
| 91 | +- For the first few documents, create 2-3 foundational concepts at most. |
| 92 | +- Do NOT create a concept that overlaps with an existing one — use "update". |
| 93 | +- Do NOT create concepts that are just the document topic itself. |
| 94 | +- "related" is for lightweight cross-linking only, no content rewrite needed. |
| 95 | +
|
| 96 | +Return ONLY valid JSON, no fences, no explanation. |
| 97 | +""" |
| 98 | + |
72 | 99 | _CONCEPT_PAGE_USER = """\ |
73 | 100 | Write the concept page for: {title} |
74 | 101 |
|
|
81 | 108 | - [[wikilinks]] to related concepts and [[summaries/{doc_name}]] |
82 | 109 | """ |
83 | 110 |
|
| 111 | +_CONCEPT_UPDATE_USER = """\ |
| 112 | +Update the concept page for: {title} |
| 113 | +
|
| 114 | +Current content of this page: |
| 115 | +{existing_content} |
| 116 | +
|
| 117 | +New information from document "{doc_name}" (summarized above) should be \ |
| 118 | +integrated into this page. Rewrite the full page incorporating the new \ |
| 119 | +information naturally — do not just append. Maintain existing \ |
| 120 | +[[wikilinks]] and add new ones where appropriate. |
| 121 | +
|
| 122 | +Return ONLY the Markdown content (no frontmatter, no code fences). |
| 123 | +""" |
| 124 | + |
84 | 125 | _LONG_DOC_SUMMARY_USER = """\ |
85 | 126 | This is a PageIndex summary for long document "{doc_name}" (doc_id: {doc_id}): |
86 | 127 |
|
@@ -296,6 +337,36 @@ def _write_concept(wiki_dir: Path, name: str, content: str, source_file: str, is |
296 | 337 | path.write_text(frontmatter + content, encoding="utf-8") |
297 | 338 |
|
298 | 339 |
|
| 340 | +def _add_related_link(wiki_dir: Path, concept_slug: str, doc_name: str, source_file: str) -> None: |
| 341 | + """Add a cross-reference link to an existing concept page (no LLM call).""" |
| 342 | + concepts_dir = wiki_dir / "concepts" |
| 343 | + path = concepts_dir / f"{concept_slug}.md" |
| 344 | + if not path.exists(): |
| 345 | + return |
| 346 | + |
| 347 | + text = path.read_text(encoding="utf-8") |
| 348 | + link = f"[[summaries/{doc_name}]]" |
| 349 | + if link in text: |
| 350 | + return |
| 351 | + |
| 352 | + # Update sources in frontmatter |
| 353 | + if source_file not in text: |
| 354 | + if text.startswith("---"): |
| 355 | + end = text.index("---", 3) |
| 356 | + fm = text[:end + 3] |
| 357 | + body = text[end + 3:] |
| 358 | + if "sources:" in fm: |
| 359 | + fm = fm.replace("sources: [", f"sources: [{source_file}, ") |
| 360 | + else: |
| 361 | + fm = fm.replace("---\n", f"---\nsources: [{source_file}]\n", 1) |
| 362 | + text = fm + body |
| 363 | + else: |
| 364 | + text = f"---\nsources: [{source_file}]\n---\n\n" + text |
| 365 | + |
| 366 | + text += f"\n\nSee also: {link}" |
| 367 | + path.write_text(text, encoding="utf-8") |
| 368 | + |
| 369 | + |
299 | 370 | def _update_index(wiki_dir: Path, doc_name: str, concept_names: list[str]) -> None: |
300 | 371 | """Append document and concept entries to index.md.""" |
301 | 372 | index_path = wiki_dir / "index.md" |
|
0 commit comments