@@ -497,6 +497,7 @@ async def _compile_concepts(
497497 summary : str ,
498498 doc_name : str ,
499499 max_concurrency : int ,
500+ doc_brief : str = "" ,
500501) -> None :
501502 """Shared Steps 2-4: concepts plan → generate/update → index.
502503
@@ -546,11 +547,11 @@ async def _compile_concepts(
546547 # --- Step 3: Generate/update concept pages concurrently (A cached) ---
547548 semaphore = asyncio .Semaphore (max_concurrency )
548549
549- async def _gen_create (concept : dict ) -> tuple [str , str , bool ]:
550+ async def _gen_create (concept : dict ) -> tuple [str , str , bool , str ]:
550551 name = concept ["name" ]
551552 title = concept .get ("title" , name )
552553 async with semaphore :
553- page_content = await _llm_call_async (model , [
554+ raw = await _llm_call_async (model , [
554555 system_msg ,
555556 doc_msg ,
556557 {"role" : "assistant" , "content" : summary },
@@ -559,9 +560,15 @@ async def _gen_create(concept: dict) -> tuple[str, str, bool]:
559560 update_instruction = "" ,
560561 )},
561562 ], f"concept:{ name } " )
562- return name , page_content , False
563-
564- async def _gen_update (concept : dict ) -> tuple [str , str , bool ]:
563+ try :
564+ parsed = _parse_json (raw )
565+ brief = parsed .get ("brief" , "" )
566+ content = parsed .get ("content" , raw )
567+ except (json .JSONDecodeError , ValueError ):
568+ brief , content = "" , raw
569+ return name , content , False , brief
570+
571+ async def _gen_update (concept : dict ) -> tuple [str , str , bool , str ]:
565572 name = concept ["name" ]
566573 title = concept .get ("title" , name )
567574 concept_path = wiki_dir / "concepts" / f"{ name } .md"
@@ -575,7 +582,7 @@ async def _gen_update(concept: dict) -> tuple[str, str, bool]:
575582 else :
576583 existing_content = "(page not found — create from scratch)"
577584 async with semaphore :
578- page_content = await _llm_call_async (model , [
585+ raw = await _llm_call_async (model , [
579586 system_msg ,
580587 doc_msg ,
581588 {"role" : "assistant" , "content" : summary },
@@ -584,13 +591,20 @@ async def _gen_update(concept: dict) -> tuple[str, str, bool]:
584591 existing_content = existing_content ,
585592 )},
586593 ], f"update:{ name } " )
587- return name , page_content , True
594+ try :
595+ parsed = _parse_json (raw )
596+ brief = parsed .get ("brief" , "" )
597+ content = parsed .get ("content" , raw )
598+ except (json .JSONDecodeError , ValueError ):
599+ brief , content = "" , raw
600+ return name , content , True , brief
588601
589602 tasks = []
590603 tasks .extend (_gen_create (c ) for c in create_items )
591604 tasks .extend (_gen_update (c ) for c in update_items )
592605
593606 concept_names : list [str ] = []
607+ concept_briefs_map : dict [str , str ] = {}
594608
595609 if tasks :
596610 total = len (tasks )
@@ -603,9 +617,11 @@ async def _gen_update(concept: dict) -> tuple[str, str, bool]:
603617 if isinstance (r , Exception ):
604618 logger .warning ("Concept generation failed: %s" , r )
605619 continue
606- name , page_content , is_update = r
607- _write_concept (wiki_dir , name , page_content , source_file , is_update )
620+ name , page_content , is_update , brief = r
621+ _write_concept (wiki_dir , name , page_content , source_file , is_update , brief = brief )
608622 concept_names .append (name )
623+ if brief :
624+ concept_briefs_map [name ] = brief
609625
610626 # --- Step 3b: Process related items (code only, no LLM) ---
611627 for slug in related_items :
@@ -618,7 +634,8 @@ async def _gen_update(concept: dict) -> tuple[str, str, bool]:
618634 _backlink_concepts (wiki_dir , doc_name , all_concept_slugs )
619635
620636 # --- Step 4: Update index (code only) ---
621- _update_index (wiki_dir , doc_name , concept_names )
637+ _update_index (wiki_dir , doc_name , concept_names ,
638+ doc_brief = doc_brief , concept_briefs = concept_briefs_map )
622639
623640
624641async def compile_short_doc (
@@ -653,13 +670,20 @@ async def compile_short_doc(
653670 )}
654671
655672 # --- Step 1: Generate summary ---
656- summary = _llm_call (model , [system_msg , doc_msg ], "summary" )
657- _write_summary (wiki_dir , doc_name , source_file , summary )
673+ summary_raw = _llm_call (model , [system_msg , doc_msg ], "summary" )
674+ try :
675+ summary_parsed = _parse_json (summary_raw )
676+ doc_brief = summary_parsed .get ("brief" , "" )
677+ summary = summary_parsed .get ("content" , summary_raw )
678+ except (json .JSONDecodeError , ValueError ):
679+ doc_brief = ""
680+ summary = summary_raw
681+ _write_summary (wiki_dir , doc_name , source_file , summary , brief = doc_brief )
658682
659683 # --- Steps 2-4: Concept plan → generate/update → index ---
660684 await _compile_concepts (
661685 wiki_dir , kb_dir , model , system_msg , doc_msg ,
662- summary , doc_name , max_concurrency ,
686+ summary , doc_name , max_concurrency , doc_brief = doc_brief ,
663687 )
664688
665689
@@ -669,6 +693,7 @@ async def compile_long_doc(
669693 doc_id : str ,
670694 kb_dir : Path ,
671695 model : str ,
696+ doc_description : str = "" ,
672697 max_concurrency : int = DEFAULT_COMPILE_CONCURRENCY ,
673698) -> None :
674699 """Compile a long (PageIndex) document's concepts and index.
@@ -700,5 +725,5 @@ async def compile_long_doc(
700725 # --- Steps 2-4: Concept plan → generate/update → index ---
701726 await _compile_concepts (
702727 wiki_dir , kb_dir , model , system_msg , doc_msg ,
703- overview , doc_name , max_concurrency ,
728+ overview , doc_name , max_concurrency , doc_brief = doc_description ,
704729 )
0 commit comments