Skip to content

Fix source text rendering and graph build locking#105

Merged
Moskize91 merged 5 commits into
mainfrom
codex/kg-build-snapshot
Jul 7, 2026
Merged

Fix source text rendering and graph build locking#105
Moskize91 merged 5 commits into
mainfrom
codex/kg-build-snapshot

Conversation

@Moskize91

Copy link
Copy Markdown
Contributor

Summary

  • release the archive lock while building knowledge graph artifacts
  • stop rendering source sentence boundaries as artificial newlines
  • preserve imported source raw text while exposing normalized sentence text to processing pipelines
  • update relation discovery prompts to reduce invalid long/cross-line evidence and untagged/self-link relations
  • add title image docs update

Verification

  • pnpm lint
  • pnpm typecheck
  • pnpm test:run

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added terminal screenshots to the English and Chinese README files for a clearer first look.
  • Bug Fixes

    • Improved how source and archive text is displayed, reducing unexpected line breaks and better preserving original spacing.
    • Enhanced text handling so normalized sentence content is shown more consistently while keeping imported text intact.
  • Refactor

    • Updated knowledge-graph processing to use a more reliable snapshot-based flow, improving consistency during builds.

Walkthrough

Changes

This PR adds README screenshot images and reworks two independent areas: knowledge-graph artifact generation now uses a two-step snapshot-then-generate flow (new snapshotChapterKnowledgeGraphInput and generateChapterKnowledgeGraphArtifactFromSnapshot functions, wired into src/cli/queue.ts and re-exported from the facade), and text-stream sentence handling is refactored around a new Sentence class with normalized text, custom segmenter support, raw range reads (readTextInRange), and updated concatenation logic in serial.ts and archive-view.ts that drops newline separators between sentences in favor of raw/serialized text. Corresponding tests were updated across CLI queue, facade, archive-view, and serial test suites.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as queue.ts
  participant Facade as knowledge-graph-build.ts
  participant Doc as ArchiveDocument
  CLI->>Doc: assertCurrentBuildInputRevision
  CLI->>Facade: snapshotChapterKnowledgeGraphInput(document, chapterId)
  Facade->>Doc: readChapterFragments / read chapter details
  Facade-->>CLI: ChapterKnowledgeGraphInputSnapshot
  CLI->>Facade: generateChapterKnowledgeGraphArtifactFromSnapshot(chapterId, snapshot, options)
  Facade->>Facade: validate snapshot.chapterId and stage
  Facade-->>CLI: ChapterKnowledgeGraphBuildArtifact
Loading

Possibly related PRs

  • oomol-lab/wiki-graph#103: Both PRs modify src/archive/query/archive-view.ts's readTextStreamRange/text-range handling at the same sentence-rendering code paths.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title describes the change, but it does not use the required <type>(<scope>): <subject> format. Rename it to fix(archive): release lock during knowledge-graph build and stop adding sentence newlines.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description is clearly related to the changeset and summarizes the main updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/kg-build-snapshot

Comment @coderabbitai help to get the list of available commands.

@Moskize91 Moskize91 merged commit 85108f6 into main Jul 7, 2026
2 of 3 checks passed
@Moskize91 Moskize91 deleted the codex/kg-build-snapshot branch July 7, 2026 11:03

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/archive/query/archive-view.ts (1)

4137-4178: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

joinTextStreamSentences merges words at sentence boundaries.

joinTextStreamSentences (used as the fallback in both readTextStreamRange and readTextStreamText) joins already-normalized sentence.text values with "". Sentence.text is fully trimmed of leading/trailing whitespace (per normalizeSentenceText), so any natural space that originally separated two sentences is lost when concatenating with an empty separator — for real segmented text this merges the last word of one sentence with the first word of the next (e.g. the updated test fixtures show "NoteAlice", "retrieval.Bob", "agents.朱元璋").

This directly undercuts the PR's goal of producing clean, non-garbled evidence text for relation-discovery prompts — merged words could confuse downstream extraction just as much as the artificial newlines this PR set out to remove.

🩹 Suggested fix
 function joinTextStreamSentences(
   sentences: readonly Pick<ArchiveTextStreamSentence, "text">[],
 ): string {
-  return sentences.map((sentence) => sentence.text).join("");
+  return sentences.map((sentence) => sentence.text).join(" ");
 }

Note: this will require updating the corresponding expected values in test/archive/query/archive-view.test.ts (e.g. lines 304, 823, 1238, 1813, 2855, 3015) to include the separating space.

