From 9412d0981bac35a6c689567d2fbc51fc321ebf87 Mon Sep 17 00:00:00 2001 From: krypticmouse Date: Thu, 26 Mar 2026 19:44:37 +0000 Subject: [PATCH] feat: add POST /v1/connectors/{id}/sync to trigger incremental sync Adds a new POST /{connector_id}/sync endpoint alongside the existing GET sync-status endpoint. The new endpoint validates the connector is registered and connected, then runs SyncEngine.sync() and returns chunks_indexed. Co-Authored-By: Claude Sonnet 4.6 --- src/openjarvis/server/connectors_router.py | 27 ++++++++++++++++++++++ tests/server/test_connectors_router.py | 14 +++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/openjarvis/server/connectors_router.py b/src/openjarvis/server/connectors_router.py index b75b53c6..58eefd96 100644 --- a/src/openjarvis/server/connectors_router.py +++ b/src/openjarvis/server/connectors_router.py @@ -236,6 +236,33 @@ def create_connectors_router(): "status": "disconnected", } + @router.post("/{connector_id}/sync") + def trigger_sync(connector_id: str) -> Dict[str, Any]: + """Trigger an incremental sync for a connector.""" + _ensure_connectors_registered() + if not ConnectorRegistry.contains(connector_id): + raise HTTPException( + status_code=404, + detail=f"Connector '{connector_id}' not found", + ) + inst = _get_or_create(connector_id) + if not inst.is_connected(): + raise HTTPException( + status_code=400, + detail=f"Connector '{connector_id}' is not connected", + ) + + from openjarvis.connectors.pipeline import IngestionPipeline + from openjarvis.connectors.store import KnowledgeStore + from openjarvis.connectors.sync_engine import SyncEngine + + store = KnowledgeStore() + pipeline = IngestionPipeline(store=store) + engine = SyncEngine(pipeline=pipeline) + chunks = engine.sync(inst) + + return {"connector_id": connector_id, "chunks_indexed": chunks, "status": "complete"} + @router.get("/{connector_id}/sync") async def sync_status(connector_id: str): """Return the current sync status for a connector.""" diff --git a/tests/server/test_connectors_router.py b/tests/server/test_connectors_router.py index 26af63d8..6ff2db3e 100644 --- a/tests/server/test_connectors_router.py +++ b/tests/server/test_connectors_router.py @@ -2,6 +2,8 @@ from __future__ import annotations +from pathlib import Path + import pytest @@ -78,3 +80,15 @@ def test_sync_status(app): data = resp.json() assert "state" in data assert data["connector_id"] == "obsidian" + + +def test_trigger_sync(app, tmp_path: Path) -> None: + """POST /v1/connectors/obsidian/sync triggers an incremental sync.""" + vault = tmp_path / "vault" + vault.mkdir() + (vault / "note.md").write_text("# Test note\n\nContent here.") + app.post("/v1/connectors/obsidian/connect", json={"path": str(vault)}) + resp = app.post("/v1/connectors/obsidian/sync") + assert resp.status_code == 200 + data = resp.json() + assert data["chunks_indexed"] >= 1