diff --git a/projects/ops-desk/api/app/agents/runner.py b/projects/ops-desk/api/app/agents/runner.py index 5b63b95..8e26980 100644 --- a/projects/ops-desk/api/app/agents/runner.py +++ b/projects/ops-desk/api/app/agents/runner.py @@ -69,6 +69,7 @@ def run_scenario(conn, scenario_id, *, trigger="cron"): status = "ok" if not raw else "degraded" store.finish_run(conn, run_id, status=status, summary=f"{len(raw)} finding(s)" if raw else "healthy") store.log_event(conn, event_type="run.finish", message=status, run_id=run_id, agent_id=agent_id) + conn.commit() return {"ok": True, "run_id": run_id, "scenario_id": scenario_id, "status": status, "findings_count": len(raw), "finding_ids": fids} def run_all_enabled(conn, trigger="cron"): diff --git a/projects/ops-desk/api/app/agents/store.py b/projects/ops-desk/api/app/agents/store.py index ec5e9d2..d44c09c 100644 --- a/projects/ops-desk/api/app/agents/store.py +++ b/projects/ops-desk/api/app/agents/store.py @@ -1,6 +1,6 @@ """Persistence Agentic Ops.""" from __future__ import annotations -import json, sqlite3 +import json, sqlite3, time from datetime import datetime, timezone from typing import Any @@ -9,6 +9,15 @@ from app.agents.messages import init_messages_schema def _now(): return datetime.now(timezone.utc).isoformat() +def _exec_retry(conn, sql, params=(), *, attempts=8): + for attempt in range(attempts): + try: + return conn.execute(sql, params) + except sqlite3.OperationalError as exc: + if "locked" not in str(exc).lower() or attempt >= attempts - 1: + raise + time.sleep(0.25 * (attempt + 1)) + def init_agent_schema(conn): init_messages_schema(conn) conn.executescript(""" @@ -90,11 +99,12 @@ def list_action_log(conn, limit=100): return [dict(r) for r in conn.execute("SELECT * FROM agent_action_log ORDER BY id DESC LIMIT ?", (limit,))] def index_kb_file(conn, source_path, text): - conn.execute("DELETE FROM agent_kb_chunks WHERE source_path=?", (source_path,)) + _exec_retry(conn, "DELETE FROM agent_kb_chunks WHERE source_path=?", (source_path,)) now = _now() for i in range(0, len(text), 1200): - conn.execute("INSERT INTO agent_kb_chunks (source_path,chunk_text,indexed_at) VALUES (?,?,?)", + _exec_retry(conn, "INSERT INTO agent_kb_chunks (source_path,chunk_text,indexed_at) VALUES (?,?,?)", (source_path, text[i:i+1200], now)) + conn.commit() def search_kb(conn, query, limit=8): terms = [t.strip().lower() for t in query.split() if len(t.strip()) > 2] diff --git a/projects/ops-desk/api/app/main.py b/projects/ops-desk/api/app/main.py index c64b6d9..836e037 100644 --- a/projects/ops-desk/api/app/main.py +++ b/projects/ops-desk/api/app/main.py @@ -827,7 +827,7 @@ def startup(): @app.get("/api/health") def health(): redis.from_url(REDIS_URL).ping() - return {"status": "ok", "service": "ligbox-ops-api", "version": "0.9.6-spec019-023"} + return {"status": "ok", "service": "ligbox-ops-api", "version": app.version} @app.get("/api/v1/integrations")