fix(wiki): pass chunks explicitly to compile_concept (single retrieve)
compile_concept now accepts chunks as a positional parameter; compile_all retrieves chunks once and passes them directly, avoiding double-retrieve. Also separates all_concepts (full list) from compile_concepts (filtered), so cross-ref injection always uses the complete concept list regardless of --concept filter (Fix 6 + Fix 8). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -426,6 +426,7 @@ def _render_page_markdown(
|
||||
|
||||
def compile_concept(
|
||||
concept: Concept,
|
||||
chunks: list[dict[str, Any]],
|
||||
*,
|
||||
top_k: int,
|
||||
llm: LLMClient,
|
||||
@@ -434,19 +435,24 @@ def compile_concept(
|
||||
) -> ConceptPage:
|
||||
"""Compile a single concept page.
|
||||
|
||||
1. Retrieve Top-K chunks (hybrid dense+FTS) for concept title + aliases.
|
||||
2. Synthesise via LLM (Ollama) with per-claim citation format.
|
||||
3. Run Grounding-Guard: mark ungrounded claims as ⚠.
|
||||
4. Inject cross-references to other concepts as [[slug]] links.
|
||||
5. Embed formula chunks if ``formulas`` table is present (graceful).
|
||||
Parameters
|
||||
----------
|
||||
concept:
|
||||
The concept to compile.
|
||||
chunks:
|
||||
Pre-retrieved source chunks for this concept (from :func:`_retrieve_chunks`).
|
||||
Passing chunks explicitly avoids a second retrieve and ensures the stored
|
||||
hash matches the chunks actually used for synthesis.
|
||||
|
||||
1. Synthesise via LLM (Ollama) with per-claim citation format.
|
||||
2. Run Grounding-Guard: mark ungrounded claims as ⚠.
|
||||
3. Inject cross-references to other concepts as [[slug]] links.
|
||||
4. Embed formula chunks if ``formulas`` table is present (graceful).
|
||||
|
||||
Returns a :class:`ConceptPage` with full markdown and claim list.
|
||||
"""
|
||||
settings = get_settings()
|
||||
_wiki_dir = wiki_dir or Path(settings.wiki_dir)
|
||||
|
||||
queries = [concept.title] + concept.aliases
|
||||
chunks = _retrieve_chunks(queries, top_k=top_k)
|
||||
_wiki_dir = wiki_dir or Path(settings.wiki_dir) # noqa: F841 — kept for future use
|
||||
|
||||
h = _chunk_hash(chunks)
|
||||
prompt = _build_synthesis_prompt(concept, chunks)
|
||||
@@ -532,10 +538,13 @@ def compile_all(
|
||||
if not concepts_path.exists():
|
||||
# Fall back to sibling concepts.yaml next to wiki/ dir
|
||||
concepts_path = wiki_dir.parent / "wiki" / "concepts.yaml"
|
||||
concepts = load_concepts(str(concepts_path))
|
||||
# Load the FULL concept list — used for cross-reference injection regardless of filter
|
||||
all_concepts = load_concepts(str(concepts_path))
|
||||
|
||||
if concept_filter:
|
||||
concepts = [c for c in concepts if c.slug == concept_filter]
|
||||
# Apply filter only to the set of concepts that will be (re-)compiled
|
||||
compile_concepts = (
|
||||
[c for c in all_concepts if c.slug == concept_filter] if concept_filter else all_concepts
|
||||
)
|
||||
|
||||
state_path = wiki_dir / ".compile-state.json"
|
||||
state = _load_compile_state(state_path)
|
||||
@@ -549,8 +558,8 @@ def compile_all(
|
||||
|
||||
report = CompileReport()
|
||||
|
||||
for concept in concepts:
|
||||
# Fast check: retrieve chunks and compare hash
|
||||
for concept in compile_concepts:
|
||||
# Retrieve chunks once — reuse for hash check and synthesis
|
||||
queries = [concept.title] + concept.aliases
|
||||
chunks = _retrieve_chunks(queries, top_k=k)
|
||||
h = _chunk_hash(chunks)
|
||||
@@ -561,9 +570,10 @@ def compile_all(
|
||||
|
||||
page = compile_concept(
|
||||
concept,
|
||||
chunks,
|
||||
top_k=k,
|
||||
llm=_llm,
|
||||
all_concepts=concepts,
|
||||
all_concepts=all_concepts, # always the full list for cross-refs
|
||||
wiki_dir=wiki_dir,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user