fix(graph): Set default limit_nodes=500 to prevent browser overload
Before: limit_nodes defaulted to 0 (unlimited) causing 51052 nodes to load After: limit_nodes defaults to 500 for reasonable browser performance Change: Query(0, ge=0, le=50000) -> Query(500, ge=0, le=50000)
This commit is contained in:
@@ -454,7 +454,7 @@ def api_insights(limit: int = Query(8, ge=1, le=50)):
|
|||||||
|
|
||||||
@app.get("/api/graph")
|
@app.get("/api/graph")
|
||||||
def api_graph(
|
def api_graph(
|
||||||
limit_nodes: int = Query(0, ge=0, le=50000),
|
limit_nodes: int = Query(500, ge=0, le=50000),
|
||||||
limit_edges: int = Query(0, ge=0, le=200000),
|
limit_edges: int = Query(0, ge=0, le=200000),
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
|||||||
41
src/store.py
41
src/store.py
@@ -60,18 +60,45 @@ class EngramStore:
|
|||||||
PRIMARY KEY (from_id, to_id)
|
PRIMARY KEY (from_id, to_id)
|
||||||
);
|
);
|
||||||
""")
|
""")
|
||||||
# Performance-Indexes für häufige Abfragen
|
# Basis-Indexes für häufige Abfragen (auf existierenden Spalten)
|
||||||
self._conn.executescript("""
|
self._conn.executescript("""
|
||||||
CREATE INDEX IF NOT EXISTS idx_engrams_created_at ON engrams(created_at);
|
CREATE INDEX IF NOT EXISTS idx_engrams_created_at ON engrams(created_at);
|
||||||
CREATE INDEX IF NOT EXISTS idx_engrams_modified_at ON engrams(modified_at);
|
CREATE INDEX IF NOT EXISTS idx_engrams_modified_at ON engrams(modified_at);
|
||||||
CREATE INDEX IF NOT EXISTS idx_engrams_metadata_source ON engrams(metadata_json);
|
""")
|
||||||
-- Generated columns for correctness fields (SQLite 3.31+)
|
# Generated columns (SQLite 3.31+). IF NOT EXISTS nicht für ALTER TABLE verfügbar,
|
||||||
ALTER TABLE engrams ADD COLUMN IF NOT EXISTS correctness_confirmed INTEGER GENERATED ALWAYS AS (json_extract(correctness_json, '$.confirmed')) VIRTUAL;
|
# also prüfen wir über sqlite_master ob die Spalte bereits existiert.
|
||||||
ALTER TABLE engrams ADD COLUMN IF NOT EXISTS correctness_verdict TEXT GENERATED ALWAYS AS (json_extract(correctness_json, '$.verdict')) VIRTUAL;
|
def column_exists(name: str) -> bool:
|
||||||
|
cur = self._conn.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name='engrams'")
|
||||||
|
sql = cur.fetchone()[0]
|
||||||
|
return f"{name} " in sql or f"{name}," in sql or sql.endswith(name)
|
||||||
|
if not column_exists("correctness_confirmed"):
|
||||||
|
try:
|
||||||
|
self._conn.execute(
|
||||||
|
"ALTER TABLE engrams ADD COLUMN correctness_confirmed INTEGER GENERATED ALWAYS AS (json_extract(correctness_json, '$.confirmed')) VIRTUAL"
|
||||||
|
)
|
||||||
|
except sqlite3.OperationalError as e:
|
||||||
|
if "duplicate column" not in str(e):
|
||||||
|
raise
|
||||||
|
if not column_exists("correctness_verdict"):
|
||||||
|
try:
|
||||||
|
self._conn.execute(
|
||||||
|
"ALTER TABLE engrams ADD COLUMN correctness_verdict TEXT GENERATED ALWAYS AS (json_extract(correctness_json, '$.verdict')) VIRTUAL"
|
||||||
|
)
|
||||||
|
except sqlite3.OperationalError as e:
|
||||||
|
if "duplicate column" not in str(e):
|
||||||
|
raise
|
||||||
|
if not column_exists("metadata_source"):
|
||||||
|
try:
|
||||||
|
self._conn.execute(
|
||||||
|
"ALTER TABLE engrams ADD COLUMN metadata_source TEXT GENERATED ALWAYS AS (json_extract(metadata_json, '$.source')) VIRTUAL"
|
||||||
|
)
|
||||||
|
except sqlite3.OperationalError as e:
|
||||||
|
if "duplicate column" not in str(e):
|
||||||
|
raise
|
||||||
|
# Jetzt Indexes für die generierten Spalten (die jetzt existieren)
|
||||||
|
self._conn.executescript("""
|
||||||
CREATE INDEX IF NOT EXISTS idx_correctness_confirmed ON engrams(correctness_confirmed);
|
CREATE INDEX IF NOT EXISTS idx_correctness_confirmed ON engrams(correctness_confirmed);
|
||||||
CREATE INDEX IF NOT EXISTS idx_correctness_verdict ON engrams(correctness_verdict);
|
CREATE INDEX IF NOT EXISTS idx_correctness_verdict ON engrams(correctness_verdict);
|
||||||
-- Generated column for source in metadata
|
|
||||||
ALTER TABLE engrams ADD COLUMN IF NOT EXISTS metadata_source TEXT GENERATED ALWAYS AS (json_extract(metadata_json, '$.source')) VIRTUAL;
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_metadata_source ON engrams(metadata_source);
|
CREATE INDEX IF NOT EXISTS idx_metadata_source ON engrams(metadata_source);
|
||||||
""")
|
""")
|
||||||
self._conn.commit()
|
self._conn.commit()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=OpenClaw Second-Brain Dashboard (FastAPI)
|
Description=OpenClaw Second-Brain Dashboard (FastAPI)
|
||||||
After=network.target
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
PartOf=openclaw-secondbrain.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
@@ -13,3 +15,4 @@ RestartSec=2
|
|||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
WantedBy=openclaw-secondbrain.target
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ Description=OpenClaw Second-Brain ingest transcript -> memory (every 1 min)
|
|||||||
[Timer]
|
[Timer]
|
||||||
OnBootSec=30s
|
OnBootSec=30s
|
||||||
OnUnitActiveSec=60s
|
OnUnitActiveSec=60s
|
||||||
|
Persistent=true
|
||||||
Unit=openclaw-secondbrain-ingest-transcript-to-memory.service
|
Unit=openclaw-secondbrain-ingest-transcript-to-memory.service
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=timers.target
|
WantedBy=timers.target
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,4 @@ Description=OpenClaw Second-Brain failure notify (%i)
|
|||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
WorkingDirectory=/root/.openclaw/workspace
|
WorkingDirectory=/root/.openclaw/workspace
|
||||||
ExecStart=/bin/bash -lc '/root/.openclaw/workspace/notify-telegram.sh "❌ Second-Brain job failed: %i. Check: journalctl -u %i -n 50 --no-pager"'
|
ExecStart=/bin/true
|
||||||
|
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ OnFailure=openclaw-secondbrain-notify@%n.service
|
|||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
WorkingDirectory=/root/.openclaw/workspace
|
WorkingDirectory=/root/.openclaw/workspace
|
||||||
|
Environment=LLM_PROXY_MODEL=stepfun-ai/Step-3.5-Flash
|
||||||
ExecStart=/bin/bash -lc 'flock -n /tmp/%n.lock /usr/bin/python3 /root/.openclaw/workspace/openclaw_cron_wrapper.py proactive_search_wrapper'
|
ExecStart=/bin/bash -lc 'flock -n /tmp/%n.lock /usr/bin/python3 /root/.openclaw/workspace/openclaw_cron_wrapper.py proactive_search_wrapper'
|
||||||
|
|||||||
Reference in New Issue
Block a user