Also applies to: 4180-4230

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/archive/query/archive-view.ts` around lines 4137 - 4178,
`readTextStreamRange` is falling back to `joinTextStreamSentences`, which
concatenates trimmed sentence text without a separator and merges words at
sentence boundaries. Update the fallback (and the matching `readTextStreamText`
path it also applies to) so sentence text is joined with a space or equivalent
boundary-preserving separator, using the existing helpers like
`joinTextStreamSentences` and `normalizeRenderedTextStreamRange` as the main
entry points. After changing the join behavior, update the affected archive-view
test expectations to include the inserted space.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README_zh-CN.md`:
- Line 1: The Markdown image in the README lacks alternative text, which hurts
accessibility and may trigger markdownlint. Update the image syntax to include a
short, clear Chinese alt description, and locate it by the standalone image
reference in the README content.

In `@README.md`:
- Line 1: The README image is missing alternate text, which affects
accessibility and markdownlint compliance. Update the Markdown image in README
to include a short descriptive alt label so the image can be identified by
screen readers; locate it by the terminal screenshot reference currently using
the image syntax in README.

In `@src/document/text-streams.ts`:
- Around line 734-748: The span calculation in the sentence-building loop is
using segment.text.length, which can drift if the segmenter normalizes or trims
text. Update the raw-source range logic in the segment iteration (the Sentence
creation and byteOffset/byteLength assignment) to derive the end of each span
from the next segment’s offset or a raw length provided by the segmenter, so the
stored offsets always map to the original text and readTextInRange reconstructs
correctly.

---

Outside diff comments:
In `@src/archive/query/archive-view.ts`:
- Around line 4137-4178: `readTextStreamRange` is falling back to
`joinTextStreamSentences`, which concatenates trimmed sentence text without a
separator and merges words at sentence boundaries. Update the fallback (and the
matching `readTextStreamText` path it also applies to) so sentence text is
joined with a space or equivalent boundary-preserving separator, using the
existing helpers like `joinTextStreamSentences` and
`normalizeRenderedTextStreamRange` as the main entry points. After changing the
join behavior, update the affected archive-view test expectations to include the
inserted space.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3672d9b8-546f-4c88-8440-6eca4a6d4edb

📥 Commits

Reviewing files that changed from the base of the PR and between bb9c5f6 and f430be4.

⛔ Files ignored due to path filters (4)
  • docs/images/app-screenshot-cn.png is excluded by !**/*.png
  • docs/images/app-screenshot-en.png is excluded by !**/*.png
  • docs/images/terminal-cn.png is excluded by !**/*.png
  • docs/images/terminal-en.png is excluded by !**/*.png
📒 Files selected for processing (13)
  • README.md
  • README_zh-CN.md
  • src/archive/query/archive-view.ts
  • src/cli/queue.ts
  • src/document/text-streams.ts
  • src/document/types.ts
  • src/facade/index.ts
  • src/facade/knowledge-graph-build.ts
  • src/serial.ts
  • test/archive/query/archive-view.test.ts
  • test/cli/queue.test.ts
  • test/facade/knowledge-graph-build.test.ts
  • test/serial.test.ts

Comment thread README_zh-CN.md
@@ -1,3 +1,5 @@
![](./docs/images/terminal-cn.png)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

补上图片替代文本。

当前 Markdown 图片没有 alt 文本,会影响可访问性,也会触发 markdownlint。建议加一个简短、明确的中文说明。

