Memory

dsh-knowledge-graph

cwbcheng/dsh-knowledge-graph · ★ 1

cwbcheng

DSH Cordis plugin: turn any source text into an AI knowledge graph (facts/inferences/concepts/definitions/examples/counter-examples/rules) with two-way linking between the graph and the original text.

License
MIT
Added
2026-08-16
Maintenance
active
Install kind
github
Manifest details
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-08-19
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add github:cwbcheng/dsh-knowledge-graph

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. What it does
  2. Workspace labels
  3. Screenshots
  4. Installation
  5. 0. Prerequisites
  6. 1. Get the source
  7. 2. Install (pick one)
  8. 3. Approve the run
  9. 4. Verify the install
  10. 5. SQLite persistence and CLI
  11. Updating
  12. Uninstalling
  13. Notes
  14. Usage

English | 中文

The knowledge-graph window now fits a narrowing browser viewport while keeping its close control reachable. Connection-model directories, details and source evidence reflow within the available space; expanding restores the preferred window geometry without resetting the current model, task or unsaved edits. Only explicit dragging or resizing saves the window position.

DSH (DeepSeek Harness) Cordis plugin: turn source text, images containing text / diagrams / tables, or an AI session execution trace into an AI-generated knowledge graph, with two-way linking between the graph and the original text.

Paste text or upload images → AI asynchronously builds the graph → two-way anchor navigation. A standalone, reusable plugin realization of NovelStudio's "资料 ⇄ 知识图" (Source ⇄ Knowledge Graph).


What it does

  • The connection-model directory shows a labeled search bar and removable filters for the query, chapter, review status, concept and role. Clear one or all filters without changing the current model, task, evidence pane or unsaved edits. Chapter names remain stable while filtering the same document revision. Result ranges and distinct empty states offer recovery from unmatched filters, outdated page positions and documents without models. Text matches do not establish applicability or factual correctness.

  • Connection-model conditions, mappings and boundaries offer “旁侧核对” to show the selected field's complete stored quote and note in the evidence pane without changing the current task. Model/revision and branch identity remain visible, including for identically named branches. Full-source navigation is a separate explicit action and retains exact-quote and ambiguity checks. Changing the field cancels an earlier pending jump; changing the model, revision or loaded detail retires the old field selection. Inspecting a quotation neither verifies its meaning nor writes graph data.

  • Connection-model details group actions into Reading, Learning and Checking while retaining the Chinese ontology terms, including “下上对照”. Larger titles and body text separate inputs, mappings/conditions and outputs; each boundary stays next to its provenance, and unknown-role endpoints remain separate. An independent evidence pane keeps the current exercise or review open and follows the selected model/revision, with a stacked layout in narrow panes. Opening evidence does not submit or discard a direction preview; quoted source remains evidence to check, not proof of the mapping.

  • Connection-model structure drafts reopen with unfinished example scenarios, example/branch names and source quote/paragraph fields intact. Recovery still checks field types, size limits, distinct identities and compatible bindings; malformed cache bytes remain untouched. These unfinished required fields stay in the diagnosis and block formal preview until completed. Saving still requires a fresh preview, explicit confirmation and the original graph revision; restoring a draft does not verify its mappings or evidence.

  • Consecutive connection-model structure edits reuse the current private draft's own JSON serialization while still creating an independent copy, caching every edit immediately and recomputing the full diagnosis. Storage failures, external cache changes, model/revision switches and discard/reload retain existing draft behavior; preview, confirmation and revision checks remain required. node scripts/kg-model-draft-copy-benchmark.mjs 88914ad compares actual generated editors: full serialization calls per edit/diagnosis fall from 3 to 2, with unchanged parse and storage-write counts. For 40 slots, 40 branches and 100 examples, 21 × 24 alternating samples give a median of 3.117 → 2.731 ms. Timings cover the edit event and render, excluding real browser storage I/O, DOM, network and heap memory; there is no CI timing gate.

  • Larger connection-model drafts share example binding status within each diagnosis after shape validation. Missing inputs/outputs, unpaired branches, provenance and condition/boundary warnings retain their full report. For 40 slots, 40 branches and 100 examples, repeated binding-match visits fall from 58232 to 0, replaced by one example-status projection. Invalid/small drafts and raw objects retain defensive diagnosis. node scripts/kg-model-draft-bindings-benchmark.mjs 19bd4ec compares full reports, raw read/exception order and generated-editor edit-event/render timings, including draft cloning and storage but excluding real browser DOM. Indexes do not survive an edit; writes still require preview, explicit confirmation and revision checks.

  • Connection-model diagnostics retain endpoint identity types: missing IDs, null, numbers and objects differ from identically spelled string concept IDs. Delimiters in identities or roles cannot conceal a difference. The warning asks for review without adding graph edges or proving mappings. node scripts/kg-model-diagnostic-identities-compare.mjs c2c37bc compares raw read and exception order, full diagnoses and 25 alternating source timing samples; regressions cover generated drafts, Host/SQLite HTTP, revisions and read-only learning boundaries.

  • Connection-model summaries with different slot and legacy-endpoint counts retain the difference warning after reading every identity and explicit role, without sorting the legacy signature or serializing either comparison array. Equal counts still receive the full identity, role and multiplicity comparison. For 16 models with 40 slots and 1024 legacy endpoints each, signature values sorted fall from 17024 to 640 and comparison JSON characters from 295776 to 0. node scripts/kg-model-summary-signatures-benchmark.mjs a3f7d21 separates work counters from 25 alternating source timings and checks full responses, raw getters and identity coercion errors; real Host/SQLite HTTP regressions preserve source and learning read-only boundaries. No mapping truth, applicability, HTTP, browser or heap-memory performance claim is made.

  • Connection-model summaries collect inputs, outputs, unknown-role warnings and completeness in one pass over their internal endpoint projections. For 128 models with 40 endpoints each, role reads fall from 20480 to 5120 for legacy relations and from 30720 to 15360 with recorded structures; full quotation validation and separate legacy warnings remain. node scripts/kg-model-summary-roles-benchmark.mjs 01698de compares full responses, exceptions and raw-data read order, with work counts separate from 25 alternating source timings. Explicit roles, distinct slots, conditions, boundaries and evidence are preserved, with no HTTP, rendering or heap-memory performance claim.

  • Connection-model material pages retain at most 20 entry references while collecting all canonical identities, avoiding a full temporary array of off-page references. Full source-context queries and accessor modes keep their original collection and read order. Totals, encounter order, indirect links, conditions and evidence remain unchanged. node scripts/kg-model-related-values-benchmark.mjs 78b1870 checks complete response/exception parity and reports separate work counts and alternating source timings; the measured timing benefit is small and varies by page, with no HTTP, rendering or heap-memory claim.

  • Asynchronous AI extraction: paste any text (chapters, technical docs, study notes…); a background task calls the LLM and saves the knowledge graph when the task completes. documentId is a random stable logical-document UUID, sourceId is a SHA-256 identity of the complete immutable source version, and each chunkId binds sourceId + batch + paragraph range, so different documents and appended source versions cannot overwrite one another through local chunk-0001 reuse. In persistent mode the full source, canonical graph, and lossless checkpoint live in SQLite; the browser restores by documentId/runId, and only a running task orphaned by a Host restart may resume from checkpoint. Explicit failed/cancelled tasks are never auto-retried.

  • Build a graph directly from PDF: the workbench accepts a searchable PDF up to 15 MiB, extracts its text locally under bounded limits, fills the source panel, and starts graph generation. The file payload is used only for that import and is not saved in the browser draft. Complex layouts and custom font encodings may produce incomplete text; scanned PDFs are not OCRed yet and must first be converted to searchable PDFs.

  • Build a graph directly from images: the workbench accepts 1–4 PNG / JPEG / WebP / GIF images (up to 6 MiB each and 16 MiB total), including text screenshots, flowcharts / architecture diagrams, charts, formulas, and tables; optional instruction text may accompany them. The Host first admits the bounded browser base64 through DSH attachments.saveImages(), then asks a multimodal model for a canonical visual transcript with per-image paragraph ranges. The existing text graph extractor consumes only that transcript. The result preserves an original-image gallery and source.visualSource provenance, and clicking an image jumps to its transcript. Visual transcription emits separate relationship units for arrows/links, grouping/containment, object correspondence, order, and color/shape encodings that have explicit legend semantics; a bounded post-extraction coverage review recovers diagram relationships omitted by the first graph pass. A relationship that cannot be mapped honestly to a built-in relation is preserved as an atomic fact/claim instead of being forced into a wrong edge. A visual transcript is model-derived rather than deterministic pixel OCR, so important words, values, table cells, and diagram arrows must still be checked against the original. Image input currently creates a new graph; incremental append remains text-only.

  • 8 node types / 12 relation types:

    • Nodes: fact · claim · inference · concept · definition · example · counter_example · rule.
    • Relations: supports · example · counter_example · defines · infers · causes · is_a · contains · driven_by · not_is · analogy · aims_at.
    • Minimal semantic contract: one node expresses one atomic proposition; source/author theories and empirical generalizations use claim rather than fact; qualifiers such as “possible / most / usually / must / if” must be preserved; use a precise semantic relation instead of falling back to supports when the source makes that relation explicit.
    • Explanatory coverage review: after the first extraction passes deterministic admission, a bounded second look runs only when a multi-step mechanism appears underrepresented or the source explicitly states a correction / anti-misinference boundary / answer deferred to later text that the graph omitted. It may also recover a stable concept anchor reused by multiple core propositions. Before the optional reviewer runs, the Host deterministically restores source-explicit atomic conclusions of the form “named method fails under an explicit condition” as node-only additions; related edges still require direct source evidence and relation-weaver review, never mere same-paragraph co-occurrence. The review normally adds only missing nodes plus necessary incident relations; for a 【图示关系】 paragraph it may also add a relation-only edge between existing nodes when an arrow, connector label, grouping, correspondence, or legend directly proves an allowed relation; that exception still requires one evidence quote to contain a relation-specific explicit cue, both endpoints, and a compatible direction. It cannot rewrite the accepted graph or add knowledge merely to improve connectivity.
  • 《学习观》 ontology graphs (learning-view-v1): a second extraction ontology, not a re-cut of an existing graph. Node and relation types follow 于建国's 学习观: knowledge (concept / feature / rule / discrimination_model / connection_model) and learning material (intension_description / feature_description / positive_example / negative_example / contrast_group / extension_contrast / relation_material / factor_material / property_material / segment_example_group / verification_material / data_or_experience / memory_material) are built as separate nodes — 18 node types and 21 relation types. Every material carries two orthogonal coordinates, modelKind (discrimination / connection) and layer (upper / lower), which is what makes knowledge-collapse diagnostics possible: lower-missing, upper-missing, layer mismatch, model mismatch, empty connection model, memorizing words, words-without-meaning, meaning-without-words, recycled verification, missing verification, and learning material stored as memorization material. Extraction is LLM-only and still yields a storable / queryable / exportable / appendable knowledge graph; documents with no ontology keep the original proposition ontology and behave exactly as before. How to use it: pick 《学习观》 in the "知识图模式" selector in the extraction form; the default stays the proposition ontology and is sent as no parameter at all, so existing behaviour is unchanged. A document renders under the ontology it was extracted with — the mode badge, legend, coordinate grid, diagnostics strip and edge attributes all follow — and an already-stored document keeps the proposition graph it has, so seeing the 《学习观》 version means extracting again. The mode only affects new extractions; it never rewrites a document. Edge attributes are ontology data too: the role on maps_between (input/output), the sign on contrasts, and the mode on compares_* (contrast/analogy) are appended to the edge label, with the value labels shipped by the ontology — the proposition ontology declares no attributes, so it renders none. Layout reads the ontology too: the layered view's backbone, satellite attraction, and branch lanes are derived from the document's own relationTypes family / weight, so a 《学习观》 graph opens out along its own structure instead of collapsing into a hairball because its relation names are absent from a hardcoded proposition table. Each material's two coordinates are also shown: a grid under the legend breaks the graph into 判别上料 / 判别下料 / 联结上料 / 联结下料 plus other materials and knowledge, and only a profile that declares coordinates renders it. See docs/learning-view-ontology.md.

  • Relation-aware layered layout: layered mode ranks and resolves overlaps inside each undirected connected component before compactly packing the component rectangles, so unrelated subgraphs can no longer stretch direct neighbours across shared global rows. Within each component, relation-weighted ordering treats the backbone relations (causes/infers for the proposition ontology; whatever a profile marks family = backbone) as the spine, keeps satellite relations as nearby branches, and uses directional relations as bounded soft proximity preferences. Which relations those are, and their weights, come from the current document's ontology rather than being hardcoded in the client. When edges share a node or inter-row band, arrow ports, horizontal channel tracks, and overlapping vertical corridors are allocated independently, with taller inter-row channels reserved for dense horizontal tracks; neighbouring relation chips are deterministically staggered within a readable distance when their rectangles collide; in pathological saturation an unplaceable chip stays hidden until its relation is hovered or selected, so lines, labels, and arrows do not crowd together. New users default to layered layout; existing saved layout preferences are preserved.

  • Connected-neighbour compaction: wrapped rows are an initial placement, not permanent rank barriers. A bounded, deterministic two-dimensional relaxation shortens relation-weighted edges while preserving reasoning order, pinned backbone lanes, node spacing and inter-row routing channels. Empty rows are removed afterward. Corridor search uses actual obstacle intervals rather than a fixed search radius. High-degree hubs and cross-links can still require longer edges; this changes only the view, never the canonical graph or its relations.

  • Two-way linking:

    • Click a graph node → opens a detail card (full content + verbatim quote + locate button) and smoothly scrolls to and highlights the matching content unit;
    • Click a source content-unit number or press Enter on it → the graph centers on and pulses the corresponding node. If the node lies outside the current large-graph window, the workbench or trajectory tab loads its ordinary page using the stored paragraph index and the existing node limit. A target outside the active relationship neighborhood returns to the base window for focusing. It checks the document revision and source quote before focusing; later navigation cancels old responses, and a paragraph without a matching node leaves the graph unchanged.
    • Nodes in the graph render only the first 4 lines (overflow collapses to …); the full content is always available in the detail card;
    • Anchoring primarily uses the content-unit index the AI reports directly (deterministic — long natural paragraphs are split into numbered units at sentence boundaries), with exact-quote matching and token-overlap scoring as fallbacks; nodes that cannot be linked are never guessed into an offset — they go to a diagnostics list.
  • Graph rendering: SVG canvas + 8-color node palette / 4 switchable layouts (dropdown at the graph's top right, choice remembered): Force (embedded d3-force engine, zero dependencies: collision avoids node overlap, edge–node repulsion keeps arrows from crossing nodes), Circular, Radial (central hub + BFS rings; edges drawn as polylines: radial exit → outer arc → radial entry), Layered (edges drawn as orthogonal right-angle polylines: inter-row channels + per-row obstacle corridors; segments never cross nodes) / relation edges carry type labels, and edges sharing a source fan out by target angle (quadratic Bézier) / drag to pan / Ctrl+wheel to zoom / toolbar − 100% + (50%–200%, 10% steps) / long-press a node to see the verbatim quote / keyboard accessible.

  • Large-graph browsing performance: ordinary layouts reuse node and text elements during pan and zoom. The all-node overview uses a spatial index to update the visible region and reuses the scene while visible membership stays unchanged; fit-to-canvas still represents every node. Node text and original-image previews appear from 35% overview zoom. Search and source navigation cover the complete graph. Loading counts relation degrees once for all node-measurement batches; both counting and text measurement yield between bounded batches so cancellation remains responsive. A closed search panel or empty query does not pre-normalize every node name and excerpt. The first text query caches only nodes in the selected type; subsequent queries reuse that cache, and replacing the graph invalidates it. Text searches above 200 nodes use batches with an 8 ms budget and display a pending status. Changing the query or type, closing search, or replacing the graph cancels old work; navigable results appear only after the current query completes. Narrower keywords or types check only the last completed matches. Backspacing, changing keywords or broadening the type restores the full search scope; cancelled partial results never become candidates. Switching overview focus queries indexed incident relations; selecting any parallel relation retains and highlights the shared path. Consecutive selections reuse node shells whose visual state is unchanged and preserve full accessible excerpts. Replacing the graph, layout, source images, anchors or review report refreshes the relevant content; cached elements cover only the current viewport.

  • Image-source lookup performance: image-containing graphs index original-image node IDs and visual-transcript ranges; source rows index figures by paragraph. Neither path rescans the image list for every node or paragraph. Overlapping transcripts still select the first original entry. Split tables collect figures from all member paragraphs in source-list order, preserving distinct entries even with repeated image IDs. Replacing metadata refreshes labels, figures and details without changing paragraph anchors, source text or source objects. Storage follows interval boundaries and explicit paragraph references rather than expanding transcript ranges. Run node scripts/kg-graph-image-benchmark.mjs [baseline-commit] and node scripts/kg-source-image-performance.mjs [baseline-commit] to compare image-record reads and initial scene/source-row construction times. Timings include counter overhead; deterministic regressions check exact provenance and read-only behavior. For browser checks, node scripts/kg-verification-ui-fixture.mjs --source-image-performance starts an isolated 12,000-paragraph / 200-image workbench.

  • Source page lookup performance: SQLite computes the target page from the number of nodes with no paragraph plus those in earlier paragraphs, using two ranges of the existing paragraph index. It preserves the first binary node ID within the paragraph, NULL-first ordering, window limits and revision snapshots without adding an index. Run node scripts/kg-paragraph-rank-performance.mjs to compare the original rank predicate; --smoke checks ordinary-page parity with random, tied and sparse paragraph data. Timings cover rank SQL only, excluding window hydration, diagnostics, HTTP, view construction and browser rendering.

  • Window linking in long sources: paging looks up node anchors in ordered paragraph spans, avoiding a scan from the first paragraph for every node. Paragraph identities, whitespace gaps, exclusive ends and full quotes retain the same semantics; all-node views use the same lookup. Run node scripts/kg-paragraph-window-benchmark.mjs [baseline-commit] to compare four tail windows and all nodes across 12,000 paragraphs, check complete view parity, and report uninstrumented median timings separately from boundary-read counts. Timings cover view construction and exclude network requests, layout and browser drawing. For browser checks, node scripts/kg-verification-ui-fixture.mjs --paragraph-window-lookup starts an isolated sample.

  • Legacy quote linking performance: when old records have no paragraph metadata and quotes cannot be located directly, prefix/suffix matching checks the longest and shortest fragments, then searches nested fragment lengths with binary search instead of rescanning the source at every length. Prefix precedence, the longest matching fragment and its first offset retain their behavior; exact/normalized matching and fuzzy fallback are unchanged. The first token fallback keeps the original scan and tokenizes each paragraph once. A second fallback converts those sets to token-to-paragraph postings and releases the sets; later queries update scores for matching paragraphs. Single-paragraph words store one index, shared words store index lists, and each query resets and reuses the score buffer. Direct anchors build no token state. Duplicate query weights, the minimum score and first-paragraph ties retain their behavior; state is not retained across views or documents. Run node scripts/kg-legacy-token-benchmark.mjs [baseline-commit] to compare 200/800 legacy quotes, sparse terms, single cold queries, prefix/suffix hits and direct quotes across 12,000 paragraphs, verify complete view parity, and report uninstrumented five-trial timings separately from tokenization, matching and allocation counts. Timings exclude HTTP, layout and browser drawing. Separately run node --expose-gc scripts/kg-legacy-token-benchmark.mjs [baseline-commit] --memory-only to compare live token-state deltas after the second score; explicit-GC diagnostics exclude whole-page memory and transient peaks. node scripts/kg-verification-ui-fixture.mjs --legacy-token-lookup starts an isolated sample with 200 legacy quotes; --legacy-fragment-lookup mixes prefix, suffix and token-fallback cases.

  • Quote normalization performance: whitespace and punctuation matching keeps its original precedence. Normalization copies retained text runs and maps every emitted UTF-16 unit to its source offset. Only space, LF, Tab and ideographic space are normalized as whitespace; CR, other Unicode whitespace, punctuation membership and leading/trailing behavior remain unchanged. A view builds at most three source forms; direct quotes skip normalization and declared paragraphs keep local matching first. Run node scripts/kg-anchor-normalization-benchmark.mjs [baseline-commit] to compare all three modes, Chinese/astral text, one/two/200/800 legacy quotes and local/direct controls across 12,000 paragraphs. It verifies complete view and offset parity and reports five uninstrumented trials separately from source output-part, mapped-unit and per-character punctuation-check counts. Timings exclude HTTP, layout and browser drawing. node scripts/kg-verification-ui-fixture.mjs --normalized-anchor-lookup starts a mixed three-mode browser sample.

  • Source table preprocessing performance: sources with no complete tables or only oversized tables skip code-region scanning. The first table keeps the original lookup without an order check. A second lookup validates paragraph order and disjoint ranges once, then uses binary lookup; malformed or unsorted ranges retain the former first-overlap rule. Split tables, literal code examples, source offsets and paragraph anchors keep their behavior. Run node scripts/kg-source-table-performance.mjs [baseline-commit] for 12,000 paragraphs, 400 tables and mixed code examples, checking complete groups and parser calls. Seven uninstrumented trial medians are separate from boundary-read/code-scan counters. Timing excludes native HTML parsing, paragraph splitting, HTTP and React/DOM rendering. node scripts/kg-verification-ui-fixture.mjs --source-table-lookup starts a browser sample with 400 split tables plus 400 inline and 400 indented examples.

  • Trajectory source linking performance: the trajectory tab builds one range lookup for its current event list and reuses it during selection and pulse updates. Multiple source units from a long event retain its actual kind and sequence. Replacing the event list rebuilds the lookup; whitespace gaps and legacy paragraph-index fallbacks keep their behavior. Unsorted or overlapping imported ranges retain the first matching entry in source-list order. Run node scripts/kg-trajectory-event-performance.mjs [baseline-commit] to compare initial row construction and four selection updates across 12,000 paragraphs/events, with counters separate from timings and complete row parity checks. Timings exclude HTTP, graph preparation and React/DOM reconciliation. node scripts/kg-verification-ui-fixture.mjs --trajectory-event-lookup starts an isolated 12,000-paragraph sample whose first event spans three units and whose sequences differ from paragraph numbers.

  • Verify & question the graph: once a graph exists, check whether it is faithful to the source text —

    • ⚡ Quick check: instant local rules (self-loops/dangling edges, quote grounding, paragraph-vs-quote mismatch, type–relation semantic rules, duplicate / suspected-contradiction nodes, isolated nodes, coverage stats);
    • 🤖 AI deep audit: an asynchronous LLM pass adversarially reviews each node/edge; every issue must cite verbatim source evidence, and the standard mode runs a second confirmation pass to suppress false positives;
    • Human-in-the-loop fix: issues are listed by severity (error / warning / suggestion); clicking an issue tints the graph target by severity and scrolls to the source paragraph; each issue can be applied (patched immediately, written to an audit log) or dismissed; a fix all button applies every automatically fixable issue at once, and the fix log shows concrete old → new diffs;
    • Ask questions: the node detail card offers question this node, selecting an edge shows an edge card with question this relation, and the verification panel lets you question the whole graph; the AI answers with one of supported / contradicted / insufficient / out-of-scope plus source evidence;
    • 🔎 External fact-check of the source: fact/claim/inference/rule/definition/counter-example nodes become checkable claims and are judged against external evidence (built-in free Wikipedia retrieval plus optional pasted domain-rule sources); verdicts are supported / contradicted / partially supported / insufficient / unverifiable / out-of-scope, every conclusion carries an evidence link and a verbatim evidence quote (quotes that cannot be located in the retrieved snippets are automatically downgraded);
    • Verification / fact-check results are persisted with the graph; appending new content marks them stale for re-running. The trajectory graph tab supports all of the same capabilities.
  • Floating workbench: draggable, resizable window; the width ratio between text and graph and the result area height are both drag-adjustable and remembered.

  • Select-to-split: select any text inside a chat message; a "拆成知识图" (split into graph) button floats above the selection — one click opens the workbench and splits the selection; selecting text in the result's source column splits it as a sub-graph; selecting part of the input textarea also offers "split selection".

  • Incremental append (追加资料): once a result exists, the input panel's primary button becomes 追加资料 (add source material) — paste the next passage / document and the AI extracts ONLY the new content, linking it into the existing graph via cross-passage edges (a concept that reappears is not duplicated — it gets an edge straight to the existing node); the result merges in place, paragraph numbering stays unified across the whole text, and the history entry updates in place. Selecting text in a chat message while a result exists appends it to the current graph automatically.

  • History: every successful split records a lightweight browser index (up to 20 entries, deletable one-by-one or all); the browser keeps only documentId, title, counts, and timestamps, then reloads the source and canonical graph from Host/SQLite instead of copying book-sized payloads into localStorage.

  • Multiple graphs at once: use “新建知识图” while a graph is generating; the previous task keeps running in the background. Each task has its own progress, pause/resume, cancellation, usage and checkpoints. The default limit is 4 concurrent tasks, configurable with DSH_KG_MAX_CONCURRENT_TASKS (integer 1–16; invalid values fall back to 4). Preparation occupies a slot; requests over the limit return busy without starting a model call. Tasks and edits on the same document remain exclusive, while unrelated documents can run and be edited independently. Per-graph batch concurrency still applies, so aggregate model concurrency increases with the number of running graphs. npm run test:kg-multitask exercises isolated overlap and persistence; node scripts/kg-multitask-ui-fixture.mjs serves a synthetic UI without contacting a model or production service.

  • Chapter filtering and candidate review: filter the graph and source paragraphs by chapter; review evidence-bearing entity / claim candidates as candidate / accepted / rejected and click a candidate to jump back to its source. Decisions sync through the Host to SQLite (dynamic plugins retain them in the Host session, with browser localStorage as fallback).

  • Knowledge consumption layer: source graphs and trajectory graphs share a “Use this knowledge graph” panel. It provides bounded structured search by text, node type, chapter, grounding status, and entailment status, while keeping direct matches distinct from relation neighbours. Evidence Q&A reads the server-side canonical graph and authenticated source only; the model may cite only Host-assigned evidenceId values, and every admitted answer part must carry node, edge, or source-paragraph evidence. Clicking a result or citation links back to graph and source; if the node lies outside the current 800-node renderer window, the client loads a canonical subgraph by node ID before locating it.

  • Knowledge graph export: the graph toolbar exports the current rendered graph as a high-resolution PNG image, and the result toolbar exports the complete graph as JSON (including source, chunk, evidence, verification, and audit data) or as separate node and edge CSV files. Data exports always contain the full graph, independent of the active chapter filter; trajectory graphs support the same exports.

  • Persistent entry: a permanent 「知识图」button on the right of each conversation header; run cards also get a launch bar.

  • Trajectory knowledge graph (conversation view tab): a third tab 「轨迹知识图」(beside 对话 / 轨迹) turns the current session's full execution trace (user messages, tool calls, tool results, assistant replies) into a knowledge graph — visualizing what the agent found, inferred, and did — with two-way linking between graph and trace events. Results are canonical Host/SQLite documents; the browser stores only the trajectory documentId/revision reference, so tab switches or page reloads rehydrate from canonical state rather than from a copied graph. Leaving mid-extraction and returning resumes polling automatically. Once the session produces new events, 追加新事件 (append new events) submits the same document id plus the expected revision, reloads the complete canonical graph Host-side, and merges only the new events; hidden nodes beyond the 800-node browser window therefore cannot be lost. The event-column / graph-column width and result height remain drag-adjustable and remembered.

Workspace labels

The Chinese interface groups tasks into 阅读知识图 (read the graph), 查找与学习 (search and learn), 检查与修正 (check and correct), and 导入资料 (import sources). Use 生成知识图 to create a graph and 追加资料 to add material to the current graph. 阅读导航 provides chapter and concept entry points; 阅读书签 saves browsing state. 联结模型 corresponds to the ontology's connection_model, and 渐构靶图 records personal understanding separately from source knowledge.

The same labels appear in tooltips, accessible names, progress messages and the Chrome extension. Source text, ontology identifiers and learning records keep their original meaning. See the UI copy guide for wording, terminology and coverage.

Screenshots

Early source/graph comparison view (the current workspace uses the four tabs above):

┌────────────────────────── Floating Workbench ──────────────────────────┐
│ ● Knowledge · Source ⇄ Knowledge Graph                     [ × ]        │
│ [Source text ────────────── collapse ▴]                                 │
│ [Source ⇄ Knowledge Graph]                                              │
│ One-line summary: …                                                     │
│ N nodes · M relations · X/Y linkable ─────────────────────┐             │
│ [paragraphs…badges]  ‖  [graph SVG…]  [− 100% +]  ← drag  │             │
│ ─────────────── drag height ───────────────               │             │
└────────────────────────────────────────────────────────────────────────┘

Trajectory knowledge graph tab:

┌────────────────────── Trajectory ⇄ Knowledge Graph ─────────────────────┐
│ Split this session's trace: user / tool call / tool result / AI reply   │
│ One-line summary: …                                                     │
│ [trace events…badges]  ‖  [graph SVG…]  [− 100% +]  ← drag width        │
│ ────────────── drag height ──────────────                               │
│ (result restored after tab switch / page reload)                        │
└─────────────────────────────────────────────────────────────────────────┘

Installation

This is a DSH dynamic Cordis plugin: one Host half (Node process) + one Client half (browser), plain JS, zero dependencies, no build step. It loads through DSH Web's Cordis plugin mechanism and works in any DSH Web session.

0. Prerequisites

  • DSH Web is running (dsh web) and you are inside a session;
  • An AI model provider is configured (Settings → Models, or agentDefaultModel). The plugin follows the system default by default; both the workbench and the “Trajectory Knowledge Graph” tab include a model dropdown so you can manually choose the model used for extraction, appends, AI audit, questioning, and external fact-checking (the choice is saved in browser local storage). If none is configured, it shows a clear Chinese error message. Image extraction requires a multimodal model that accepts image input. The picker labels known image and text-only models; models with unknown metadata may be attempted, while provider rejection is surfaced as typed model_image_unsupported.

1. Get the source

git clone https://github.com/cwbcheng/dsh-knowledge-graph.git
cd dsh-knowledge-graph
File Purpose
src/index.host.js Host half: async AI extraction engine (paragraph numbering, batching, schema validation, typed diagnostics, model routing, session-trace serialization) + graph verification/questioning + canonical structured search and evidence-ID Q&A
src/index.client.js Client half: floating workbench UI, graph rendering, two-way linking, shared search/evidence-Q&A panel, verification & questioning, fix application/audit, history, resizing, trajectory graph tab
src/kg-store.mjs SQLite persistence: documents, chunks, nodes, edges, evidence, candidates, extraction checkpoints, and bounded large-graph consumption queries

2. Install (pick one)

Option A: let an Agent install it (recommended)

Send this to the Agent in any session (replace the path with your clone location):

Please read src/index.host.js and src/index.client.js from the dsh-knowledge-graph repo, define these two files as the Host half and Client half of a Cordis plugin, and run it.

The Agent runs cordis_define (define) → cordis_run (run); an approval card pops up in the UI.

Option B: paste the source and define it yourself

  1. Run a cordis_define in any session (have the Agent do it, or follow your environment's Cordis tool flow);
  2. Paste src/index.host.js into the Host half and src/index.client.js into the Client half;
  3. Paste the function body: strip the export default function hostPlugin() { / export default function clientPlugin() { line and the matching trailing }, keep the return { ... }; part in between (the header comment may be kept or dropped).

Not familiar with cordis_define? Use Option A — the Agent handles the function-body extraction automatically.

Option C: persistent install (recommended — survives restarts)

Install the repo as a web-profile composition plugin (same community-plugin package shape as dsh-hud): the Host half serves a webServer route, the Client half is a __ModuleLoader__ browser module; it auto-loads with dsh web — no redefinition after every restart, no approval.

# 1. Add the dependency and bundle to the profile ($DSH_HOME defaults to ~/.dsh)
cd ~/.dsh/profiles/web
#    add to package.json dependencies:
#    "dsh-knowledge-graph": "github:cwbcheng/dsh-knowledge-graph#main"
#    add to package.json dsh.profile.bundles:
#    "dsh-knowledge-graph"
pnpm install

# 2. Restart dsh web (Ctrl+C, then `dsh web` again)

After the restart: the 「知识图」button appears at the right of each conversation header. Browser localStorage keeps only lightweight UI state such as layout and history indexes; source text, graph, checkpoints, and revisions are persisted by Host/SQLite.

File Purpose (persistent package)
lib/index.js Host half: task engine + /api/dsh-knowledge-graph routes for extraction/append, task status, document-load/canonical-membership-checked image-load/document-export, revisioned graph-commit, graph-query, answer-graph, safe resume-extract, verification/questioning, plus automatic SQLite canonical-graph/checkpoint persistence
lib/client.js Client half: __ModuleLoader__ browser module (fetch RPC + manual style injection)
cordis.patch.yml bundle patch: inserts the dsh-knowledge-graph row into the composition

src/ and lib/ are two deployment shapes of the same plugin: src/ for the dynamic plugin (Options A/B), lib/ for the persistent composition (Option C); the logic stays in sync.

3. Approve the run

After defining, the run enters awaiting approval:

  • The plugin panel (bottom-left Cordis Plugin button) pops up automatically and highlights the row awaiting approval;
  • Click ✓ (single check): authorize this run only; click ✓✓ (double check): also authorize automatic runs of future versions (recommended);
  • After approval the plugin activates in the browser and the panel shows running.

4. Verify the install

  • The 「知识图」button appears at the right of the conversation title (header action row);
  • Click it → the floating workbench opens; paste a text → 生成知识图; read the knowledge graph when the task completes;
  • A third tab 「轨迹知识图」appears at the top of the conversation area (对话 / 轨迹 / 轨迹知识图); click it → 生成会话知识图; read the session graph when the task completes.

5. SQLite persistence and CLI

The CLI uses Node node:sqlite and requires Node 22.13+ without an experimental-sqlite flag. Imports require an explicit --db or DSH_KG_DB, the full sourceText, and the same deterministic admission gate as the Host. Imported files cannot grant themselves verified entailment. Imports are create-only unless --expected-revision N explicitly fences a replacement.

npm run kg -- init --db ./data/knowledge.sqlite
npm run kg -- import-graph --db ./data/knowledge.sqlite --input ./graph.json
npm run kg -- list-candidates --db ./data/knowledge.sqlite --kind entity --status candidate
npm run kg -- list-candidates --db ./data/knowledge.sqlite --kind claim --status candidate
npm run kg -- set-candidate --db ./data/knowledge.sqlite --kind entity --id ent_xxx --status accepted
npm run kg -- set-candidate --db ./data/knowledge.sqlite --kind claim --id clm_xxx --status rejected
npm run kg -- list-documents --db ./data/knowledge.sqlite
npm run kg -- show-document --db ./data/knowledge.sqlite --id document_xxx
npm run kg -- save-checkpoint --db ./data/knowledge.sqlite --input checkpoint.json --run-id run_xxx
npm run kg -- load-checkpoint --db ./data/knowledge.sqlite --run-id run_xxx
npm run kg -- list-revisions --db ./data/knowledge.sqlite --id document_xxx
npm run kg -- restore-revision --db ./data/knowledge.sqlite --id document_xxx --revision 2 --expected-revision 5

The persistent lib/index.js writes each successful chunk and completed graph to SQLite automatically. Set DSH_KG_DB to choose the database path; otherwise it uses .dsh-knowledge-graph.sqlite in the current working directory. npm run test:kg verifies graph/chunk/evidence persistence, candidate state changes, checkpoint storage, and document restoration in an in-memory SQLite database; npm run test:kg-consumption covers dynamic RPC, persistent HTTP and SQLite query parity, retrieval beyond the 800-node view and beyond 600 common early candidates, relation-only selection, aggregate context budgets, revision fencing, invalid filters, node/edge/source citation admission, unknown and valid-but-unrelated evidence IDs, authority qualification, clause-smuggling rejection, and both frontend mounts; npm run test:kg-timeout uses non-cooperative providers to cover real wall-clock deadlines, late-iterator cleanup, and immediate cancellation; npm run test:kg-image covers dynamic/persistent image admission, multimodal content blocks, text/table/diagram transcription, recovery of omitted color-grouping and object-correspondence relationships, typed text-only-model rejection, visual provenance, canonical-membership-checked image reads, forged visual-checkpoint rejection, immediate post-transcription checkpoint/run-ID recovery, and the no-raw-base64 SQLite boundary; npm run test:kg-performance exercises keyset paging and bounded responses on a graph with more than 10,000 nodes and edges; npm run test:kg-candidates covers candidate list/update flows. The persistent build also copies lib/kg-store.mjs.

Graph replacements snapshot the previous graph and source units in the same transaction. Restoration creates a new CAS-fenced revision. Old count-only revisions are explicitly non-restorable; unavailable historical contents cannot be reconstructed. Include the growing snapshots in database backups. Removing or clearing browser history hides indexes, not SQLite documents; Restore history makes those documents visible again.

npm test also covers the independent pipeline, missing-revision rejection, asynchronous history races, simulated OCR interruptions, and CRX payload parity. See the OCR pipeline guide for commands and safety boundaries.

Updating

  • Dynamic install (A/B): repeat Option A after repo updates — have the Agent re-read both source files and cordis_define (append a new Package under the same plugin), then cordis_run (update mode) to switch versions; if you previously clicked the double check, new versions run automatically.
  • Persistent install (C): after updates, re-run pnpm install (pulls latest #main) and restart dsh web.

Uninstalling

  • Dynamic install: open the Cordis Plugin panel → click Stop on the plugin row to pause; use cordis_undefine to delete the definition entirely.
  • Persistent install: remove the dependency and bundles entries from the profile's package.json, then pnpm install and restart.

Window layout, history indexes, and other lightweight UI state live in browser localStorage; book-sized sources, canonical graphs, checkpoints, and graph revisions live in Host/SQLite in persistent mode. Keep the SQLite database or export JSON/CSV before uninstalling if you need long-term retention.

Notes

  • A dynamic plugin runs inside the DSH process: it disappears after a process restart and must be reinstalled (Option A, or switch to persistent Option C; browser data remains); the persistent plugin loads with the service and is unaffected by restarts;
  • The Host half needs a working LLM (see prerequisites); AI calls happen only inside your own DSH environment — whether they leave it depends on the model provider you configured. Image extraction sends DSH-admitted originals to the selected multimodal provider, so review that provider's data policy before using sensitive images;
  • This project has no paid / quota features: extraction, history, and two-way linking all run locally.

Usage

  1. Click the 「知识图」button at the right of the conversation title to open the floating workbench;
  2. Paste text into 「导入资料」, or click 上传图片 to choose images containing text, diagrams, or tables (optional instruction text and title may accompany them). Choose an image-capable model and click 生成知识图. Image-derived results show an original-image gallery and visual-transcript warning above the source column (the input area collapses; result height and text/graph width ratio are drag-adjustable and remembered);
  3. Once the summary / graph appears, click a graph node to view the detail card (full content) and locate the source, or click a source paragraph to focus its node;
  4. In Use this knowledge graph, switch between structured search and evidence Q&A: find nodes by text/type/chapter, or ask the canonical graph directly; click a result/citation to link back to node, relation, and source evidence;
  5. Click ⚡ 规则检查 (quick check) for an instant deterministic report, or 🤖 AI 原文核对 (deep audit) for an evidence-grounded adversarial LLM review; click an issue to tint its graph target and locate its source paragraph, then apply the fix or dismiss; question a node from its detail card, an edge from its selected-edge card, or the whole graph from the verification panel;
  6. In 章节与候选审核 (chapter and candidate review), choose a chapter to filter the

…