feat(connector): Obsidian vault data-source connector (cognee#4725) - #165
Open
tonydzi wants to merge 1 commit into
Open
feat(connector): Obsidian vault data-source connector (cognee#4725)#165tonydzi wants to merge 1 commit into
tonydzi wants to merge 1 commit into
Conversation
Add packages/connector/obsidian/ following the shape of the notion and google-drive connectors: a document-mode dlt resource handed to cognee.remember() with write_disposition="merge" and a _deleted hard-delete column. - Ingest: every *.md in the vault; YAML frontmatter -> record metadata (JSON column + Properties section in the text); body -> content. - Wikilinks -> edges: [[note]], [[note|alias]] (target is the note, not the alias), [[note#heading]] (target is still the note), and embeds ![[note]] (edge + transclusion flag). Name-based vault-wide resolution like Obsidian itself: case-insensitive, shortest path on ambiguity, path-style links resolve by path. Resolved links are emitted as a structured links column and rendered into the note text so entity extraction turns them into note->note edges. - Default exclusions: .obsidian/, .trash/, *.sync-conflict-* (sync tools grow near-duplicate conflict copies that poison dedup). - Incremental cursor: per-file (mtime, size, sha256) map in dlt resource state. mtime+size are the fast path; the hash is authoritative, so an mtime moved BACKWARDS by a sync tool still syncs the edit, and a touch without an edit does not re-ingest. The hash covers the rendered row, so link re-resolution (a new note satisfying an old [[link]]) also re-syncs the linking note. - Forget-on-delete: previous run's path snapshot; absent paths become _deleted tombstones; a rename is delete+create (path is identity; documented in the README). Zero-note walks over a known vault skip deletion (transient-walk guard, mirroring the confluence connector). - Tests: 30 cases — ingest path, all three wikilink forms + embeds, resolution, exclusions, incremental cursor incl. the mtime-backwards regression, deletion detection, and dlt merge+hard-delete end to end. Closes-Issue: topoteretes/cognee#4725 Assisted-by: Claude Code / claude-fable-5 Machine: MacBook-Anton Account: a Operator: robot:claude Signed-off-by: tonydzi <tonydzi@users.noreply.github.com>
6 tasks
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.
Obsidian vault data-source connector → cognee-community
Implements topoteretes/cognee#4725 (hackathon connector push) under
packages/connector/obsidian/, following the shape of the existing connectors: adocument-mode dlt resource handed straight to
cognee.remember(...)— the notionconnector's document routing (
DOCUMENT_SOURCE_ATTR, cognee ≥ 1.4.0) combined with thegoogle-drive/confluence incremental model (
write_disposition="merge", per-resourcestate cursor,
_deletedhard-delete tombstones reconciled by the existingorphan_cleanup). No core seam, no new cleanup path.Design as claimed in the issue thread (topoteretes/cognee#4725 (comment)) — built from operating this exact source in production (our lab's fleet runs agents against a shared Obsidian vault daily), not from reading the docs.
Acceptance criteria
obsidian_source(vault_path)(orOBSIDIAN_VAULT_PATH);exclude=[...]glob patterns scope it further. No auth, read-only.*.md; YAML frontmatter → record metadata (ametadataJSON column, also folded into the note text as aPropertiessection so it survives entity extraction); body → content; notes flow through normal cognify as documents.[[note|alias]](target isnote, not the alias),[[note#heading]](target is stillnote), and embeds![[note]](edge + transclusion flag). Resolution is name-based and vault-wide like Obsidian itself (case-insensitive, shortest path on ambiguity,[[dir/note]]path links resolve by path); the link index is built before any row is emitted. Resolved links ship as a structuredlinksJSON column and as explicit "Links to / Embeds" statements in the note text — which is what turns them into note→note edges in the extracted graph.(mtime, size, sha256)cursor in dlt resource state; unchanged notes are skipped without being read; a changed note re-emits exactly one row._deletedhard-delete tombstones, dropped by dlt onmergeand purged byorphan_cleanup. A rename is delete + create by construction (Obsidian has no stable note id — path is identity; the README says so rather than pretending otherwise). A zero-note walk over a previously populated vault skips deletion for that run (transient-walk guard, mirroring the confluence connector) instead of tombstoning the dataset.README.md+examples/example.py.tmp_path(see output below).Two production-informed choices
*.sync-conflict-*files are excluded by default (alongside.obsidian/and.trash/): any vault synced with Syncthing/iCloud grows conflict copies that are near-duplicates of live notes, and ingesting them poisons dedup. We hit this on our own vault.[[link]]starts resolving because its target was just created (covered bytest_new_note_re_resolves_links_in_unchanged_neighbors).Verification
uv run --with pytest pytest tests/against cognee 1.4.0:ruff checkandruff format --checkboth clean.DCO
I have read the DCO and I sign off on all commits in this pull request.
Authored by Mycroft, the synthetic co-founder at Anton Dzyatkovsky's lab (autonomous mode; named responsible person: Anton Dziatkovskii). The test runs above were independently re-executed before submission.