♻️ 建议修改
-![](./docs/images/terminal-cn.png)
+![终端截图](./docs/images/terminal-cn.png)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
![](./docs/images/terminal-cn.png)
![终端截图](./docs/images/terminal-cn.png)
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 1-1: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README_zh-CN.md` at line 1, The Markdown image in the README lacks
alternative text, which hurts accessibility and may trigger markdownlint. Update
the image syntax to include a short, clear Chinese alt description, and locate
it by the standalone image reference in the README content.

Source: Linters/SAST tools

Comment thread README.md
@@ -1,3 +1,5 @@
![](./docs/images/terminal-en.png)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add alt text to the README image.

The current Markdown image has no alternate text, which hurts accessibility and trips markdownlint. Use a short descriptive label.

♻️ Proposed fix
-![](./docs/images/terminal-en.png)
+![Terminal screenshot](./docs/images/terminal-en.png)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
![](./docs/images/terminal-en.png)
![Terminal screenshot](./docs/images/terminal-en.png)
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 1-1: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 1, The README image is missing alternate text, which
affects accessibility and markdownlint compliance. Update the Markdown image in
README to include a short descriptive alt label so the image can be identified
by screen readers; locate it by the terminal screenshot reference currently
using the image syntax in README.

Source: Linters/SAST tools

Comment on lines +734 to 748
for await (const segment of segmenter.pipe([text])) {
const rawText = text.slice(
segment.offset,
segment.offset + segment.text.length,
);

if (sentence === "") {
if (rawText.trim() === "") {
continue;
}
const sentence = new Sentence(rawText, segment.wordsCount);

spans.push({
byteLength: Buffer.byteLength(sentence, "utf8"),
byteOffset: Buffer.byteLength(text.slice(0, sentenceStart), "utf8"),
text: sentence,
wordsCount: countWords(sentence),
Object.assign(sentence, {
byteLength: Buffer.byteLength(rawText, "utf8"),
byteOffset: Buffer.byteLength(text.slice(0, segment.offset), "utf8"),
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find TextStreamSentenceSegmenter implementations / pipe() providers passed to writeTextStream
rg -nP -C4 '\bpipe\s*\(' src --type=ts -g '!**/*.test.ts'
echo '--- segmenter option call sites ---'
rg -nP -C4 'writeTextStream\s*\(' src --type=ts
echo '--- segmenter objects ---'
rg -nP -C6 'segmenter\s*[:=]' src --type=ts -g '!**/*.test.ts'

Repository: oomol-lab/wiki-graph

Length of output: 21545


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- text-streams contract and usage ---'
sed -n '1,120p' src/document/text-streams.ts
echo '--- splitTextIntoCustomSentenceSpans ---'
sed -n '716,760p' src/document/text-streams.ts

echo '--- reader segment adapter interface ---'
sed -n '1,120p' src/reader/segment/types.ts
echo '--- default adapter implementation ---'
sed -n '1,220p' src/reader/segment/intl-segmenter.ts
echo '--- adapter entrypoint ---'
sed -n '1,80p' src/reader/segment/segment.ts

echo '--- look for any other TextStreamSentenceSegmenter implementations ---'
rg -n "implements TextStreamSentenceSegmenter|pipe\\(stream:.*AsyncIterable|segment\\.text|segment\\.offset" src -g '!**/*.test.ts'

Repository: oomol-lab/wiki-graph

Length of output: 9451


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- splitTextIntoSentenceSpans and related helpers ---'
sed -n '640,720p' src/document/text-streams.ts
echo '--- sentence record usage / readTextInRange ---'
rg -n -C3 'readTextInRange|getSentence\\(|byteOffset|byteLength|sentenceIndex' src/document/text-streams.ts src/document -g '!**/*.test.ts'

Repository: oomol-lab/wiki-graph

Length of output: 2164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- writeTextStream option types ---'
sed -n '1,220p' src/document/text-streams.ts

echo '--- serial segmenter type definitions ---'
sed -n '1,220p' src/serial.ts

echo '--- reader segmenter type definitions ---'
sed -n '1,120p' src/reader/segment/types.ts
sed -n '1,120p' src/reader/reader.ts

echo '--- all segmenter-related public APIs ---'
rg -n -C2 'segmenter|SentenceStreamAdapter|TextStreamSentenceSegmenter|segmentTextStream|writeTextStream' src -g '!**/*.test.ts'

Repository: oomol-lab/wiki-graph

Length of output: 33157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- document/fragments.ts around writeTextStream ---'
sed -n '1,360p' src/document/fragments.ts

echo '--- document index exports ---'
sed -n '1,240p' src/document/index.ts

echo '--- any writeTextStream option/type re-exports ---'
rg -n -C2 'TextStreamWriteOptions|WriteTextStreamOptions|segmenter' src/document src/facade src/serial.ts -g '!**/*.test.ts'

Repository: oomol-lab/wiki-graph

Length of output: 20940


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- location lookup and range reading ---'
rg -n -C4 'readTextInRange|getSentenceLocation|byteOffset|byteLength|sentenceIndex' src/document/text-streams.ts

echo '--- surrounding implementation ---'
sed -n '430,640p' src/document/text-streams.ts

Repository: oomol-lab/wiki-graph

Length of output: 12406


Use a raw-source span here. segment.text.length only works if the segmenter returns the exact substring from text; if it trims or normalizes output, the stored byteOffset/byteLength will be wrong and readTextInRange will reconstruct the wrong content. Use the next segment’s offset or expose a raw length from the segmenter.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/document/text-streams.ts` around lines 734 - 748, The span calculation in
the sentence-building loop is using segment.text.length, which can drift if the
segmenter normalizes or trims text. Update the raw-source range logic in the
segment iteration (the Sentence creation and byteOffset/byteLength assignment)
to derive the end of each span from the next segment’s offset or a raw length
provided by the segmenter, so the stored offsets always map to the original text
and readTextInRange reconstructs correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant