script_Überprüfung und Kommentarheader
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 4s
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 4s
This commit is contained in:
parent
23b1cb2966
commit
e9532e8878
|
|
@ -1,18 +1,59 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
tests/assert_payload_schema.py (compat v1.1)
|
FILE: scripts/assert_payload_schema.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Prüft, ob die erwarteten Payload-Indizes (payload_schema) auf den drei Collections vorhanden sind.
|
Zweck:
|
||||||
Kompatibel mit älteren qdrant-client Versionen (ohne with_payload_schema im Wrapper).
|
-------
|
||||||
|
Prüft, ob die erwarteten Payload-Indizes auf allen Collections vorhanden sind.
|
||||||
|
Validiert Schema-Integrität für CI/CD und Wartung.
|
||||||
|
|
||||||
Collections & Pflichtfelder:
|
Funktionsweise:
|
||||||
- mindnet_notes : note_id, type, title, updated, tags
|
---------------
|
||||||
- mindnet_chunks : note_id, chunk_id, index, type, tags
|
1. Ermittelt Collections für das Präfix (notes, chunks, edges)
|
||||||
- mindnet_edges : note_id, kind, scope, source_id, target_id, chunk_id
|
2. Lädt Payload-Schema für jede Collection
|
||||||
|
3. Prüft, ob alle Pflichtfelder indiziert sind:
|
||||||
|
- notes: note_id, type, title, updated, tags
|
||||||
|
- chunks: note_id, chunk_id, index, type, tags
|
||||||
|
- edges: note_id, kind, scope, source_id, target_id, chunk_id
|
||||||
|
4. Gibt Validierungs-Ergebnis aus
|
||||||
|
|
||||||
Nutzung:
|
Ergebnis-Interpretation:
|
||||||
python3 -m tests.assert_payload_schema
|
------------------------
|
||||||
|
- Ausgabe: JSON mit Validierungs-Ergebnissen
|
||||||
|
* collections: Schema-Status pro Collection
|
||||||
|
* missing: Fehlende Indizes
|
||||||
|
* valid: true/false
|
||||||
|
- Exit-Code 0: Alle Indizes vorhanden
|
||||||
|
- Exit-Code 1: Fehlende Indizes gefunden
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- CI/CD-Validierung nach ensure_payload_indexes
|
||||||
|
- Diagnose von Index-Problemen
|
||||||
|
- Wartung und Audit
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Kompatibel mit verschiedenen qdrant-client Versionen
|
||||||
|
- Nutzt Fallback-Strategie für Schema-Abfrage
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.assert_payload_schema --prefix mindnet
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.1.0: Kompatibilität mit verschiedenen qdrant-client Versionen
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,64 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
FILE: scripts/audit_chunks.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Audit-Tool zur Analyse der Chunk-Qualität im Vault.
|
||||||
|
Erkennt Probleme wie überdimensionierte Chunks, leere Chunks und defekte Nachbarschafts-Links.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt alle Markdown-Dateien im Vault
|
||||||
|
2. Für jede Datei:
|
||||||
|
- Erzeugt Chunks via assemble_chunks
|
||||||
|
- Prüft Token-Anzahl pro Chunk
|
||||||
|
- Validiert Nachbarschafts-Links (prev/next)
|
||||||
|
3. Aggregiert Statistiken und identifiziert Probleme
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON mit Zusammenfassung
|
||||||
|
* notes: Anzahl verarbeiteter Notizen
|
||||||
|
* chunks_total: Gesamtanzahl Chunks
|
||||||
|
* chunks_per_note_avg: Durchschnittliche Chunks pro Note
|
||||||
|
* tokens_avg: Durchschnittliche Token pro Chunk
|
||||||
|
* tokens_p95: 95. Perzentil der Token-Verteilung
|
||||||
|
* issues_counts: Anzahl gefundener Probleme
|
||||||
|
- Zusätzlich: Liste der ersten 20 Probleme pro Kategorie
|
||||||
|
* oversize: Chunks > 600 Tokens
|
||||||
|
* broken_neighbors: Defekte prev/next Links
|
||||||
|
* empty: Leere Chunks (0 Tokens)
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Qualitätskontrolle nach Chunking-Änderungen
|
||||||
|
- Identifikation von Problemen vor dem Import
|
||||||
|
- Monitoring der Chunk-Verteilung
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Nutzt synchrones assemble_chunks (kann async sein)
|
||||||
|
- Heuristik für Oversize: > 600 Tokens
|
||||||
|
- Prüft nur strukturelle Integrität, keine semantische Qualität
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.audit_chunks --vault ./vault
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, json, glob, statistics as stats
|
import argparse, os, json, glob, statistics as stats
|
||||||
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,66 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Script: audit_edges_vs_expectations.py — Prüfe Kanten in Qdrant gegen Vault-Erwartungen
|
FILE: scripts/audit_edges_vs_expectations.py
|
||||||
Version: 1.0.0
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
Datum: 2025-09-09
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Zweck
|
Zweck:
|
||||||
-----
|
|
||||||
- Liest Edges/Chunks/Notes aus Qdrant.
|
|
||||||
- Ermittelt erwartete Kanten-Anzahlen aus dem Vault:
|
|
||||||
* belongs_to : sollte == #Chunks
|
|
||||||
* next / prev : je Note (#Chunks_in_Note - 1)
|
|
||||||
* references : Summe aller Chunk-Wikilinks
|
|
||||||
* backlink : Summe einzigartiger Wikilinks pro Note (Note-Level)
|
|
||||||
- Vergleicht IST vs. SOLL und meldet Abweichungen.
|
|
||||||
|
|
||||||
ENV/Qdrant
|
|
||||||
----------
|
|
||||||
QDRANT_URL, QDRANT_API_KEY (optional), COLLECTION_PREFIX (Default: mindnet)
|
|
||||||
|
|
||||||
Aufrufe
|
|
||||||
-------
|
-------
|
||||||
# Gesamtaudit
|
Prüft Edge-Anzahlen in Qdrant gegen erwartete Werte aus dem Vault.
|
||||||
python3 -m scripts.audit_edges_vs_expectations --vault ./test_vault
|
Validiert strukturelle Integrität des Graphen.
|
||||||
|
|
||||||
# Mit anderem Prefix
|
Funktionsweise:
|
||||||
python3 -m scripts.audit_edges_vs_expectations --vault ./test_vault --prefix mindnet_dev
|
---------------
|
||||||
|
1. Liest Edges/Chunks/Notes aus Qdrant
|
||||||
|
2. Ermittelt erwartete Edge-Anzahlen aus Vault:
|
||||||
|
- belongs_to: sollte == #Chunks pro Note
|
||||||
|
- next/prev: je Note (#Chunks - 1)
|
||||||
|
- references: Summe aller Chunk-Wikilinks
|
||||||
|
- backlink: Summe einzigartiger Wikilinks (Note-Level)
|
||||||
|
3. Vergleicht IST vs. SOLL
|
||||||
|
4. Meldet Abweichungen
|
||||||
|
|
||||||
# Details anzeigen
|
Ergebnis-Interpretation:
|
||||||
python3 -m scripts.audit_edges_vs_expectations --vault ./test_vault --details
|
------------------------
|
||||||
|
- Ausgabe: JSON mit Vergleichs-Ergebnissen
|
||||||
|
* expected: Erwartete Edge-Anzahlen
|
||||||
|
* actual: Tatsächliche Edge-Anzahlen
|
||||||
|
* discrepancies: Abweichungen
|
||||||
|
* per_note: Details pro Note (mit --details)
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Validierung nach Importen
|
||||||
|
- Debugging von Edge-Problemen
|
||||||
|
- Qualitätskontrolle
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Prüft strukturelle, nicht semantische Korrektheit
|
||||||
|
- Kann bei großen Vaults langsam sein
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.audit_edges_vs_expectations --vault ./vault
|
||||||
|
python3 -m scripts.audit_edges_vs_expectations --vault ./vault --prefix mindnet_dev --details
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--prefix TEXT Collection-Präfix (Default: mindnet)
|
||||||
|
--details Zeigt Details pro Note
|
||||||
|
|
||||||
|
Umgebungsvariablen:
|
||||||
|
-------------------
|
||||||
|
QDRANT_URL, QDRANT_API_KEY (optional), COLLECTION_PREFIX
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0 (2025-09-09): Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,61 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Name: scripts/audit_vault_vs_qdrant.py
|
FILE: scripts/audit_vault_vs_qdrant.py
|
||||||
Version: v1.0.0 (2025-09-05)
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
Kurzbeschreibung:
|
STATUS: Active
|
||||||
Prüft die Konsistenz zwischen Obsidian-Vault und Qdrant:
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
- Zählt Markdown-Dateien mit gültiger Frontmatter (title, id, type, status, created).
|
|
||||||
- Zählt Wikilink-Vorkommen im Vault (regex wie in derive_edges.py).
|
|
||||||
- Liest Zählungen aus Qdrant (Notes/Chunks/Edges je kind).
|
|
||||||
- Vergleicht erwartete Wikilink-Anzahl (Vault) vs. tatsächlich importierte Edges (Qdrant).
|
|
||||||
- Listet Auffälligkeiten pro Note (z. B. Wikilinks im Vault, aber keine references in Qdrant).
|
|
||||||
|
|
||||||
Aufruf (aus Projekt-Root, im venv):
|
Zweck:
|
||||||
|
-------
|
||||||
|
Prüft Konsistenz zwischen Vault und Qdrant.
|
||||||
|
Vergleicht erwartete vs. tatsächliche Edge-Anzahlen.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt Vault:
|
||||||
|
- Zählt Markdown-Dateien mit gültiger Frontmatter
|
||||||
|
- Zählt Wikilink-Vorkommen (regex wie in derive_edges.py)
|
||||||
|
2. Liest Qdrant:
|
||||||
|
- Zählt Notes/Chunks/Edges
|
||||||
|
- Gruppiert Edges nach kind
|
||||||
|
3. Vergleicht:
|
||||||
|
- Erwartete Wikilink-Anzahl (Vault) vs. references (Qdrant)
|
||||||
|
- Listet Auffälligkeiten pro Note
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON mit Vergleichs-Ergebnissen
|
||||||
|
* vault_stats: Zählungen aus Vault
|
||||||
|
* qdrant_stats: Zählungen aus Qdrant
|
||||||
|
* discrepancies: Abweichungen und Auffälligkeiten
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Konsistenz-Check nach Importen
|
||||||
|
- Validierung der Edge-Erzeugung
|
||||||
|
- Debugging von fehlenden Links
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Wikilink-Regex entspricht derive_edges.py
|
||||||
|
- Prüft strukturelle, nicht semantische Korrektheit
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
python3 -m scripts.audit_vault_vs_qdrant --vault ./vault --prefix mindnet
|
python3 -m scripts.audit_vault_vs_qdrant --vault ./vault --prefix mindnet
|
||||||
|
|
||||||
Parameter:
|
Parameter:
|
||||||
--vault Pfad zum Vault (z. B. ./vault)
|
----------
|
||||||
--prefix Collection-Prefix in Qdrant (Default: mindnet)
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
--limit Max. Punkte pro Scroll-Seite aus Qdrant (Default: 1000)
|
--prefix TEXT Collection-Präfix (Default: mindnet)
|
||||||
|
--limit INT Max. Punkte pro Scroll-Seite (Default: 1000)
|
||||||
|
|
||||||
Voraussetzungen:
|
Änderungen:
|
||||||
- Aktives Python venv mit installiertem qdrant-client.
|
-----------
|
||||||
- Zugriff auf Qdrant per ENV (QDRANT_URL, QDRANT_API_KEY optional).
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0 (2025-09-05): Initial Release
|
||||||
Hinweise:
|
|
||||||
- Der Wikilink-Regex entspricht dem in app/core/derive_edges.py verwendeten Muster. (Quelle: derive_edges.py) # :contentReference[oaicite:3]{index=3}
|
|
||||||
- Pflicht-Frontmatter wird wie in app/core/parser.py geprüft. (Quelle: parser.py) # :contentReference[oaicite:4]{index=4}
|
|
||||||
- Collection-Namen & 1D-Edge-Vektoren folgen app/core/qdrant.py / qdrant_points.py. (Quellen: qdrant.py, qdrant_points.py) #
|
|
||||||
|
|
||||||
Changelog:
|
|
||||||
v1.0.0: Erste Version.
|
|
||||||
|
|
||||||
Autor:
|
|
||||||
mindnet – Datenimporte & Sync
|
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, glob, re, json
|
import argparse, os, glob, re, json
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,61 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
FILE: scripts/backfill_edges.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Füllt fehlende Edges nach, indem es Wikilinks aus dem Vault extrahiert
|
||||||
|
und in Qdrant schreibt. Nützlich nach Migrationen oder wenn Edges verloren gingen.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt alle Markdown-Dateien im Vault
|
||||||
|
2. Für jede Datei:
|
||||||
|
- Erstellt Note-Stub (minimaler Payload)
|
||||||
|
- Erstellt einen Chunk mit dem gesamten Body
|
||||||
|
- Extrahiert Wikilinks via derive_wikilink_edges
|
||||||
|
3. Baut Lookup-Index (Titel/Alias -> note_id)
|
||||||
|
4. Löst Wikilinks auf und erzeugt Edges
|
||||||
|
5. Schreibt Edges in Qdrant
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON mit Statistiken
|
||||||
|
* notes_scanned: Anzahl verarbeiteter Notizen
|
||||||
|
* edges_upserted: Anzahl geschriebener Edges
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Nach Migrationen oder Datenverlust
|
||||||
|
- Wenn Edges fehlen oder unvollständig sind
|
||||||
|
- Zur Reparatur des Graphen
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Überschreibt existierende Edges (kein Merge)
|
||||||
|
- Nutzt vereinfachtes Chunking (1 Chunk = gesamter Body)
|
||||||
|
- Erzeugt nur Wikilink-Edges, keine anderen Edge-Typen
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.backfill_edges --vault ./vault
|
||||||
|
python3 -m scripts.backfill_edges --vault ./vault --exclude /.obsidian/ /_backup/
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--exclude PATH Pfade zum Ausschließen (Default: /.obsidian/, /_backup_frontmatter/)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, glob, json, os
|
import argparse, glob, json, os
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,67 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
FILE: scripts/debug_edge_loss.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active (Debug-Tool)
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Debug-Tool zur Analyse von Edge-Verlust-Problemen bei der Chunk-Verarbeitung.
|
||||||
|
Hilft zu verstehen, warum bestimmte Edges nicht erkannt oder verloren gehen.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Analysiert eine einzelne Markdown-Datei
|
||||||
|
2. Führt zwei Analyseschritte durch:
|
||||||
|
a) Pre-Scan: Extrahiert alle Edge-Kandidaten aus dem rohen Text
|
||||||
|
- Wikilinks
|
||||||
|
- Typed Relations
|
||||||
|
- Callout Relations
|
||||||
|
b) Chunk-Analyse:
|
||||||
|
- Erstellt Chunks mit konfigurierbarem Profil
|
||||||
|
- Prüft, welche Edges in jedem Chunk gefunden werden
|
||||||
|
- Vergleicht mit Pre-Scan-Ergebnissen
|
||||||
|
3. Gibt detaillierte Analyse pro Chunk aus
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- [1] Globale Kandidaten: Alle Edge-Kandidaten, die im Text vorhanden sind
|
||||||
|
- [2] Chunk-Struktur: Für jeden Chunk:
|
||||||
|
* Section-Pfad
|
||||||
|
* Text-Snippet
|
||||||
|
* Gefundene explizite Kanten (callout:edge, inline:rel)
|
||||||
|
* Warnung, falls Callout im Text vorhanden, aber nicht erkannt
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Debugging von Edge-Verlust bei Chunk-Grenzen
|
||||||
|
- Validierung der Edge-Extraktion in verschiedenen Chunk-Kontexten
|
||||||
|
- Analyse von Problemen mit Callout-Erkennung
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Asynchrones Skript (nutzt assemble_chunks async API)
|
||||||
|
- Konfigurierbares Chunking-Profil (Standard: sliding_window, 400/600 chars)
|
||||||
|
- Smart Edge Allocation ist standardmäßig deaktiviert für klare Analyse
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 scripts/debug_edge_loss.py [PFAD_ZUR_DATEI.md]
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
Keine CLI-Parameter. Dateipfad als erstes Argument oder Standard-Pfad.
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Entfernt: _extract_all_edges_from_md (nicht mehr vorhanden)
|
||||||
|
- Ersetzt durch: extract_wikilinks, extract_typed_relations, extract_callout_relations
|
||||||
|
- Chunk-Payload-Struktur angepasst (window, type hinzugefügt)
|
||||||
|
v1.0.0: Erster Release
|
||||||
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -6,8 +70,10 @@ from pathlib import Path
|
||||||
# Pfad-Setup
|
# Pfad-Setup
|
||||||
sys.path.insert(0, os.path.abspath("."))
|
sys.path.insert(0, os.path.abspath("."))
|
||||||
|
|
||||||
from app.core.chunking import assemble_chunks, _extract_all_edges_from_md
|
from app.core.chunking import assemble_chunks
|
||||||
from app.core.derive_edges import build_edges_for_note
|
from app.core.derive_edges import build_edges_for_note
|
||||||
|
from app.core.parser import extract_wikilinks
|
||||||
|
from app.core.graph.graph_extractors import extract_typed_relations, extract_callout_relations
|
||||||
|
|
||||||
# Mock für Settings, falls nötig
|
# Mock für Settings, falls nötig
|
||||||
os.environ["MINDNET_LLM_MODEL"] = "phi3:mini"
|
os.environ["MINDNET_LLM_MODEL"] = "phi3:mini"
|
||||||
|
|
@ -19,9 +85,25 @@ async def analyze_file(file_path: str):
|
||||||
text = f.read()
|
text = f.read()
|
||||||
|
|
||||||
# 1. Globale Kandidaten (Was sieht der Pre-Scan?)
|
# 1. Globale Kandidaten (Was sieht der Pre-Scan?)
|
||||||
# Wir simulieren den Aufruf, den der Chunker macht
|
# Wir extrahieren alle Edge-Kandidaten aus dem Text
|
||||||
note_id = Path(file_path).stem
|
note_id = Path(file_path).stem
|
||||||
candidates = _extract_all_edges_from_md(text, note_id, "concept")
|
candidates = []
|
||||||
|
|
||||||
|
# Wikilinks extrahieren
|
||||||
|
wikilinks = extract_wikilinks(text)
|
||||||
|
for wl in wikilinks:
|
||||||
|
candidates.append(f"wikilink:{wl}")
|
||||||
|
|
||||||
|
# Typed Relations extrahieren
|
||||||
|
typed_rels, _ = extract_typed_relations(text)
|
||||||
|
for kind, target in typed_rels:
|
||||||
|
candidates.append(f"typed:{kind}:{target}")
|
||||||
|
|
||||||
|
# Callout Relations extrahieren
|
||||||
|
callout_rels, _ = extract_callout_relations(text)
|
||||||
|
for kind, target in callout_rels:
|
||||||
|
candidates.append(f"callout:{kind}:{target}")
|
||||||
|
|
||||||
print(f"\n[1] Globale Kandidaten (Pre-Scan):")
|
print(f"\n[1] Globale Kandidaten (Pre-Scan):")
|
||||||
for c in candidates:
|
for c in candidates:
|
||||||
print(f" - {c}")
|
print(f" - {c}")
|
||||||
|
|
@ -45,7 +127,12 @@ async def analyze_file(file_path: str):
|
||||||
|
|
||||||
# Was findet derive_edges in diesem rohen Chunk?
|
# Was findet derive_edges in diesem rohen Chunk?
|
||||||
# Wir simulieren das Payload-Dict, das derive_edges erwartet
|
# Wir simulieren das Payload-Dict, das derive_edges erwartet
|
||||||
chunk_pl = {"text": chunk.text, "window": chunk.window, "chunk_id": chunk.id}
|
chunk_pl = {
|
||||||
|
"text": chunk.text,
|
||||||
|
"window": chunk.window or chunk.text,
|
||||||
|
"chunk_id": chunk.id,
|
||||||
|
"type": "concept"
|
||||||
|
}
|
||||||
edges = build_edges_for_note(note_id, [chunk_pl])
|
edges = build_edges_for_note(note_id, [chunk_pl])
|
||||||
|
|
||||||
found_explicitly = [f"{e['kind']}:{e.get('target_id')}" for e in edges if e['rule_id'] in ['callout:edge', 'inline:rel']]
|
found_explicitly = [f"{e['kind']}:{e.get('target_id')}" for e in edges if e['rule_id'] in ['callout:edge', 'inline:rel']]
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,62 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/debug_note_payload.py
|
FILE: scripts/debug_note_payload.py
|
||||||
Zeigt, welche app.core.note_payload geladen wird, ruft make_note_payload auf
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
und druckt Typ/Preview der Rückgabe.
|
STATUS: Active (Debug-Tool)
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Debug-Tool zur Analyse der Note-Payload-Erzeugung.
|
||||||
|
Zeigt, welches Modul geladen wird und die erzeugte Payload-Struktur.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Lädt Note-Payload-Modul
|
||||||
|
2. Liest Markdown-Datei
|
||||||
|
3. Ruft make_note_payload auf
|
||||||
|
4. Zeigt Modul-Pfad, Rückgabe-Typ und Payload-Inhalt
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: Debug-Informationen
|
||||||
|
* module_path: Pfad zum geladenen Modul
|
||||||
|
* return_type: Typ der Rückgabe
|
||||||
|
* keys: Liste der Payload-Keys (falls Dict)
|
||||||
|
* JSON: Vollständige Payload (falls Dict)
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Debugging von Payload-Erzeugungsproblemen
|
||||||
|
- Validierung der Modul-Ladung
|
||||||
|
- Analyse der Payload-Struktur
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Nutzt app.core.ingestion.ingestion_note_payload (nicht mehr app.core.note_payload)
|
||||||
|
- Zeigt vollständige Payload-Struktur
|
||||||
|
|
||||||
Aufruf:
|
Aufruf:
|
||||||
python3 -m scripts.debug_note_payload --file ./test_vault/40_concepts/concept-alpha.md --vault-root ./test_vault
|
-------
|
||||||
|
python3 -m scripts.debug_note_payload --file ./vault/note.md --vault-root ./vault
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--file PATH Pfad zur Markdown-Datei (erforderlich)
|
||||||
|
--vault-root PATH Vault-Root für relative Pfade (optional)
|
||||||
|
--hash-mode MODE Hash-Modus (optional)
|
||||||
|
--hash-normalize N Hash-Normalisierung (optional)
|
||||||
|
--hash-source SRC Hash-Quelle (optional)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Geändert: app.core.note_payload → app.core.ingestion.ingestion_note_payload
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
import argparse, json, os, pprint
|
import argparse, json, os, pprint
|
||||||
from app.core import note_payload as np
|
from app.core.ingestion import ingestion_note_payload as np
|
||||||
from app.core.parser import read_markdown
|
from app.core.parser import read_markdown
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
@ -24,7 +71,6 @@ def main():
|
||||||
print("module_path:", getattr(np, "__file__", "<unknown>"))
|
print("module_path:", getattr(np, "__file__", "<unknown>"))
|
||||||
parsed = read_markdown(args.file)
|
parsed = read_markdown(args.file)
|
||||||
res = np.make_note_payload(parsed, vault_root=args.vault_root,
|
res = np.make_note_payload(parsed, vault_root=args.vault_root,
|
||||||
hash_mode=args.hash_mode,
|
|
||||||
hash_normalize=args.hash_normalize,
|
hash_normalize=args.hash_normalize,
|
||||||
hash_source=args.hash_source,
|
hash_source=args.hash_source,
|
||||||
file_path=args.file)
|
file_path=args.file)
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,55 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/debug_qdrant_state.py
|
FILE: scripts/debug_qdrant_state.py
|
||||||
Zeigt Prefix, Collections und einfache Counts (notes/chunks/edges) + sample note_ids.
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active (Debug-Tool)
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Zeigt schnelle Übersicht über den Qdrant-Zustand.
|
||||||
|
Gibt Prefix, Collections, Punkt-Anzahlen und Beispiel-IDs aus.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Verbindet mit Qdrant
|
||||||
|
2. Ermittelt Collections für das Präfix
|
||||||
|
3. Zählt Points in jeder Collection
|
||||||
|
4. Extrahiert Beispiel-IDs (erste 5)
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON mit Zustands-Übersicht
|
||||||
|
* prefix: Collection-Präfix
|
||||||
|
* collections: Namen der Collections
|
||||||
|
* counts: Punkt-Anzahlen pro Collection
|
||||||
|
* samples: Beispiel-IDs pro Collection
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Schnelle Status-Prüfung
|
||||||
|
- Debugging von Verbindungsproblemen
|
||||||
|
- Validierung der Collection-Struktur
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Nutzt count() für exakte Zählung (falls verfügbar)
|
||||||
|
- Fallback auf scroll() bei Problemen
|
||||||
|
|
||||||
Aufruf:
|
Aufruf:
|
||||||
export COLLECTION_PREFIX="mindnet"
|
-------
|
||||||
python3 -m scripts.debug_qdrant_state
|
python3 -m scripts.debug_qdrant_state
|
||||||
# oder:
|
python3 -m scripts.debug_qdrant_state --prefix mindnet_dev
|
||||||
python3 -m scripts.debug_qdrant_state --prefix mindnet
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, json
|
import argparse, os, json
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,56 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/diag_payload_indexes.py (compat v1.2)
|
FILE: scripts/diag_payload_indexes.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Zeigt payload_schema je Collection; kompatibel mit älteren qdrant-client Versionen.
|
Zweck:
|
||||||
Strategie (in dieser Reihenfolge):
|
-------
|
||||||
1) openapi_client.collections_api.get_collection(..., with_payload_schema=True)
|
Zeigt das Payload-Schema (Indizes) für alle Collections eines Präfixes.
|
||||||
2) client.get_collection(...)
|
Nützlich zur Diagnose von Index-Problemen oder Validierung der Schema-Struktur.
|
||||||
3) HTTP GET /collections/{name}?with_payload_schema=true
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Ermittelt Collections für das Präfix (notes, chunks, edges)
|
||||||
|
2. Für jede Collection:
|
||||||
|
- Versucht Payload-Schema über verschiedene Methoden zu laden:
|
||||||
|
* qdrant-client API (get_collection)
|
||||||
|
* HTTP GET direkt (Fallback)
|
||||||
|
- Zeigt Schema als JSON
|
||||||
|
3. Gibt Schema-Übersicht aus
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON pro Collection mit payload_schema
|
||||||
|
- Zeigt vorhandene Indizes (keyword, text) und deren Konfiguration
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Diagnose von Index-Problemen
|
||||||
|
- Validierung nach ensure_payload_indexes
|
||||||
|
- Dokumentation der Schema-Struktur
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Kompatibel mit verschiedenen qdrant-client Versionen
|
||||||
|
- Nutzt Fallback-Strategie für maximale Kompatibilität
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.diag_payload_indexes --prefix mindnet
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.2.0: Kompatibilität mit verschiedenen qdrant-client Versionen
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,58 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
FILE: scripts/dump_note_chunks.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Gibt die Chunks einer bestimmten Note in lesbarer Form aus.
|
||||||
|
Nützlich zur Analyse der Chunk-Struktur und -Inhalte.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Sucht Note nach note-id im Vault
|
||||||
|
2. Erzeugt Chunks via assemble_chunks
|
||||||
|
3. Gibt Chunks formatiert aus:
|
||||||
|
- Chunk-ID, Token-Anzahl, Section-Pfad
|
||||||
|
- Vollständiger Chunk-Text
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: Formatierter Text
|
||||||
|
* Header: "# Titel (note-id) — X chunks"
|
||||||
|
* Pro Chunk: "--- chunk_id | tokens | section_path ---"
|
||||||
|
* Gefolgt vom Chunk-Text
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
- Fehlermeldung, wenn Note nicht gefunden
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Analyse der Chunk-Struktur einer spezifischen Note
|
||||||
|
- Debugging von Chunking-Problemen
|
||||||
|
- Validierung der Chunk-Inhalte
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Nutzt synchrones assemble_chunks (kann async sein)
|
||||||
|
- Gibt nur erste gefundene Note aus (bei Duplikaten)
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.dump_note_chunks --vault ./vault --note-id my-note-id
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--note-id ID Note-ID zum Dumpen (erforderlich)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, glob
|
import argparse, os, glob
|
||||||
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,70 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# scripts/edges_dryrun.py
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Dry-Run: Erzeuge Edges aus einem Vault **ohne** Qdrant-Upsert.
|
FILE: scripts/edges_dryrun.py
|
||||||
- Liest Markdown mit YAML-Frontmatter
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
- Chunking: einfacher Absatz-Chunker (Index + text)
|
STATUS: Active
|
||||||
- Kanten: nutzt app.core.edges.build_edges_for_note()
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
- Ausgabe: JSON pro Note mit Edge-Counts und 3 Beispiel-Payloads
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Simuliert die Edge-Erzeugung aus Markdown-Dateien ohne Datenbank-Upsert.
|
||||||
|
Nützlich zur Analyse, welche Kanten aus einem Vault generiert würden.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt alle .md-Dateien im Vault
|
||||||
|
2. Für jede Datei:
|
||||||
|
- Parst Markdown mit Frontmatter
|
||||||
|
- Erstellt einfache Absatz-basierte Chunks (vereinfachtes Chunking)
|
||||||
|
- Extrahiert Edge-Kandidaten via build_edges_for_note():
|
||||||
|
* Wikilinks [[...]]
|
||||||
|
* Typed Relations [[rel:KIND|Target]]
|
||||||
|
* Callout Relations [!edge] KIND: [[Target]]
|
||||||
|
* Struktur-Kanten (belongs_to, next, prev)
|
||||||
|
- Zählt Edges nach Typ (kind/relation)
|
||||||
|
3. Gibt JSON-Report aus mit Edge-Statistiken pro Note
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON-Array mit einem Objekt pro Note
|
||||||
|
- Jedes Objekt enthält:
|
||||||
|
* path: Dateipfad
|
||||||
|
* note_id: Note-Identifier
|
||||||
|
* type: Note-Typ
|
||||||
|
* chunks: Anzahl der Chunks
|
||||||
|
* edges_total: Gesamtanzahl der Edges
|
||||||
|
* edges_by_kind: Dictionary mit Edge-Anzahl pro Typ
|
||||||
|
* samples: Erste 3 Edges als Beispiele
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Analyse der Graph-Struktur vor dem Import
|
||||||
|
- Debugging von fehlenden oder unerwarteten Edges
|
||||||
|
- Validierung der Edge-Extraktion-Logik
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Verwendet vereinfachtes Chunking (Absatz-basiert), nicht das vollständige Chunking-System
|
||||||
|
- Edge-Extraktion entspricht der Produktions-Logik (app.core.derive_edges)
|
||||||
|
- Keine Datenbank-Operationen, rein analytisch
|
||||||
|
|
||||||
Aufruf:
|
Aufruf:
|
||||||
|
-------
|
||||||
python3 -m scripts.edges_dryrun --vault ./vault
|
python3 -m scripts.edges_dryrun --vault ./vault
|
||||||
|
python3 -m scripts.edges_dryrun --vault ./vault --include-note-scope-refs
|
||||||
|
|
||||||
Optional:
|
Parameter:
|
||||||
--include-note-scope-refs # auch Frontmatter-Links (links[].target_id) als Note-Scope-Referenzen
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--include-note-scope-refs Berücksichtigt auch Frontmatter-Links (links[].target_id)
|
||||||
|
|
||||||
Voraussetzungen:
|
Änderungen:
|
||||||
- app/core/parser.py (read_markdown, normalize_frontmatter)
|
-----------
|
||||||
- app/core/edges.py (dieses Modul forwardet zur v2-Implementierung)
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Geändert: app.core.edges → app.core.derive_edges
|
||||||
|
- Parameter korrigiert: chunk_payloads → chunks, note_level_refs → note_level_references
|
||||||
|
v1.0.0: Erster Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
@ -28,7 +76,7 @@ from pathlib import Path
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
from app.core.parser import read_markdown, normalize_frontmatter
|
from app.core.parser import read_markdown, normalize_frontmatter
|
||||||
from app.core.edges import build_edges_for_note
|
from app.core.derive_edges import build_edges_for_note
|
||||||
|
|
||||||
def _iter_markdown(vault: str):
|
def _iter_markdown(vault: str):
|
||||||
for p in Path(vault).rglob("*.md"):
|
for p in Path(vault).rglob("*.md"):
|
||||||
|
|
@ -83,8 +131,8 @@ def main():
|
||||||
|
|
||||||
edges = build_edges_for_note(
|
edges = build_edges_for_note(
|
||||||
note_id=note_id,
|
note_id=note_id,
|
||||||
chunk_payloads=chunks,
|
chunks=chunks,
|
||||||
note_level_refs=note_refs,
|
note_level_references=note_refs,
|
||||||
include_note_scope_refs=include_note_scope,
|
include_note_scope_refs=include_note_scope,
|
||||||
)
|
)
|
||||||
kinds = {}
|
kinds = {}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,64 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/edges_full_check.py
|
FILE: scripts/edges_full_check.py
|
||||||
Zählt und validiert Kanten in Qdrant. Erkennt folgende Rule-Gruppen:
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
- explicit_total: rule_id startswith "explicit:" (z.B. explicit:wikilink, explicit:note_scope)
|
STATUS: Active
|
||||||
- callout_total: rule_id == "callout:edge"
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
- inline_total: rule_id startswith "inline:" (z.B. inline:rel)
|
|
||||||
- defaults_total: rule_id startswith "edge_defaults:"
|
|
||||||
- structure: rule_id in {"structure:belongs_to","structure:order"}
|
|
||||||
|
|
||||||
Gibt zusätzlich:
|
Zweck:
|
||||||
- edges_by_kind (aggregiert)
|
-------
|
||||||
- notes/chunks/edges Anzahlen
|
Umfassende Validierung der Edge-Struktur in Qdrant.
|
||||||
- multi_callout_detected: True, falls ein Chunk mehrere Callout-Ziele der gleichen Relation enthält
|
Analysiert Edge-Typen, Rule-Gruppen und strukturelle Integrität.
|
||||||
- per_note_checks: belongs_to == chunks, next == prev == (chunks-1)
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Lädt alle Edges aus {prefix}_edges
|
||||||
|
2. Gruppiert Edges nach rule_id:
|
||||||
|
- explicit: rule_id startswith "explicit:" (wikilink, note_scope)
|
||||||
|
- callout: rule_id == "callout:edge"
|
||||||
|
- inline: rule_id startswith "inline:" (rel)
|
||||||
|
- defaults: rule_id startswith "edge_defaults:"
|
||||||
|
- structure: rule_id in {"structure:belongs_to", "structure:order"}
|
||||||
|
3. Prüft strukturelle Integrität:
|
||||||
|
- belongs_to == chunks pro Note
|
||||||
|
- next == prev == (chunks-1) pro Note
|
||||||
|
- Multi-Callout-Erkennung
|
||||||
|
4. Aggregiert Statistiken
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON mit umfassender Analyse
|
||||||
|
* counts: notes/chunks/edges Anzahlen
|
||||||
|
* edges_by_kind: Aggregierte Edge-Anzahl pro Typ
|
||||||
|
* rule_groups: Zählung nach Rule-Gruppen
|
||||||
|
* per_note_checks: Strukturelle Validierung pro Note
|
||||||
|
* multi_callout_detected: Boolean
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Umfassende Graph-Analyse
|
||||||
|
- Validierung nach größeren Änderungen
|
||||||
|
- Debugging von Edge-Problemen
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Kann bei großen Graphen langsam sein
|
||||||
|
- Prüft strukturelle, nicht semantische Korrektheit
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.edges_full_check --prefix mindnet
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,74 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Script: scripts/export_markdown.py — Qdrant → Markdown (Vault)
|
FILE: scripts/export_markdown.py
|
||||||
Version: 1.4.1
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
Datum: 2025-09-10
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Funktion
|
Zweck:
|
||||||
--------
|
-------
|
||||||
Exportiert Notes (Frontmatter + Body) aus Qdrant in einen Zielordner. Der Body wird
|
Exportiert Notes (Frontmatter + Body) aus Qdrant zurück in Markdown-Dateien.
|
||||||
bevorzugt aus dem Feld `fulltext` rekonstruiert; falls leer/nicht vorhanden, aus Chunks
|
Nützlich für Backup, Migration oder Notfall-Wiederherstellung.
|
||||||
(Sortierung: seq → chunk_index → Nummer in chunk_id). Pfade werden **relativ** geschrieben.
|
|
||||||
|
|
||||||
Optionen
|
Funktionsweise:
|
||||||
--------
|
---------------
|
||||||
--out PATH Zielordner (erforderlich)
|
1. Liest alle Notes aus Qdrant (Collection: {prefix}_notes)
|
||||||
--prefix TEXT Collection-Prefix (CLI überschreibt ENV COLLECTION_PREFIX)
|
2. Für jede Note:
|
||||||
--note-id ID Nur eine Note exportieren
|
- Rekonstruiert Frontmatter aus Payload-Feldern
|
||||||
--overwrite Existierende Dateien überschreiben
|
- Rekonstruiert Body:
|
||||||
|
* Primär: aus `fulltext` Feld (falls vorhanden)
|
||||||
|
* Fallback: aus Chunks (sortiert nach seq → chunk_index → chunk_id)
|
||||||
|
- Optional: Fügt Edges als Links hinzu (yaml/footer)
|
||||||
|
3. Schreibt Markdown-Dateien mit relativen Pfaden
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON pro Datei mit note_id, path, decision (write/skip-exists)
|
||||||
|
- Abschluss: "Done. Exported notes: X"
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Backup vor größeren Änderungen
|
||||||
|
- Migration zwischen Instanzen
|
||||||
|
- Notfall-Wiederherstellung bei Vault-Verlust
|
||||||
|
- Analyse der in Qdrant gespeicherten Daten
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Pfade werden relativ geschrieben (wie im Original-Vault)
|
||||||
|
- --flatten-paths: Alle Dateien in einen Ordner (orig_path in Frontmatter)
|
||||||
|
- Body-Rekonstruktion aus Chunks kann bei sehr langen Dokumenten unvollständig sein
|
||||||
|
- Edge-Export optional (none/yaml/footer)
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.export_markdown --out ./_exportVault
|
||||||
|
python3 -m scripts.export_markdown --out ./_exportVault --note-id concept-alpha --include-edges yaml
|
||||||
|
python3 -m scripts.export_markdown --out ./_exportVault --flatten-paths --overwrite
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--out PATH Zielordner für exportierte Markdown-Dateien (erforderlich)
|
||||||
|
--prefix TEXT Collection-Präfix (überschreibt ENV COLLECTION_PREFIX)
|
||||||
|
--note-id ID Nur eine bestimmte Note-ID exportieren (optional)
|
||||||
|
--overwrite Existierende Dateien überschreiben (sonst skip)
|
||||||
--include-edges MODE none|yaml|footer (Default: none)
|
--include-edges MODE none|yaml|footer (Default: none)
|
||||||
--flatten-paths Alle Dateien flach schreiben; Originalpfad in FM: orig_path
|
- none: Keine Edges
|
||||||
|
- yaml: Als YAML-Feld 'references' im Frontmatter
|
||||||
|
- footer: Als Markdown-Links am Ende
|
||||||
|
--flatten-paths Alle Dateien flach schreiben (orig_path in Frontmatter)
|
||||||
|
|
||||||
ENV
|
Umgebungsvariablen:
|
||||||
---
|
-------------------
|
||||||
COLLECTION_PREFIX, QDRANT_URL | QDRANT_HOST/QDRANT_PORT | QDRANT_API_KEY
|
COLLECTION_PREFIX, QDRANT_URL | QDRANT_HOST/QDRANT_PORT | QDRANT_API_KEY
|
||||||
|
|
||||||
Beispiele
|
Änderungen:
|
||||||
---------
|
-----------
|
||||||
export COLLECTION_PREFIX="mindnet"
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
python3 -m scripts.export_markdown --out ./_exportVault
|
- Aktualisiert: Import-Pfade für neue Struktur
|
||||||
|
v1.4.1 (2025-09-10): Initial Release
|
||||||
# Nur eine Note, Edges als YAML-Feld 'references'
|
|
||||||
python3 -m scripts.export_markdown --out ./_exportVault --note-id concept-alpha --include-edges yaml
|
|
||||||
|
|
||||||
# Flach schreiben mit Überschreiben
|
|
||||||
python3 -m scripts.export_markdown --out ./_exportVault --flatten-paths --overwrite
|
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,68 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
FILE: scripts/fix_frontmatter.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Repariert oder ergänzt fehlende Frontmatter-Felder in Markdown-Dateien.
|
||||||
|
Erzeugt stabile IDs, erkennt Typen und erstellt vollständige Frontmatter-Struktur.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt alle Markdown-Dateien im Vault
|
||||||
|
2. Für jede Datei:
|
||||||
|
- Liest vorhandenes Frontmatter
|
||||||
|
- Erkennt fehlende Felder (id, title, type, created)
|
||||||
|
- Generiert fehlende Werte:
|
||||||
|
* id: Stabile ID aus Pfad, Titel und Datum
|
||||||
|
* title: Aus H1, Dateiname oder "Untitled"
|
||||||
|
* type: Aus Pfad/Tags (journal, task, project, etc.)
|
||||||
|
* created: Aus Dateiname oder mtime
|
||||||
|
- Validiert Payload (optional)
|
||||||
|
- Schreibt korrigiertes Frontmatter zurück
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON pro Datei mit Änderungen
|
||||||
|
* path: Dateipfad
|
||||||
|
* changes: Dict mit alten/neuen Werten
|
||||||
|
* backup_path: Pfad zur Backup-Datei (falls --backup)
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Migration von Legacy-Vaults ohne Frontmatter
|
||||||
|
- Reparatur beschädigter Frontmatter
|
||||||
|
- Standardisierung von Frontmatter-Strukturen
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Erstellt Backups vor Änderungen (mit --backup)
|
||||||
|
- Idempotent: Überspringt bereits vollständige Frontmatter
|
||||||
|
- Nutzt Heuristiken für Typ-Erkennung (Pfad/Tags)
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.fix_frontmatter --vault ./vault --apply
|
||||||
|
python3 -m scripts.fix_frontmatter --vault ./vault --backup --apply
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--backup Erstellt Backup-Dateien vor Änderungen
|
||||||
|
--apply Führt tatsächliche Änderungen durch (sonst Dry-Run)
|
||||||
|
--validate Validiert Note-Payload nach Fix
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
- Hinweis: validate_note_payload existiert nicht mehr (wird entfernt)
|
||||||
|
v1.0.0: Initial Release
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, re, sys, json, shutil, time, hashlib
|
import argparse, os, re, sys, json, shutil, time, hashlib
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
@ -6,7 +70,7 @@ from typing import Dict, Tuple, Optional, List
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from app.core.parser import read_markdown, normalize_frontmatter
|
from app.core.parser import read_markdown, normalize_frontmatter
|
||||||
from app.core.parser import FRONTMATTER_RE # für Re-Inject
|
from app.core.parser import FRONTMATTER_RE # für Re-Inject
|
||||||
from app.core.validate_note import validate_note_payload
|
# NOTE: validate_note_payload existiert nicht mehr - entfernt
|
||||||
from app.core.ingestion.ingestion_note_payload import make_note_payload
|
from app.core.ingestion.ingestion_note_payload import make_note_payload
|
||||||
|
|
||||||
DATE_IN_NAME = re.compile(r"(?P<y>\d{4})[-_\.]?(?P<m>\d{2})[-_\.]?(?P<d>\d{2})")
|
DATE_IN_NAME = re.compile(r"(?P<y>\d{4})[-_\.]?(?P<m>\d{2})[-_\.]?(?P<d>\d{2})")
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,73 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# scripts/gc_qdrant_after_vault_scan.py
|
# -*- coding: utf-8 -*-
|
||||||
# Version: 1.0.0 (2025-09-05)
|
"""
|
||||||
#
|
FILE: scripts/gc_qdrant_after_vault_scan.py
|
||||||
# Zweck
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
# -----
|
STATUS: Active
|
||||||
# Garbage-Collector für Qdrant: löscht Einträge (Edges, Chunks, Notes), deren Note-ID
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
# nicht mehr im Obsidian-Vault vorhanden ist. So bleiben Vektorindex/Graph mit dem Vault konsistent.
|
|
||||||
#
|
Zweck:
|
||||||
# Aufrufparameter
|
-------
|
||||||
# ---------------
|
Garbage-Collector für Qdrant: löscht Einträge, deren Note-ID nicht mehr
|
||||||
# --vault PATH Pfad zum Obsidian-Vault (z. B. ./vault) [erforderlich]
|
im Vault vorhanden ist. Hält Vektorindex/Graph mit dem Vault konsistent.
|
||||||
# --mode {edges,content,all}
|
|
||||||
# edges -> nur Kanten mit source_id/target_id ∉ Vault-Notes löschen
|
Funktionsweise:
|
||||||
# content -> Chunks & Notes löschen, deren note_id ∉ Vault-Notes (keine Edges)
|
---------------
|
||||||
# all -> zuerst edges, dann content
|
1. Scannt Vault und sammelt alle note_ids
|
||||||
# --prefix PREFIX Collection-Präfix (Default: aus ENV COLLECTION_PREFIX oder "mindnet")
|
2. Lädt note_ids aus Qdrant
|
||||||
# --apply Ohne diesen Schalter: Dry-Run (nur Vorschau). Mit Schalter: ausführen.
|
3. Berechnet Differenz (verwaiste IDs)
|
||||||
# --yes Sicherheitsabfrage überspringen (non-interaktiv)
|
4. Löscht verwaiste Einträge:
|
||||||
# --batch-size N Größe für In-Filter (Default: 1000)
|
- mode=edges: Nur Edges mit source_id/target_id ∉ Vault
|
||||||
#
|
- mode=content: Chunks & Notes mit note_id ∉ Vault
|
||||||
# Hinweise
|
- mode=all: Zuerst edges, dann content
|
||||||
# --------
|
5. Nutzt Batch-Filter für effiziente Löschung
|
||||||
# - Benötigt funktionierendes Python-venv mit allen Abhängigkeiten von mindnet (qdrant-client usw.).
|
|
||||||
# - Läuft gegen die drei Collections {prefix}_notes, {prefix}_chunks, {prefix}_edges (keine anderen Projekte).
|
Ergebnis-Interpretation:
|
||||||
# - Nutzt OR-Filter (Filter.should) korrekt, keine minimum_should (Pydantic v2 lässt die Option nicht zu).
|
------------------------
|
||||||
#
|
- Ausgabe: JSON mit Preview und Statistiken
|
||||||
# Änderungen ggü. vorher
|
* mode: DRY-RUN oder APPLY
|
||||||
# ----------------------
|
* vault_note_ids: Anzahl Notizen im Vault
|
||||||
# - Neu: eigenes GC-Tool; berührt ausschließlich das übergebene Projekt-Präfix.
|
* qdrant_note_ids: Anzahl Notizen in Qdrant
|
||||||
# - Sichere Dry-Run-Vorschau mit Zählung pro Collection; interaktive Bestätigung.
|
* orphans: Anzahl verwaister Notizen
|
||||||
# - Löscht Edges mittels Filter auf (source_id ∈ MISSING) ODER (target_id ∈ MISSING).
|
* deleted: Anzahl gelöschter Einträge (nach --apply)
|
||||||
# - Löscht Chunks/Notes mittels Filter auf note_id ∈ MISSING.
|
- Exit-Code 0: Erfolgreich
|
||||||
#
|
|
||||||
# Beispiele
|
Verwendung:
|
||||||
# ---------
|
-----------
|
||||||
# DRY RUN: python3 -m scripts.gc_qdrant_after_vault_scan --vault ./vault --mode all
|
- Regelmäßige Wartung nach Vault-Bereinigung
|
||||||
# APPLY: python3 -m scripts.gc_qdrant_after_vault_scan --vault ./vault --mode all --apply
|
- Konsistenz-Check zwischen Vault und Datenbank
|
||||||
# CI-Modus: python3 -m scripts.gc_qdrant_after_vault_scan --vault ./vault --mode edges --apply --yes
|
- Vor Migrationen
|
||||||
#
|
|
||||||
# Kompatibilität / Kontext
|
Sicherheitsmerkmale:
|
||||||
# ------------------------
|
-------------------
|
||||||
# - Frontmatter-Validierung & Parsing wie im Projekt (parser.read_markdown, validate_required_frontmatter). :contentReference[oaicite:0]{index=0}
|
- Dry-Run standardmäßig (keine Änderungen ohne --apply)
|
||||||
# - Note-Payload-Schema (u. a. note_id, hash_fulltext) wie spezifiziert. :contentReference[oaicite:1]{index=1}
|
- Interaktive Bestätigung (außer mit --yes)
|
||||||
# - Collection-Namen & Anlage-Logik über app.core.qdrant (notes/chunks = dim, edges = 1D). :contentReference[oaicite:2]{index=2}
|
- Nur betroffene Collections werden geändert
|
||||||
# - Edges nutzen Felder source_id/target_id; Chunks/Notes tragen note_id in payload. :contentReference[oaicite:3]{index=3} :contentReference[oaicite:4]{index=4}
|
|
||||||
#
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.gc_qdrant_after_vault_scan --vault ./vault --mode all
|
||||||
|
python3 -m scripts.gc_qdrant_after_vault_scan --vault ./vault --mode all --apply
|
||||||
|
python3 -m scripts.gc_qdrant_after_vault_scan --vault ./vault --mode edges --apply --yes
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--mode MODE edges | content | all (Default: all)
|
||||||
|
- edges: Nur Edges löschen
|
||||||
|
- content: Nur Chunks & Notes löschen
|
||||||
|
- all: Beides (zuerst edges, dann content)
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
--apply Führt tatsächliches Löschen durch (sonst Dry-Run)
|
||||||
|
--yes Keine interaktive Bestätigung
|
||||||
|
--batch-size N Batch-Größe für Filter (Default: 1000)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Aktualisiert: Import-Pfade für neue Struktur
|
||||||
|
v1.0.0 (2025-09-05): Initial Release
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, glob, json, sys
|
import argparse, os, glob, json, sys
|
||||||
from typing import Iterable, Set, Tuple, List
|
from typing import Iterable, Set, Tuple, List
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,70 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/health_check_mindnet.py
|
FILE: scripts/health_check_mindnet.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Health-Check für den mindnet-Retriever-/Query-Endpoint.
|
Zweck:
|
||||||
|
-------
|
||||||
|
Health-Check für den mindnet /query-Retriever-Endpoint.
|
||||||
|
Prüft Verfügbarkeit, Antwortzeit und Ergebnisqualität.
|
||||||
|
|
||||||
Funktion:
|
Funktionsweise:
|
||||||
- Führt POST-Requests auf /query in verschiedenen Modi aus (standard: semantic + hybrid).
|
---------------
|
||||||
- Prüft Status-Code, JSON-Struktur und Anzahl der Treffer.
|
1. Führt POST-Requests auf /query in verschiedenen Modi aus
|
||||||
- Kennzeichnet Probleme als:
|
2. Prüft für jeden Modus:
|
||||||
- status="ok"
|
- HTTP-Status-Code (erwartet 200)
|
||||||
- status="warning" (z.B. Timeout)
|
- JSON-Struktur (erwartet Objekt mit results-Array)
|
||||||
- status="error" (harte Fehler wie HTTP-Fehler, JSON-Fehler etc.)
|
- Anzahl der Treffer (mindestens min-results)
|
||||||
|
- Antwortzeit (Latency)
|
||||||
|
3. Klassifiziert Ergebnisse:
|
||||||
|
- ok: Alles in Ordnung
|
||||||
|
- warning: Timeout oder unerwartetes Verhalten
|
||||||
|
- error: HTTP-Fehler, JSON-Fehler, zu wenige Ergebnisse
|
||||||
|
|
||||||
Exit-Code:
|
Ergebnis-Interpretation:
|
||||||
- Default (tolerant):
|
------------------------
|
||||||
- overall_status = "ok" (inkl. warnings) → Exit-Code 0
|
- Ausgabe: Menschlich lesbare Zusammenfassung + JSON-Report
|
||||||
- overall_status = "error" → Exit-Code 1
|
- overall_status: ok | warning | error
|
||||||
- Mit --strict:
|
- Exit-Code 0: ok (tolerant) oder ok/warning (strict)
|
||||||
- warnings werden wie errors behandelt → Exit-Code 1
|
- Exit-Code 1: error (tolerant) oder warning/error (strict)
|
||||||
|
|
||||||
Beispiele:
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Monitoring und Alerting (z.B. cronjob)
|
||||||
|
- CI/CD-Pipelines (Validierung nach Deployment)
|
||||||
|
- Debugging von Performance-Problemen
|
||||||
|
- Integration in externe Monitoring-Tools (n8n, etc.)
|
||||||
|
|
||||||
python scripts/health_check_mindnet.py \
|
Hinweise:
|
||||||
--url http://127.0.0.1:8001/query \
|
---------
|
||||||
--query "embeddings" \
|
- Standard: Prüft semantic und hybrid Modi
|
||||||
--top-k 3
|
- Tolerant: Warnings führen nicht zu Exit-Code 1
|
||||||
|
- Strict: Warnings werden wie Errors behandelt
|
||||||
|
- JSON-Ausgabe für maschinelle Weiterverarbeitung
|
||||||
|
|
||||||
python scripts/health_check_mindnet.py \
|
Aufruf:
|
||||||
--url http://127.0.0.1:8001/query \
|
-------
|
||||||
--query "embeddings" \
|
python3 scripts/health_check_mindnet.py --url http://127.0.0.1:8001/query
|
||||||
--top-k 3 \
|
python3 scripts/health_check_mindnet.py --query "test" --top-k 5 --modes semantic hybrid
|
||||||
--timeout 15 \
|
python3 scripts/health_check_mindnet.py --strict
|
||||||
--modes hybrid
|
|
||||||
|
|
||||||
# Strenger Modus (warnings → Exit-Code 1)
|
Parameter:
|
||||||
python scripts/health_check_mindnet.py --strict
|
----------
|
||||||
|
--url URL Vollständige URL des /query-Endpunkts (Default: http://127.0.0.1:8001/query)
|
||||||
|
--query TEXT Test-Query (Default: embeddings)
|
||||||
|
--top-k INT Anzahl der erwarteten Ergebnisse (Default: 3)
|
||||||
|
--timeout FLOAT Timeout in Sekunden pro Request (Default: 5.0)
|
||||||
|
--modes LIST Zu prüfende Modi (Default: semantic hybrid)
|
||||||
|
--min-results INT Minimale Anzahl erwarteter Ergebnisse (Default: 1)
|
||||||
|
--strict Warnings als Fehler behandeln (Exit-Code 1 bei warnings)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,69 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/import_markdown.py
|
FILE: scripts/import_markdown.py
|
||||||
CLI-Tool zum Importieren von Markdown-Dateien in Qdrant.
|
VERSION: 2.4.1 (2025-12-15)
|
||||||
WP-15b: Implementiert den Two-Pass Workflow (Pre-Scan + Processing).
|
STATUS: Active (Core)
|
||||||
Sorgt dafür, dass der LocalBatchCache vor der Verarbeitung robust gefüllt wird.
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
Indiziert Notizen nach ID, Titel und Dateiname für maximale Link-Kompatibilität.
|
|
||||||
VERSION: 2.4.1
|
Zweck:
|
||||||
|
-------
|
||||||
|
Hauptwerkzeug zum Importieren von Markdown-Dateien aus einem Vault in Qdrant.
|
||||||
|
Implementiert den Two-Pass Workflow (WP-15b) für robuste Edge-Validierung.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. PASS 1: Global Pre-Scan
|
||||||
|
- Scannt alle Markdown-Dateien im Vault
|
||||||
|
- Extrahiert Note-Kontext (ID, Titel, Dateiname)
|
||||||
|
- Füllt LocalBatchCache für semantische Edge-Validierung
|
||||||
|
- Indiziert nach ID, Titel und Dateiname für Link-Auflösung
|
||||||
|
|
||||||
|
2. PASS 2: Semantic Processing
|
||||||
|
- Verarbeitet Dateien in Batches (20 Dateien, max. 5 parallel)
|
||||||
|
- Nutzt gefüllten Cache für binäre Edge-Validierung
|
||||||
|
- Erzeugt Notes, Chunks und Edges in Qdrant
|
||||||
|
- Respektiert Hash-basierte Change Detection
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Log-Ausgabe: Fortschritt und Statistiken
|
||||||
|
- Stats: processed, skipped, errors
|
||||||
|
- Exit-Code 0: Erfolgreich (auch wenn einzelne Dateien Fehler haben)
|
||||||
|
- Ohne --apply: Dry-Run (keine DB-Änderungen)
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Regelmäßiger Import nach Vault-Änderungen
|
||||||
|
- Initial-Import eines neuen Vaults
|
||||||
|
- Re-Indexierung mit --force
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Two-Pass Workflow sorgt für robuste Edge-Validierung
|
||||||
|
- Change Detection verhindert unnötige Re-Indexierung
|
||||||
|
- Parallele Verarbeitung für Performance (max. 5 gleichzeitig)
|
||||||
|
- Cloud-Resilienz durch Semaphore-Limits
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.import_markdown --vault ./vault --apply
|
||||||
|
python3 -m scripts.import_markdown --vault ./vault --prefix mindnet_dev --force --apply
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (Default: ./vault)
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
--force Erzwingt Re-Indexierung aller Dateien (ignoriert Hashes)
|
||||||
|
--apply Führt tatsächliche DB-Schreibvorgänge durch (sonst Dry-Run)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.4.1 (2025-12-15): WP-15b Two-Pass Workflow
|
||||||
|
- Implementiert Pre-Scan für LocalBatchCache
|
||||||
|
- Indizierung nach ID, Titel und Dateiname
|
||||||
|
- Batch-Verarbeitung mit Semaphore-Limits
|
||||||
|
v2.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,60 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
make_test_vault.py — erzeugt einen minimalen, nachvollziehbaren Test-Vault
|
FILE: scripts/make_test_vault.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active (Test-Tool)
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Version: 1.2 (2025-09-09)
|
Zweck:
|
||||||
Änderungen ggü. 1.1:
|
-------
|
||||||
- Fügt **externe Links** (http/mailto) in `exp-two.md` hinzu, damit der Chunk-Payload-Exporter
|
Erzeugt einen minimalen, nachvollziehbaren Test-Vault für Entwicklung und Tests.
|
||||||
`external_links` realistisch testen kann.
|
Enthält verschiedene Szenarien: leere Links, externe Links, verschiedene Note-Typen.
|
||||||
- Kleine Textanpassungen zur stabilen Chunk-Bildung (Absatzstruktur).
|
|
||||||
|
|
||||||
Zweck
|
Funktionsweise:
|
||||||
- Kleiner Obsidian-ähnlicher Vault zum Durchspielen des Importers (Chunks/Edges).
|
---------------
|
||||||
- Szenarien: leere Links, spätere Anlage fehlender Noten, Chunk-Neuaufteilung, externe Links.
|
1. Erstellt Verzeichnisstruktur (concepts, experiences, projects)
|
||||||
|
2. Generiert Test-Notizen mit vollständigem Frontmatter:
|
||||||
|
- concept-alpha.md (Basis-Concept)
|
||||||
|
- exp-one.md (verlinkt auf concept-alpha und missing-note)
|
||||||
|
- exp-two.md (verlinkt auf concept-alpha + externe Links)
|
||||||
|
- project-demo.md (verlinkt auf concept-alpha und exp-one)
|
||||||
|
3. Optional: Erstellt missing-note (mit --with-missing)
|
||||||
|
|
||||||
Struktur (Default: ./test_vault)
|
Ergebnis-Interpretation:
|
||||||
- 40_concepts/concept-alpha.md
|
------------------------
|
||||||
- 20_experiences/exp-one.md (verlinkt auf [[concept-alpha]] und [[missing-note]])
|
- Ausgabe: Erfolgsmeldung mit erstellten Dateien
|
||||||
- 20_experiences/exp-two.md (verlinkt auf [[concept-alpha]] + externe Links)
|
- Exit-Code 0: Erfolgreich
|
||||||
- 30_projects/project-demo.md (verlinkt auf [[concept-alpha]] und [[exp-one]])
|
- Exit-Code 1: Fehler (z.B. Verzeichnis existiert bereits ohne --force)
|
||||||
|
|
||||||
Voraussetzungen
|
Verwendung:
|
||||||
- Keine. Rein Dateigenerierung.
|
-----------
|
||||||
|
- Entwicklung und Testing
|
||||||
|
- Demo und Dokumentation
|
||||||
|
- CI/CD-Tests
|
||||||
|
|
||||||
Aufruf
|
Hinweise:
|
||||||
python3 -m scripts.make_test_vault [--out ./test_vault] [--force] [--with-missing]
|
---------
|
||||||
|
- Erstellt realistische Test-Daten mit verschiedenen Edge-Szenarien
|
||||||
|
- Enthält "Red Links" (missing-note) für Link-Auflösungs-Tests
|
||||||
|
- Externe Links für Chunk-Payload-Tests
|
||||||
|
|
||||||
Parameter
|
Aufruf:
|
||||||
--out Zielverzeichnis (Standard: ./test_vault)
|
-------
|
||||||
--force Bestehenden Ordner löschen und neu anlegen.
|
python3 -m scripts.make_test_vault --out ./test_vault
|
||||||
--with-missing Auch die 'missing-note' direkt anlegen (Standard: erst im 2. Lauf)
|
python3 -m scripts.make_test_vault --out ./test_vault --force --with-missing
|
||||||
|
|
||||||
Hinweise für Tests
|
Parameter:
|
||||||
1) Erster Import (dry-run oder --apply): Es gibt einen „leeren“ Link [[missing-note]].
|
----------
|
||||||
2) Lege danach eine Datei für „missing-note“ an (mit gleicher ID im YAML) und importiere erneut:
|
--out PATH Zielverzeichnis (Default: ./test_vault)
|
||||||
-> Erwartung: Edges für ehemals leeren Link werden korrekt nachgezogen (references + backlink).
|
--force Löscht bestehenden Ordner und legt neu an
|
||||||
3) Ändere den Body von exp-one.md so, dass andere Chunk-Grenzen entstehen und importiere erneut:
|
--with-missing Erstellt auch missing-note direkt (Standard: erst im 2. Lauf)
|
||||||
-> Erwartung: Chunks/Edges/Note werden für betroffene Noten aktualisiert.
|
|
||||||
4) Prüfe externe Links (verify_chunk_texts.py betrifft nur Text; externe Links siehst du in chunk_payloads).
|
|
||||||
|
|
||||||
Kompatibel mit:
|
Änderungen:
|
||||||
- note.schema.json: 'created'/'updated' müssen strings sein. (Wichtig!)
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.2 (2025-09-09): Externe Links hinzugefügt
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,62 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/ollama_tool_runner.py — Minimaler Tool-Caller für Ollama + mindnet
|
FILE: scripts/ollama_tool_runner.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Zweck:
|
Zweck:
|
||||||
Führt den Tool-Call-Loop für mindnet_query / mindnet_subgraph aus.
|
-------
|
||||||
Nutzt /tools/ollama (Schema) und deine FastAPI (/query, /graph).
|
Minimaler Tool-Caller für Ollama mit mindnet-Tools.
|
||||||
ENV:
|
Führt Tool-Call-Loop für mindnet_query und mindnet_subgraph aus.
|
||||||
OLLAMA=http://127.0.0.1:11434
|
|
||||||
API_BASE=http://127.0.0.1:8000
|
Funktionsweise:
|
||||||
MODEL=llama3.1
|
---------------
|
||||||
Nutzung:
|
1. Lädt Tool-Schema von /tools/ollama Endpoint
|
||||||
|
2. Sendet Query an Ollama mit Tool-Definitionen
|
||||||
|
3. Ollama entscheidet, welche Tools aufzurufen sind
|
||||||
|
4. Führt Tool-Calls aus:
|
||||||
|
- mindnet_query: Ruft /query Endpoint auf
|
||||||
|
- mindnet_subgraph: Ruft /graph Endpoint auf
|
||||||
|
5. Wiederholt bis keine weiteren Tool-Calls nötig sind
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: Konversations-Verlauf mit Tool-Calls und Antworten
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
- Exit-Code 1: Fehler (z.B. API nicht erreichbar)
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Testing von Tool-Integration
|
||||||
|
- Demo der Agent-Funktionalität
|
||||||
|
- Entwicklung neuer Tools
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Nutzt Ollama als LLM-Backend
|
||||||
|
- Tool-Schema wird von mindnet API bereitgestellt
|
||||||
|
- Unterstützt mehrere Tool-Calls in einer Konversation
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
python3 scripts/ollama_tool_runner.py "Frage an den Agenten"
|
python3 scripts/ollama_tool_runner.py "Frage an den Agenten"
|
||||||
Version:
|
|
||||||
0.1.0 (Erstanlage)
|
Parameter:
|
||||||
Stand:
|
----------
|
||||||
2025-10-07
|
Keine CLI-Parameter. Query als erstes Argument.
|
||||||
|
|
||||||
|
Umgebungsvariablen:
|
||||||
|
-------------------
|
||||||
|
OLLAMA (Default: http://127.0.0.1:11434)
|
||||||
|
API_BASE (Default: http://127.0.0.1:8000)
|
||||||
|
MODEL (Default: llama3.1)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v0.1.0 (2025-10-07): Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,63 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
FILE: scripts/parse_validate_notes.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Validiert alle Markdown-Dateien in einem Vault auf strukturelle Korrektheit.
|
||||||
|
Prüft Frontmatter-Validität und Note-Payload-Erzeugung ohne Datenbank-Upsert.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt rekursiv alle .md-Dateien im angegebenen Vault-Verzeichnis
|
||||||
|
2. Für jede Datei:
|
||||||
|
- Liest und parst Markdown mit Frontmatter
|
||||||
|
- Validiert erforderliche Frontmatter-Felder (id, title, type)
|
||||||
|
- Erzeugt Note-Payload (validiert durch JSON-Serialisierung)
|
||||||
|
3. Gibt Statistik aus: Anzahl valider vs. invalider Dateien
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Exit-Code 0: Alle Dateien sind valide
|
||||||
|
- Exit-Code 1: Mindestens eine Datei ist invalide
|
||||||
|
- Ausgabe: "✅ Valid: X | ❌ Invalid: Y"
|
||||||
|
- Fehlerdetails werden auf stderr ausgegeben
|
||||||
|
|
||||||
|
Häufige Fehler:
|
||||||
|
--------------
|
||||||
|
- Fehlende oder ungültige Frontmatter-Felder (id, title, type)
|
||||||
|
- JSON-Serialisierungsfehler im Payload (z.B. ungültige Datentypen)
|
||||||
|
- Encoding-Probleme beim Lesen der Datei
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.parse_validate_notes --vault ./vault
|
||||||
|
python3 -m scripts.parse_validate_notes --vault ./vault --include "**/*.md" --exclude /.obsidian/ /_imported/
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--include PATTERN Glob-Pattern für Dateien (Default: "**/*.md")
|
||||||
|
--exclude PATH Pfade zum Ausschließen (Default: /.obsidian/, /_imported/)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Entfernt: app.core.note_payload (ersetzt durch ingestion_note_payload)
|
||||||
|
- Entfernt: app.core.validate_note (Validierung in make_note_payload integriert)
|
||||||
|
- Entfernt: jsonschema.ValidationError (nicht mehr benötigt)
|
||||||
|
v1.0.0: Erster Release
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import glob
|
import glob
|
||||||
from jsonschema import ValidationError
|
|
||||||
from app.core.parser import read_markdown, validate_required_frontmatter, normalize_frontmatter
|
from app.core.parser import read_markdown, validate_required_frontmatter, normalize_frontmatter
|
||||||
from app.core.note_payload import make_note_payload
|
|
||||||
from app.core.validate_note import validate_note_payload
|
|
||||||
from app.core.ingestion.ingestion_note_payload import make_note_payload
|
from app.core.ingestion.ingestion_note_payload import make_note_payload
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,11 +89,10 @@ def main():
|
||||||
parsed = read_markdown(path)
|
parsed = read_markdown(path)
|
||||||
fm = normalize_frontmatter(parsed.frontmatter)
|
fm = normalize_frontmatter(parsed.frontmatter)
|
||||||
validate_required_frontmatter(fm)
|
validate_required_frontmatter(fm)
|
||||||
# Note-Payload gemäß note.schema.json validieren
|
# Note-Payload wird in make_note_payload bereits validiert (JSON-Serialisierung)
|
||||||
payload = make_note_payload(parsed, vault_root=root)
|
payload = make_note_payload(parsed, vault_root=root, file_path=path)
|
||||||
validate_note_payload(payload)
|
|
||||||
ok += 1
|
ok += 1
|
||||||
except (ValidationError, ValueError) as e:
|
except (ValueError, TypeError, KeyError, AttributeError) as e:
|
||||||
failed += 1
|
failed += 1
|
||||||
print(f"❌ {os.path.relpath(path, root)} :: {e}", file=sys.stderr)
|
print(f"❌ {os.path.relpath(path, root)} :: {e}", file=sys.stderr)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,104 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/payload_dryrun.py (zeigt, was VOR dem Upsert tatsächlich in den Payloads steht)
|
FILE: scripts/payload_dryrun.py
|
||||||
- KEIN Überschreiben der Note-Payload mehr
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
- types.yaml ist maßgeblich (gemäß app/core/note_payload.py & chunk_payload.py)
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Zeigt die Payload-Struktur, die vor dem Datenbank-Upsert erzeugt würde.
|
||||||
|
Nützlich zur Validierung der Payload-Erzeugung und Konfiguration (types.yaml).
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt alle Markdown-Dateien im Vault
|
||||||
|
2. Für jede Datei:
|
||||||
|
- Parst Markdown mit Frontmatter
|
||||||
|
- Erzeugt Note-Payload (wie in make_note_payload)
|
||||||
|
- Erstellt Chunks via assemble_chunks
|
||||||
|
- Erzeugt Chunk-Payloads (wie in make_chunk_payloads)
|
||||||
|
- Optional: Erzeugt Edges (mit --with-edges)
|
||||||
|
3. Gibt JSON pro Note aus mit Payload-Zusammenfassung
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON-Objekte (ein Objekt pro Note, eine Zeile pro Objekt)
|
||||||
|
- Jedes Objekt enthält:
|
||||||
|
* note_id, title, type, path
|
||||||
|
* note_payload: retriever_weight, chunk_profile
|
||||||
|
* chunks_summary: count, first (erste 3 Chunks mit Metadaten)
|
||||||
|
* edges_summary (nur mit --with-edges): total, by_kind
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Validierung der types.yaml Konfiguration
|
||||||
|
- Debugging von Payload-Erzeugungsproblemen
|
||||||
|
- Analyse der Chunk-Struktur vor dem Import
|
||||||
|
- Prüfung von retriever_weight und chunk_profile Zuweisungen
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- types.yaml ist maßgeblich für Payload-Erzeugung
|
||||||
|
- Frontmatter-Überschreibungen werden berücksichtigt
|
||||||
|
- Keine Datenbank-Operationen, rein analytisch
|
||||||
|
- Chunking nutzt vollständiges assemble_chunks (nicht vereinfacht)
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.payload_dryrun --vault ./vault
|
||||||
|
python3 -m scripts.payload_dryrun --vault ./vault --note-id my-note-id
|
||||||
|
python3 -m scripts.payload_dryrun --vault ./vault --with-edges
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--note-id ID Nur eine bestimmte Note verarbeiten (optional)
|
||||||
|
--with-edges Edge-Erzeugung einschließen (optional)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Entfernt: Fallback für app.core.edges
|
||||||
|
- Verwendet direkt: app.core.derive_edges
|
||||||
|
- Parameter korrigiert: chunk_payloads → chunks, note_level_refs → note_level_references
|
||||||
|
v1.0.0: Erster Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, json
|
import argparse, os, json, asyncio
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
||||||
from app.core.chunking import assemble_chunks
|
from app.core.chunking import assemble_chunks
|
||||||
from app.core.ingestion.ingestion_note_payload import make_note_payload
|
from app.core.ingestion.ingestion_note_payload import make_note_payload
|
||||||
from app.core.ingestion.ingestion_chunk_payload import make_chunk_payloads
|
from app.core.ingestion.ingestion_chunk_payload import make_chunk_payloads
|
||||||
try:
|
|
||||||
from app.core.derive_edges import build_edges_for_note
|
from app.core.derive_edges import build_edges_for_note
|
||||||
except Exception:
|
|
||||||
from app.core.edges import build_edges_for_note # type: ignore
|
|
||||||
|
|
||||||
def main():
|
async def process_file(path: str, root: str, args):
|
||||||
ap = argparse.ArgumentParser()
|
"""Verarbeitet eine einzelne Datei asynchron."""
|
||||||
ap.add_argument("--vault", required=True)
|
|
||||||
ap.add_argument("--note-id")
|
|
||||||
ap.add_argument("--with-edges", action="store_true")
|
|
||||||
args = ap.parse_args()
|
|
||||||
|
|
||||||
root = os.path.abspath(args.vault)
|
|
||||||
|
|
||||||
files: List[str] = []
|
|
||||||
for dp, _, fns in os.walk(root):
|
|
||||||
for fn in fns:
|
|
||||||
if fn.lower().endswith(".md"):
|
|
||||||
files.append(os.path.join(dp, fn))
|
|
||||||
files.sort()
|
|
||||||
|
|
||||||
for path in files:
|
|
||||||
parsed = read_markdown(path)
|
parsed = read_markdown(path)
|
||||||
if not parsed:
|
if not parsed:
|
||||||
continue
|
return None
|
||||||
fm = normalize_frontmatter(parsed.frontmatter)
|
fm = normalize_frontmatter(parsed.frontmatter)
|
||||||
try:
|
try:
|
||||||
validate_required_frontmatter(fm)
|
validate_required_frontmatter(fm)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(json.dumps({"path": path, "error": f"invalid frontmatter: {e}"}))
|
print(json.dumps({"path": path, "error": f"invalid frontmatter: {e}"}))
|
||||||
continue
|
return None
|
||||||
|
|
||||||
if args.note_id and fm.get("id") != args.note_id:
|
if args.note_id and fm.get("id") != args.note_id:
|
||||||
continue
|
return None
|
||||||
|
|
||||||
# Note-Payload exakt so, wie der Importer ihn baut (types.yaml maßgeblich)
|
# Note-Payload exakt so, wie der Importer ihn baut (types.yaml maßgeblich)
|
||||||
note_pl = make_note_payload(parsed,
|
note_pl = make_note_payload(parsed,
|
||||||
vault_root=root,
|
vault_root=root,
|
||||||
hash_mode="body",
|
|
||||||
hash_normalize="canonical",
|
|
||||||
hash_source="parsed",
|
hash_source="parsed",
|
||||||
|
hash_normalize="canonical",
|
||||||
file_path=path)
|
file_path=path)
|
||||||
|
|
||||||
body_text = getattr(parsed, "body", "") or ""
|
body_text = getattr(parsed, "body", "") or ""
|
||||||
chunks = assemble_chunks(fm["id"], body_text, fm.get("type","concept"))
|
chunks = await assemble_chunks(fm["id"], body_text, fm.get("type","concept"))
|
||||||
|
|
||||||
chunk_note = {
|
chunk_note = {
|
||||||
"frontmatter": fm,
|
"frontmatter": fm,
|
||||||
|
|
@ -99,8 +140,8 @@ def main():
|
||||||
if args.with_edges:
|
if args.with_edges:
|
||||||
edges = build_edges_for_note(
|
edges = build_edges_for_note(
|
||||||
note_id=note_pl.get("note_id") or fm.get("id"),
|
note_id=note_pl.get("note_id") or fm.get("id"),
|
||||||
chunk_payloads=chunk_pls,
|
chunks=chunk_pls,
|
||||||
note_level_refs=note_pl.get("references") or [],
|
note_level_references=note_pl.get("references") or [],
|
||||||
include_note_scope_refs=False,
|
include_note_scope_refs=False,
|
||||||
)
|
)
|
||||||
kinds = {}
|
kinds = {}
|
||||||
|
|
@ -109,7 +150,31 @@ def main():
|
||||||
kinds[k] = kinds.get(k, 0) + 1
|
kinds[k] = kinds.get(k, 0) + 1
|
||||||
out["edges_summary"] = {"total": len(edges), "by_kind": kinds}
|
out["edges_summary"] = {"total": len(edges), "by_kind": kinds}
|
||||||
|
|
||||||
print(json.dumps(out, ensure_ascii=False))
|
return out
|
||||||
|
|
||||||
|
async def main_async():
|
||||||
|
ap = argparse.ArgumentParser()
|
||||||
|
ap.add_argument("--vault", required=True)
|
||||||
|
ap.add_argument("--note-id")
|
||||||
|
ap.add_argument("--with-edges", action="store_true")
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
root = os.path.abspath(args.vault)
|
||||||
|
|
||||||
|
files: List[str] = []
|
||||||
|
for dp, _, fns in os.walk(root):
|
||||||
|
for fn in fns:
|
||||||
|
if fn.lower().endswith(".md"):
|
||||||
|
files.append(os.path.join(dp, fn))
|
||||||
|
files.sort()
|
||||||
|
|
||||||
|
for path in files:
|
||||||
|
result = await process_file(path, root, args)
|
||||||
|
if result:
|
||||||
|
print(json.dumps(result, ensure_ascii=False))
|
||||||
|
|
||||||
|
def main():
|
||||||
|
asyncio.run(main_async())
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,60 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
FILE: scripts/preview_chunks.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
|
Zeigt eine Vorschau der Chunk-Struktur für Notizen im Vault.
|
||||||
|
Nützlich zur Analyse der Chunking-Strategie und Nachbarschafts-Links.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Scannt alle Markdown-Dateien im Vault
|
||||||
|
2. Für jede Datei:
|
||||||
|
- Erzeugt Note-Payload
|
||||||
|
- Erstellt Chunks via assemble_chunks
|
||||||
|
- Erzeugt Chunk-Payloads
|
||||||
|
3. Gibt JSON pro Note aus mit Chunk-Details
|
||||||
|
|
||||||
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON-Objekte (ein Objekt pro Note, eine Zeile pro Objekt)
|
||||||
|
- Jedes Objekt enthält:
|
||||||
|
* note_id, title
|
||||||
|
* num_chunks: Anzahl der Chunks
|
||||||
|
* avg_tokens: Durchschnittliche Token pro Chunk
|
||||||
|
* chunks: Array mit Chunk-Details (id, tokens, section, prev, next)
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Analyse der Chunk-Verteilung
|
||||||
|
- Validierung der Nachbarschafts-Links
|
||||||
|
- Debugging von Chunking-Problemen
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Nutzt synchrones assemble_chunks (kann async sein)
|
||||||
|
- Zeigt nur Struktur, keine Inhalte
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.preview_chunks --vault ./vault
|
||||||
|
python3 -m scripts.preview_chunks --vault ./vault --note-id my-note-id
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--note-id ID Nur eine bestimmte Note verarbeiten (optional)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, os, glob, json
|
import argparse, os, glob, json
|
||||||
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
from app.core.parser import read_markdown, normalize_frontmatter, validate_required_frontmatter
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,79 @@
|
||||||
# scripts/prune_qdrant_vs_vault.py
|
#!/usr/bin/env python3
|
||||||
# -----------------------------------------------------------------------------
|
# -*- coding: utf-8 -*-
|
||||||
# Name: prune_qdrant_vs_vault.py
|
"""
|
||||||
# Version: 1.0.0 (2025-09-08)
|
FILE: scripts/prune_qdrant_vs_vault.py
|
||||||
# Zweck: Entfernt verwaiste Qdrant-Einträge (notes/chunks/edges), wenn
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
# die zugehörigen Markdown-Dateien im Vault nicht mehr existieren.
|
STATUS: Active
|
||||||
#
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
# Was es macht:
|
|
||||||
# - Liest alle note_id aus dem Vault (Frontmatter: id / note_id).
|
Zweck:
|
||||||
# - Liest alle note_id aus Qdrant (mindnet_notes).
|
-------
|
||||||
# - Bildet die Differenz (nur in Qdrant vorhandene, im Vault fehlende).
|
Bereinigt verwaiste Einträge in Qdrant, wenn die zugehörigen Markdown-Dateien
|
||||||
# - Löscht für jede verwaiste note_id:
|
im Vault nicht mehr existieren. Stellt Konsistenz zwischen Vault und Datenbank her.
|
||||||
# * Notes-Point(s)
|
|
||||||
# * Alle Chunks der Note
|
Funktionsweise:
|
||||||
# * Alle Edges, die auf diese Note referenzieren
|
---------------
|
||||||
# (source_id == note_id ODER target_id == note_id ODER
|
1. Liest alle note_id aus dem Vault (aus Frontmatter: id / note_id)
|
||||||
# source_note_id == note_id ODER target_note_id == note_id)
|
2. Liest alle note_id aus Qdrant (Collection: {prefix}_notes)
|
||||||
#
|
3. Berechnet Differenz: note_ids nur in Qdrant vorhanden (verwaist)
|
||||||
# Hinweise:
|
4. Für jede verwaiste note_id (nur mit --apply):
|
||||||
# - Kein globaler Delete. Nur betroffene note_id.
|
- Löscht Note-Point(s) aus {prefix}_notes
|
||||||
# - Dry-Run standardmäßig; tatsächliches Löschen erst mit --apply.
|
- Löscht alle Chunks der Note aus {prefix}_chunks
|
||||||
# - Interaktive Bestätigung (abschaltbar mit --yes).
|
- Löscht alle Edges, die auf diese Note referenzieren:
|
||||||
#
|
* source_id == note_id
|
||||||
# Aufruf:
|
* target_id == note_id
|
||||||
# python3 -m scripts.prune_qdrant_vs_vault --vault ./vault --prefix mindnet
|
* source_note_id == note_id
|
||||||
# python3 -m scripts.prune_qdrant_vs_vault --vault ./vault --prefix mindnet --apply
|
* target_note_id == note_id
|
||||||
# python3 -m scripts.prune_qdrant_vs_vault --vault ./vault --prefix mindnet --apply --yes
|
|
||||||
#
|
Ergebnis-Interpretation:
|
||||||
# Voraussetzungen:
|
------------------------
|
||||||
# - Ausführung im aktivierten venv empfohlen: source .venv/bin/activate
|
- Ausgabe: JSON mit Preview-Informationen
|
||||||
# - Qdrant läuft lokal (oder URL/API-Key in ENV), siehe app/core/qdrant.py
|
* mode: "DRY-RUN" oder "APPLY"
|
||||||
#
|
* counts: Statistiken (vault_note_ids, qdrant_note_ids, orphans)
|
||||||
# Änderungen:
|
* orphans_sample: Erste 20 verwaiste note_ids
|
||||||
# - 1.0.0: Erster Release.
|
- Bei --apply: Zusätzlich JSON mit deleted-Statistiken
|
||||||
# -----------------------------------------------------------------------------
|
* deleted.notes: Anzahl gelöschter Note-Points
|
||||||
|
* deleted.chunks: Anzahl gelöschter Chunks
|
||||||
|
* deleted.edges: Anzahl gelöschter Edges
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Regelmäßige Wartung nach Vault-Bereinigung
|
||||||
|
- Vor Migrationen oder größeren Umstrukturierungen
|
||||||
|
- Konsistenz-Check zwischen Vault und Datenbank
|
||||||
|
|
||||||
|
Sicherheitsmerkmale:
|
||||||
|
-------------------
|
||||||
|
- Dry-Run standardmäßig (keine Änderungen ohne --apply)
|
||||||
|
- Interaktive Bestätigung (außer mit --yes)
|
||||||
|
- Nur betroffene note_ids werden gelöscht (kein globaler Delete)
|
||||||
|
- Zeigt Preview vor Ausführung
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
# Dry-Run (nur Analyse)
|
||||||
|
python3 -m scripts.prune_qdrant_vs_vault --vault ./vault --prefix mindnet
|
||||||
|
|
||||||
|
# Tatsächliches Löschen
|
||||||
|
python3 -m scripts.prune_qdrant_vs_vault --vault ./vault --prefix mindnet --apply
|
||||||
|
|
||||||
|
# Ohne Rückfrage
|
||||||
|
python3 -m scripts.prune_qdrant_vs_vault --vault ./vault --prefix mindnet --apply --yes
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--vault PATH Pfad zum Vault-Verzeichnis (erforderlich)
|
||||||
|
--prefix TEXT Collection-Präfix (Default: mindnet)
|
||||||
|
--apply Führt tatsächliches Löschen durch (sonst nur Dry-Run)
|
||||||
|
--yes Keine interaktive Bestätigung
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Geändert: parse_markdown_file → read_markdown + normalize_frontmatter
|
||||||
|
- Parsing-Logik an neue API angepasst
|
||||||
|
v1.0.0 (2025-09-08): Erster Release
|
||||||
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
|
@ -45,15 +86,16 @@ from qdrant_client import QdrantClient
|
||||||
from qdrant_client.http import models as rest
|
from qdrant_client.http import models as rest
|
||||||
|
|
||||||
from app.core.qdrant import QdrantConfig, get_client, collection_names
|
from app.core.qdrant import QdrantConfig, get_client, collection_names
|
||||||
from app.core.parser import parse_markdown_file # nutzt euer bestehendes Parsing/Schema
|
from app.core.parser import read_markdown, normalize_frontmatter
|
||||||
|
|
||||||
|
|
||||||
def read_vault_note_ids(vault_dir: Path) -> Set[str]:
|
def read_vault_note_ids(vault_dir: Path) -> Set[str]:
|
||||||
note_ids: Set[str] = set()
|
note_ids: Set[str] = set()
|
||||||
for p in vault_dir.rglob("*.md"):
|
for p in vault_dir.rglob("*.md"):
|
||||||
try:
|
try:
|
||||||
parsed = parse_markdown_file(str(p))
|
parsed = read_markdown(str(p))
|
||||||
fm = parsed.frontmatter if hasattr(parsed, "frontmatter") else (parsed.get("frontmatter") or {})
|
if parsed:
|
||||||
|
fm = normalize_frontmatter(parsed.frontmatter) if parsed.frontmatter else {}
|
||||||
nid = fm.get("id") or fm.get("note_id")
|
nid = fm.get("id") or fm.get("note_id")
|
||||||
if nid:
|
if nid:
|
||||||
note_ids.add(str(nid))
|
note_ids.add(str(nid))
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,59 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Script: scripts/report_hashes.py — Übersicht & Lücken bei Mehrfach-Hashes
|
FILE: scripts/report_hashes.py
|
||||||
Version: 1.0.0
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
Datum: 2025-09-10
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Funktion
|
Zweck:
|
||||||
--------
|
-------
|
||||||
Listet je Note die vorhandenen Einträge im Feld `hashes` (Signaturen: <mode>:<source>:<normalize>)
|
Erstellt Übersicht über Hash-Signaturen in Note-Payloads.
|
||||||
und meldet fehlende Soll-Keys. Eignet sich als CI-Check.
|
Meldet fehlende Soll-Keys für Multi-Hash Change Detection.
|
||||||
|
|
||||||
Optionen
|
Funktionsweise:
|
||||||
--------
|
---------------
|
||||||
--prefix TEXT Collection-Prefix (CLI überschreibt ENV)
|
1. Lädt alle Notes aus {prefix}_notes
|
||||||
--require K [K ...] Zusätzliche Soll-Keys (Default: body|frontmatter|full:parsed:canonical)
|
2. Prüft für jede Note das `hashes` Feld
|
||||||
--fail-on-missing Exitcode 2, wenn fehlende Keys gefunden werden
|
3. Vergleicht vorhandene Keys mit Soll-Keys
|
||||||
|
4. Meldet fehlende Keys pro Note
|
||||||
|
|
||||||
Beispiele
|
Ergebnis-Interpretation:
|
||||||
|
------------------------
|
||||||
|
- Ausgabe: JSON mit Hash-Übersicht
|
||||||
|
* notes_total: Anzahl geprüfter Notizen
|
||||||
|
* notes_with_missing: Anzahl Notizen mit fehlenden Keys
|
||||||
|
* missing_keys: Liste fehlender Keys pro Note
|
||||||
|
- Exit-Code 0: Keine fehlenden Keys (oder --fail-on-missing nicht gesetzt)
|
||||||
|
- Exit-Code 2: Fehlende Keys gefunden (nur mit --fail-on-missing)
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- CI/CD-Validierung der Hash-Integrität
|
||||||
|
- Audit nach Migrationen
|
||||||
|
- Prüfung der Change Detection Funktionalität
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
---------
|
---------
|
||||||
|
- Multi-Hash Format: <mode>:<source>:<normalize>
|
||||||
|
- Standard Soll-Keys: body:parsed:canonical, full:parsed:canonical
|
||||||
|
- Kann zusätzliche Keys via --require anfordern
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
python3 -m scripts.report_hashes --prefix mindnet
|
python3 -m scripts.report_hashes --prefix mindnet
|
||||||
python3 -m scripts.report_hashes --require frontmatter:raw:none --fail-on-missing
|
python3 -m scripts.report_hashes --require frontmatter:raw:none --fail-on-missing
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (überschreibt ENV COLLECTION_PREFIX)
|
||||||
|
--require KEY ... Zusätzliche Soll-Keys (Default: body:parsed:canonical, full:parsed:canonical)
|
||||||
|
--fail-on-missing Exit-Code 2, wenn fehlende Keys gefunden werden
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0 (2025-09-10): Initial Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,75 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Name: scripts/reset_qdrant.py
|
FILE: scripts/reset_qdrant.py
|
||||||
Version: v1.2.1 (2025-12-11)
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
Kurzbeschreibung:
|
STATUS: Active (Core)
|
||||||
Sicheres Zurücksetzen der Qdrant-Collections für EIN Projektpräfix. Das Skript
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
ermittelt zunächst die tatsächlich betroffenen Collections und zeigt eine
|
|
||||||
Übersicht an. Anschließend wird der User um Bestätigung gebeten (interaktive
|
|
||||||
Abfrage), bevor eine der Aktionen ausgeführt wird:
|
|
||||||
|
|
||||||
- wipe: Löscht die Collections komplett und legt sie gemäß Projekt-Defaults neu an.
|
Zweck:
|
||||||
**Neu**: Danach werden *immer* die Payload-Indizes & Schema-Ergänzungen
|
-------
|
||||||
über ensure_payload_indexes() idempotent eingerichtet (falls nicht mit --no-indexes deaktiviert).
|
Sicheres Zurücksetzen der Qdrant-Collections für ein Projektpräfix.
|
||||||
- truncate: Löscht nur alle Points (Inhalte), behält die Collection-Settings.
|
Ermöglicht vollständigen Neustart (wipe) oder Löschen nur der Inhalte (truncate).
|
||||||
**Neu**: Optional (Default) werden im Anschluss die Payload-Indizes geprüft/ergänzt.
|
|
||||||
|
|
||||||
Aufruf (aus Projekt-Root, im venv):
|
Funktionsweise:
|
||||||
python3 -m scripts.reset_qdrant --mode wipe [--prefix PREFIX] [--yes] [--dry-run]
|
---------------
|
||||||
python3 -m scripts.reset_qdrant --mode truncate [--prefix PREFIX] [--yes] [--dry-run]
|
1. Ermittelt betroffene Collections (notes, chunks, edges für Präfix)
|
||||||
|
2. Zeigt Preview der existierenden Collections
|
||||||
|
3. Interaktive Bestätigung (außer mit --yes)
|
||||||
|
4. Führt Aktion aus:
|
||||||
|
- wipe: Löscht Collections komplett, legt neu an, richtet Indizes ein
|
||||||
|
- truncate: Löscht nur Points, behält Collection-Settings, prüft Indizes
|
||||||
|
5. Richtet Payload-Indizes idempotent ein (außer mit --no-indexes)
|
||||||
|
|
||||||
Parameter:
|
Ergebnis-Interpretation:
|
||||||
--mode wipe | truncate (Pflicht)
|
------------------------
|
||||||
--prefix Collection-Prefix (Default: env COLLECTION_PREFIX oder 'mindnet')
|
- Preview: Zeigt betroffene Collections vor Ausführung
|
||||||
--yes Keine Rückfrage, direkt ausführen (CI/CD geeignet)
|
- Exit-Code 0: Erfolgreich
|
||||||
--dry-run Nur anzeigen, was passieren würde; nichts ändern
|
- Exit-Code 1: Abgebrochen oder keine Aktion
|
||||||
--no-indexes Überspringt den Schritt ensure_payload_indexes() (Standard: Indizes/Schema werden geprüft/ergänzt)
|
- Exit-Code 2: Verbindungs- oder Konfigurationsfehler
|
||||||
|
|
||||||
Umgebungsvariablen (optional):
|
Verwendung:
|
||||||
QDRANT_URL, QDRANT_API_KEY, COLLECTION_PREFIX, VECTOR_DIM (Default 384)
|
-----------
|
||||||
(Zusätzliche ENV für Named Vectors etc. werden innerhalb ensure_collections/ensure_payload_indexes berücksichtigt.)
|
- Vor größeren Migrationen oder Schema-Änderungen
|
||||||
|
- Bei Inkonsistenzen in der Datenbank
|
||||||
|
- Für Entwicklung/Testing (schneller Reset)
|
||||||
|
- CI/CD-Pipelines (mit --yes)
|
||||||
|
|
||||||
Sicherheitsmerkmale:
|
Sicherheitsmerkmale:
|
||||||
- Betrachtet ausschließlich Collections des angegebenen Präfixes.
|
-------------------
|
||||||
- Listet vor Ausführung die tatsächlich existierenden Ziel-Collections auf.
|
- Betrachtet nur Collections des angegebenen Präfixes
|
||||||
- Fragt interaktiv nach Bestätigung (es sei denn --yes ist gesetzt).
|
- Listet betroffene Collections vor Ausführung auf
|
||||||
|
- Interaktive Bestätigung (außer mit --yes)
|
||||||
|
- Dry-Run Modus verfügbar
|
||||||
|
|
||||||
Exitcodes:
|
Aufruf:
|
||||||
0 = OK, 1 = abgebrochen/keine Aktion, 2 = Verbindungs-/Konfigurationsfehler
|
-------
|
||||||
|
python3 -m scripts.reset_qdrant --mode wipe --prefix mindnet
|
||||||
|
python3 -m scripts.reset_qdrant --mode truncate --prefix mindnet --yes
|
||||||
|
python3 -m scripts.reset_qdrant --mode wipe --dry-run
|
||||||
|
|
||||||
Changelog:
|
Parameter:
|
||||||
v1.2.1: Fix: load_dotenv() hinzugefügt, damit VECTOR_DIM aus .env gelesen wird.
|
----------
|
||||||
v1.2.0: ensure_payload_indexes() nach wipe/truncate standardmäßig ausführen (idempotent); --no-indexes Flag ergänzt.
|
--mode MODE wipe | truncate (Pflicht)
|
||||||
v1.1.1: Stabilisierung & Preview (2025-09-05).
|
- wipe: Collections löschen & neu anlegen
|
||||||
v1.1.0: Interaktive Bestätigung, --yes/--dry-run hinzugefügt, Preview der betroffenen Collections.
|
- truncate: Nur Points löschen, Settings behalten
|
||||||
v1.0.0: Wipe/Truncate ohne Bestätigungsabfrage.
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
--yes Keine Rückfrage, direkt ausführen (CI/CD)
|
||||||
|
--dry-run Nur anzeigen, was passieren würde
|
||||||
|
--no-indexes Überspringt ensure_payload_indexes() (Standard: Indizes werden geprüft/ergänzt)
|
||||||
|
|
||||||
|
Umgebungsvariablen:
|
||||||
|
-------------------
|
||||||
|
QDRANT_URL, QDRANT_API_KEY, COLLECTION_PREFIX, VECTOR_DIM (Default: 768)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Aktualisiert: Import-Pfade für neue Struktur
|
||||||
|
v1.2.1 (2025-12-11): Fix load_dotenv() für VECTOR_DIM
|
||||||
|
v1.2.0: ensure_payload_indexes() standardmäßig nach wipe/truncate
|
||||||
|
v1.1.0: Interaktive Bestätigung, --yes/--dry-run
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse
|
import argparse
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,66 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# scripts/resolve_unresolved_references.py
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
resolve_unresolved_references.py — Unaufgelöste Wikilinks in Qdrant nachträglich auflösen
|
FILE: scripts/resolve_unresolved_references.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Version: 1.1.0 (Fixed for v2.6 Architecture)
|
Zweck:
|
||||||
|
-------
|
||||||
|
Löst unaufgelöste Wikilinks in Qdrant nachträglich auf.
|
||||||
|
Findet Edges mit status=="unresolved" und versucht sie über Titel/Alias aufzulösen.
|
||||||
|
|
||||||
Zweck
|
Funktionsweise:
|
||||||
------
|
---------------
|
||||||
- Findet Edges in {prefix}_edges mit payload.status=="unresolved".
|
1. Baut Lookup-Index aus allen Notizen:
|
||||||
- Baut einen In-Memory Index aller Notizen (Titel/Alias -> ID).
|
- Mapping: lower(title) -> note_id
|
||||||
- Aktualisiert die Edges (setzt target_id, entfernt status).
|
- Mapping: lower(alias) -> note_id
|
||||||
- Erzeugt symmetrische 'backlink'-Kanten für 'references'.
|
2. Findet alle Edges mit status=="unresolved"
|
||||||
|
3. Versucht Auflösung über Lookup-Index
|
||||||
|
4. Aktualisiert erfolgreich aufgelöste Edges:
|
||||||
|
- Setzt target_id
|
||||||
|
- Entfernt status
|
||||||
|
- Fügt resolution="healed_by_script" hinzu
|
||||||
|
5. Erzeugt Backlinks für erfolgreich aufgelöste references-Edges
|
||||||
|
|
||||||
Aufruf
|
Ergebnis-Interpretation:
|
||||||
------
|
------------------------
|
||||||
|
- Log-Ausgabe: Fortschritt und Statistiken
|
||||||
|
- "Resolvable: X/Y": Anzahl aufgelösbarer Edges
|
||||||
|
- Ohne --apply: Dry-Run (keine DB-Änderungen)
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Nach Import von neuen Notizen, die bestehende Links auflösen
|
||||||
|
- Reparatur von "Red Links" (Links auf noch nicht existierende Notizen)
|
||||||
|
- Wartung des Graphen nach größeren Änderungen
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Sucht nach status=="unresolved" in Edge-Payloads
|
||||||
|
- Auflösung erfolgt über Titel und Aliases (case-insensitive)
|
||||||
|
- Erzeugt automatisch Backlinks für references-Edges
|
||||||
|
- Batch-Verarbeitung für Performance
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
python3 -m scripts.resolve_unresolved_references --apply
|
python3 -m scripts.resolve_unresolved_references --apply
|
||||||
|
python3 -m scripts.resolve_unresolved_references --prefix mindnet --limit 1000 --apply
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX)
|
||||||
|
--apply Führt tatsächliche DB-Änderungen durch (sonst Dry-Run)
|
||||||
|
--limit INT Maximale Anzahl zu verarbeitender Edges (0=alle, Default: 0)
|
||||||
|
--batch INT Batch-Größe für Upserts (Default: 100)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.1.0: Fixed for v2.6 Architecture
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,63 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
|
FILE: scripts/setup_mindnet_collections.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
|
Zweck:
|
||||||
|
-------
|
||||||
Richtet die Qdrant-Collections für das mindnet-Projekt ein.
|
Richtet die Qdrant-Collections für das mindnet-Projekt ein.
|
||||||
|
Legt Collections und Payload-Indizes an (idempotent).
|
||||||
|
|
||||||
Collections:
|
Funktionsweise:
|
||||||
- mindnet_chunks : semantische Suche über Markdown-Text-Chunks (Vektor: dim/Cosine)
|
---------------
|
||||||
- mindnet_notes : 1 Punkt pro Notiz (Metadaten, optional Titel-Embedding)
|
1. Prüft Qdrant-Verfügbarkeit (optional /ready Endpoint)
|
||||||
- mindnet_edges : explizite Link-Kanten (Dummy-Vektor size=1; Filter über Payload)
|
2. Legt drei Collections an:
|
||||||
|
- {prefix}_chunks: Semantische Suche über Text-Chunks (Vektor: dim/Cosine)
|
||||||
|
- {prefix}_notes: Metadaten pro Notiz (Vektor: dim/Cosine)
|
||||||
|
- {prefix}_edges: Link-Kanten (Dummy-Vektor size=1, Filter über Payload)
|
||||||
|
3. Richtet Payload-Indizes ein:
|
||||||
|
- Keyword-Indizes für häufige Filter-Felder
|
||||||
|
- Text-Index für Volltextsuche (chunks.text)
|
||||||
|
|
||||||
Eigenschaften:
|
Ergebnis-Interpretation:
|
||||||
- Idempotent: legt nur an, wenn eine Collection noch nicht existiert
|
------------------------
|
||||||
- Legt sinnvolle Payload-Indizes an (keyword/text)
|
- Ausgabe: Status pro Collection ([+] angelegt, [=] existiert bereits)
|
||||||
- Ohne "global"-Seiteneffekte; Qdrant-URL wird sauber übergeben
|
- Abschluss: JSON-Liste aller vorhandenen Collections
|
||||||
|
- Exit-Code 0: Erfolgreich
|
||||||
|
- Exit-Code 1: Fehler (z.B. Qdrant nicht erreichbar)
|
||||||
|
|
||||||
Aufrufbeispiel:
|
Verwendung:
|
||||||
python3 setup_mindnet_collections.py \
|
-----------
|
||||||
--qdrant-url http://127.0.0.1:6333 \
|
- Initial-Setup einer neuen mindnet-Instanz
|
||||||
--prefix mindnet \
|
- Nach Qdrant-Reset oder Migration
|
||||||
--dim 384 \
|
- Validierung der Collection-Struktur
|
||||||
--distance Cosine
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Idempotent: Überspringt existierende Collections
|
||||||
|
- Nutzt HTTP-API direkt (kein qdrant-client)
|
||||||
|
- Legt nur Basis-Indizes an (erweiterte Indizes via ensure_payload_indexes)
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.setup_mindnet_collections --qdrant-url http://127.0.0.1:6333 --prefix mindnet --dim 768
|
||||||
|
python3 -m scripts.setup_mindnet_collections --prefix mindnet_dev --dim 768 --distance Cosine
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--qdrant-url URL Qdrant-URL (Default: http://127.0.0.1:6333)
|
||||||
|
--prefix TEXT Collection-Präfix (Default: mindnet)
|
||||||
|
--dim INT Vektor-Dimension (Default: 384, empfohlen: 768 für nomic)
|
||||||
|
--distance METRIC Cosine | Euclid | Dot (Default: Cosine)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Kompatibilität mit WP-14 Modularisierung
|
||||||
|
- Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,66 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/validate_edges.py
|
FILE: scripts/validate_edges.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Validiert die von WP-03 erzeugten Edges in Qdrant:
|
Zweck:
|
||||||
- Zählt Kanten je Typ (references, backlink, references_at)
|
-------
|
||||||
- Prüft: Für jede "references" (resolved) existiert eine "backlink"-Gegenkante
|
Validiert die Integrität der Edges in Qdrant.
|
||||||
|
Prüft strukturelle Korrektheit, Referenz-Integrität und Konsistenz.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
|
---------------
|
||||||
|
1. Lädt alle Edges aus {prefix}_edges
|
||||||
|
2. Führt mehrere Validierungen durch:
|
||||||
|
- Zählt Edges nach Typ (references, backlink, etc.)
|
||||||
|
- Prüft: Für jede "references" existiert "backlink"-Gegenkante
|
||||||
- Prüft: "backlink" darf nicht "unresolved" sein
|
- Prüft: "backlink" darf nicht "unresolved" sein
|
||||||
- Prüft: "references_at".source_id existiert in {prefix}_chunks
|
- Prüft: "references_at".source_id existiert in chunks
|
||||||
- Prüft: "references"/"backlink" source/target existieren in {prefix}_notes
|
- Prüft: source/target existieren in notes
|
||||||
- Prüft: doppelte edge_id (sollte 0 sein, da UUIDv5 aus edge_id)
|
- Prüft: doppelte edge_id (sollte 0 sein)
|
||||||
Gibt ein kompaktes JSON-Resultat + optionale Detail-Listen aus.
|
3. Gibt kompaktes JSON-Resultat + optionale Detail-Listen aus
|
||||||
|
|
||||||
Umgebung/Parameter:
|
Ergebnis-Interpretation:
|
||||||
- QDRANT_URL (Default: http://127.0.0.1:6333)
|
------------------------
|
||||||
- QDRANT_API_KEY (optional)
|
- Ausgabe: JSON mit Validierungs-Ergebnissen
|
||||||
- COLLECTION_PREFIX (Default: mindnet)
|
* counts_by_kind: Anzahl Edges pro Typ
|
||||||
|
* validation_results: Ergebnisse der einzelnen Prüfungen
|
||||||
|
* issues: Liste gefundener Probleme (optional mit --verbose)
|
||||||
|
- Exit-Code 0: Alle Validierungen bestanden
|
||||||
|
- Exit-Code 1: Validierungsfehler gefunden
|
||||||
|
|
||||||
Beispiel:
|
Verwendung:
|
||||||
python scripts/validate_edges.py --prefix mindnet
|
-----------
|
||||||
|
- Qualitätskontrolle nach Importen
|
||||||
|
- Debugging von Graph-Problemen
|
||||||
|
- CI/CD-Validierung
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Prüft strukturelle Integrität, nicht semantische Korrektheit
|
||||||
|
- Kann bei großen Graphen langsam sein
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
|
python3 -m scripts.validate_edges --prefix mindnet
|
||||||
|
python3 -m scripts.validate_edges --prefix mindnet --verbose
|
||||||
|
|
||||||
|
Parameter:
|
||||||
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX oder mindnet)
|
||||||
|
--verbose Zeigt detaillierte Problem-Listen
|
||||||
|
|
||||||
|
Umgebungsvariablen:
|
||||||
|
-------------------
|
||||||
|
QDRANT_URL (Default: http://127.0.0.1:6333), QDRANT_API_KEY, COLLECTION_PREFIX
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0: Initial Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse
|
import argparse
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,73 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Script: scripts/verify_chunk_texts.py
|
FILE: scripts/verify_chunk_texts.py
|
||||||
Version: 1.0.0
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
Datum: 2025-09-09
|
STATUS: Active
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Kurzbeschreibung
|
Zweck:
|
||||||
|
-------
|
||||||
|
Verifiziert, dass Chunk-Texte in Qdrant korrekt gespeichert sind und
|
||||||
|
der Note-Body aus Chunks rekonstruiert werden kann.
|
||||||
|
|
||||||
|
Funktionsweise:
|
||||||
---------------
|
---------------
|
||||||
Verifiziert, dass in Qdrant für jede Note die zugehörigen Chunks ein Textfeld
|
1. Lädt alle Notes aus {prefix}_notes
|
||||||
enthalten und der Body (notes.payload.fulltext) aus den Chunk-Texten sinnvoll
|
2. Für jede Note:
|
||||||
rekonstruiert werden kann.
|
- Lädt zugehörige Chunks
|
||||||
|
- Prüft, dass alle Chunks Text enthalten (text/content/raw)
|
||||||
|
- Rekonstruiert Body aus Chunks (sortiert nach chunk_index/chunk_id)
|
||||||
|
- Berechnet Coverage: gefundene Textsegmente / Fulltext-Länge
|
||||||
|
3. Validiert gegen notes.payload.fulltext
|
||||||
|
|
||||||
Prüfungen pro Note:
|
Ergebnis-Interpretation:
|
||||||
- Alle Chunks vorhanden (>=1).
|
------------------------
|
||||||
- Jedes Chunk-Payload hat einen nutzbaren Textschlüssel: "text" (bevorzugt), sonst "content", sonst "raw".
|
- Ausgabe: JSON mit Validierungs-Ergebnissen
|
||||||
- Reihenfolge der Chunks wird stabil bestimmt (payload.chunk_index -> Nummer aus chunk_id).
|
* summary: Gesamtstatistiken
|
||||||
- Coverage: Summe der im Fulltext gefundenen Chunk-Textsegmente / len(Fulltext) (Toleranz für Overlaps).
|
* per_note: Details pro Note
|
||||||
-> OK wenn coverage >= 0.90 (konfigurierbar via --min-coverage)
|
* coverage: Durchschnittliche Coverage
|
||||||
|
- Exit-Code 0: Alle Prüfungen bestanden
|
||||||
|
- Exit-Code 1: Probleme gefunden
|
||||||
|
|
||||||
Ausgabe:
|
Verwendung:
|
||||||
- JSON mit Gesamtsummen und Details je Note.
|
-----------
|
||||||
|
- Validierung nach Importen
|
||||||
|
- Diagnose von Text-Rekonstruktionsproblemen
|
||||||
|
- Qualitätskontrolle
|
||||||
|
|
||||||
ENV:
|
Hinweise:
|
||||||
- QDRANT_URL | QDRANT_HOST/QDRANT_PORT | QDRANT_API_KEY
|
---------
|
||||||
- COLLECTION_PREFIX (Fallback, wenn --prefix fehlt)
|
- Coverage-Toleranz für Overlaps (Standard: >= 0.90)
|
||||||
|
- Prüft Text-Felder: text (bevorzugt), content, raw
|
||||||
|
|
||||||
Beispiele:
|
Aufruf:
|
||||||
# Alle Notes prüfen (Prefix aus ENV)
|
-------
|
||||||
python3 -m scripts.verify_chunk_texts
|
python3 -m scripts.verify_chunk_texts --prefix mindnet
|
||||||
|
python3 -m scripts.verify_chunk_texts --note-id concept-alpha --min-coverage 0.95
|
||||||
|
|
||||||
# Nur eine Note prüfen
|
Parameter:
|
||||||
python3 -m scripts.verify_chunk_texts --note-id concept-alpha
|
----------
|
||||||
|
--prefix TEXT Collection-Präfix (Default: ENV COLLECTION_PREFIX)
|
||||||
|
--note-id ID Nur eine bestimmte Note prüfen (optional)
|
||||||
|
--min-coverage F Minimale Coverage (Default: 0.90)
|
||||||
|
|
||||||
# Prefix explizit setzen und strengere Coverage verlangen
|
Umgebungsvariablen:
|
||||||
python3 -m scripts.verify_chunk_texts --prefix mindnet --min-coverage 0.95
|
-------------------
|
||||||
|
QDRANT_URL | QDRANT_HOST/QDRANT_PORT | QDRANT_API_KEY, COLLECTION_PREFIX
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v1.0.0 (2025-09-09): Initial Release
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse, json, os, re, sys
|
import argparse, json, os, re, sys
|
||||||
from typing import Dict, List, Tuple, Optional
|
from typing import Dict, List, Tuple, Optional
|
||||||
|
|
||||||
from qdrant_client import QdrantClient
|
|
||||||
from qdrant_client.http import models as rest
|
from qdrant_client.http import models as rest
|
||||||
|
|
||||||
def _names(prefix: str) -> Tuple[str,str,str]:
|
from app.core.qdrant import QdrantConfig, get_client, collection_names
|
||||||
return f"{prefix}_notes", f"{prefix}_chunks", f"{prefix}_edges"
|
|
||||||
|
|
||||||
def _client() -> QdrantClient:
|
|
||||||
url = os.getenv("QDRANT_URL")
|
|
||||||
if not url:
|
|
||||||
host = os.getenv("QDRANT_HOST", "127.0.0.1")
|
|
||||||
port = int(os.getenv("QDRANT_PORT", "6333"))
|
|
||||||
url = f"http://{host}:{port}"
|
|
||||||
api_key = os.getenv("QDRANT_API_KEY") or None
|
|
||||||
return QdrantClient(url=url, api_key=api_key)
|
|
||||||
|
|
||||||
def _chunk_sort_key(p: Dict, pid: str) -> Tuple[int,int,str]:
|
def _chunk_sort_key(p: Dict, pid: str) -> Tuple[int,int,str]:
|
||||||
# Primär: payload.chunk_index, sekundär: Nummer am Ende der ID (#cNN oder #NN), sonst 0
|
# Primär: payload.chunk_index, sekundär: Nummer am Ende der ID (#cNN oder #NN), sonst 0
|
||||||
|
|
@ -104,9 +119,11 @@ def main() -> None:
|
||||||
ap.add_argument("--min-coverage", type=float, default=0.90, help="Mindestabdeckung durch Chunks (Default: 0.90)")
|
ap.add_argument("--min-coverage", type=float, default=0.90, help="Mindestabdeckung durch Chunks (Default: 0.90)")
|
||||||
args = ap.parse_args()
|
args = ap.parse_args()
|
||||||
|
|
||||||
prefix = args.prefix or os.getenv("COLLECTION_PREFIX", "mindnet")
|
cfg = QdrantConfig.from_env()
|
||||||
notes_col, chunks_col, _ = _names(prefix)
|
if args.prefix:
|
||||||
cli = _client()
|
cfg.prefix = args.prefix
|
||||||
|
notes_col, chunks_col, _ = collection_names(cfg.prefix)
|
||||||
|
cli = get_client(cfg)
|
||||||
|
|
||||||
# Notes abrufen (optional filter by note_id)
|
# Notes abrufen (optional filter by note_id)
|
||||||
notes_filter = None
|
notes_filter = None
|
||||||
|
|
@ -125,7 +142,7 @@ def main() -> None:
|
||||||
if off is None:
|
if off is None:
|
||||||
break
|
break
|
||||||
|
|
||||||
results = []
|
results: List[Dict] = []
|
||||||
total_missing_text = 0
|
total_missing_text = 0
|
||||||
total_notes_ok = 0
|
total_notes_ok = 0
|
||||||
for n in notes:
|
for n in notes:
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,60 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
scripts/wp04_smoketest.py — E2E-Schnelltest der WP-04 Endpunkte
|
FILE: scripts/wp04_smoketest.py
|
||||||
|
VERSION: 2.1.0 (2025-12-15)
|
||||||
|
STATUS: Active (Test-Tool)
|
||||||
|
COMPATIBILITY: v2.9.1 (Post-WP14/WP-15b)
|
||||||
|
|
||||||
Zweck:
|
Zweck:
|
||||||
- Holt exemplarisch einen Vektor aus {prefix}_chunks (falls verfügbar),
|
-------
|
||||||
- ruft POST /query mit diesem Vektor auf,
|
E2E-Schnelltest der WP-04 Endpunkte (/query und /graph).
|
||||||
- ruft GET /graph/<note_id> für die Top-Note auf,
|
Validiert grundlegende Funktionalität der Retrieval- und Graph-APIs.
|
||||||
- druckt Kurzresultate auf STDOUT.
|
|
||||||
|
|
||||||
Kompatibilität:
|
Funktionsweise:
|
||||||
Python 3.12+, requests, qdrant-client
|
---------------
|
||||||
Version:
|
1. Holt exemplarischen Chunk-Vektor aus Qdrant
|
||||||
0.1.0 (Erstanlage)
|
2. Ruft POST /query mit Test-Query auf
|
||||||
Stand:
|
3. Ruft GET /graph/<note_id> für Top-Note auf
|
||||||
2025-10-07
|
4. Gibt Kurzresultate aus
|
||||||
Bezug:
|
|
||||||
WP-04 /query & /graph
|
Ergebnis-Interpretation:
|
||||||
Nutzung:
|
------------------------
|
||||||
export QDRANT_URL="http://localhost:6333"
|
- Ausgabe: Test-Ergebnisse
|
||||||
export MINDNET_PREFIX="mindnet"
|
* query_result: Ergebnis des /query Aufrufs
|
||||||
|
* graph_result: Ergebnis des /graph Aufrufs
|
||||||
|
* status: ok/error
|
||||||
|
- Exit-Code 0: Alle Tests bestanden
|
||||||
|
- Exit-Code 1: Fehler (z.B. API nicht erreichbar, keine Daten)
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
-----------
|
||||||
|
- Schnelle Validierung nach Deployment
|
||||||
|
- CI/CD-Tests
|
||||||
|
- Debugging von API-Problemen
|
||||||
|
|
||||||
|
Hinweise:
|
||||||
|
---------
|
||||||
|
- Benötigt vorhandene Daten in Qdrant
|
||||||
|
- Testet nur grundlegende Funktionalität
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
-------
|
||||||
python3 scripts/wp04_smoketest.py --api http://localhost:8000
|
python3 scripts/wp04_smoketest.py --api http://localhost:8000
|
||||||
Änderungsverlauf:
|
|
||||||
0.1.0 (2025-10-07) – Erstanlage.
|
Parameter:
|
||||||
|
----------
|
||||||
|
--api URL Base-URL der mindnet API (Default: http://localhost:8000)
|
||||||
|
|
||||||
|
Umgebungsvariablen:
|
||||||
|
-------------------
|
||||||
|
QDRANT_URL (Default: http://localhost:6333)
|
||||||
|
MINDNET_PREFIX (Default: mindnet)
|
||||||
|
|
||||||
|
Änderungen:
|
||||||
|
-----------
|
||||||
|
v2.1.0 (2025-12-15): Dokumentation aktualisiert
|
||||||
|
v0.1.0 (2025-10-07): Initial Release
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user