feat(agent): opt-in append-note concept_update_mode to avoid full-page rewrites on ingest - #246
Open
sebastianbraun25 wants to merge 4 commits into
Conversation
added 3 commits
September 7, 2026 10:29
Adds concept_update_mode (default "rewrite", unchanged) with a new "append" mode: instead of sending an existing concept/entity page's full body to the LLM for a rewrite, generates a short 1-2 sentence note (the LLM never sees the existing page) and appends it deterministically under a "## Notes" heading, keyed by source document so re-ingesting an updated document replaces its own line instead of duplicating it. Removal cleanup and config docs updated accordingly. Resolves VectifyAI#245
VectifyAI#245) Adds a new `openkb consolidate [PAGE_NAME] [--all] [--min-notes N] [--dry-run] [--yes]` command (mirrors `recompile`'s CLI shape) and a new `openkb/agent/consolidator.py` module. For concept/entity pages accumulating notes under `concept_update_mode: append`, this folds the pending "## Notes" section into curated prose with a single LLM call per page — no new source document, no concept/entity classification, since the page is already fixed. - Contradictions between notes (or notes vs. existing prose) are described directly in the rewritten text rather than silently resolved. - The full wikilink whitelist is sent here (once per page per run, not per ticket) so consolidated prose can properly cross-link to other pages. - The "## Notes" section is replaced entirely; `sources:`/`type:` are preserved, only `description:` may be refreshed. A later `append_*_note` call re-creates a fresh "## Notes" section, so the next consolidation run only ever sees what changed since the last one — no extra tracking state needed. - Manual, opt-in only (no automatic trigger during ingest).
…'some short sentences'
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR was created in collaboration between a human and AI: implementation, tests, and
PR text were created by an AI assistant under the guidance and review of the human author.
Problem
openkb addcurrently regenerates the FULL body of every existing concept/entity page it touches._gen_update/_gen_entity_updateinopenkb/agent/compiler.pyread the entire current page from disk and send it to the LLM asexisting_content, with the instruction "Rewrite the full page incorporating the new information naturally — do not just append." For a short document (e.g. a support ticket) that touches 8-10 already-existing concepts/entities, this means 8-10 full-page rewrites per ingest, even when the actual new information is just 1-2 sentences. Cost scales with page size, and page size only grows as more documents are ingested over time.Solution / Changes
concept_update_modeconfig key (.openkb/config.yaml, default"rewrite"— current behavior, fully unchanged). KB-only, likedebug/insert_mode— not inGLOBAL_SCALAR_KEYS."append"mode:existing_content, no wikilink whitelist turn — notes stay plain text, deferring cross-linking to a future reconciliation step).## Notesheading, keyed by the[[summaries/{doc_name}]]source marker so re-ingesting an updated version of the same document replaces its own line instead of duplicating it.description, no full-page LLM generation).sources:frontmatter tracking, backlinks, related-item cross-refs, andindex.mdupdates are unchanged and shared with the existing "rewrite" path.openkb removecleanup (_remove_doc_from_pages) extended to also strip a removed document's own note line — a no-op for "rewrite"-mode pages.openkb/agent/compiler_notes.py(prompts + append/upsert logic) rather than growingcompiler.pyfurther (already over the 800-line limit, grandfathered tech debt).openkb consolidate [PAGE_NAME] [--all] [--min-notes N] [--dry-run] [--yes]command (mirrorsrecompile's CLI shape) + new moduleopenkb/agent/consolidator.py, to fold a page's accumulated## Notesinto curated prose — manual/opt-in only, never triggered automatically byopenkb add:## Notessection is replaced entirely;sources:/type:are preserved, onlydescription:may be refreshed. A later note-append call re-creates a fresh## Notessection, so the next run only ever sees what changed since the last one — no extra tracking state needed.Issues
Resolves #245