From 56db6b9f92cc2591f3144cc77c1b6a975de1cd93 Mon Sep 17 00:00:00 2001 From: Sarthak Agrawal Date: Sat, 13 Jun 2026 11:11:35 +0530 Subject: [PATCH] =?UTF-8?q?chore:=20fix=20CI=20=E2=80=94=20ruff=20formatti?= =?UTF-8?q?ng=20and=20minio=20service=20startup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Run ruff format on 6 files that would be reformatted (infer.py, ingest_data.py, schemas.py, engine.py, search.py, qdrant_store.py). - Fix ragas-eval minio service: the minio/minio image requires `server /data` as CMD args which GitHub Actions service containers cannot pass via options. Move minio to an explicit `docker run` background step with a health-poll loop. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/eval.yml | 22 +++++++++++++++------- src/kb/api/routes/infer.py | 4 +--- src/kb/api/routes/ingest_data.py | 8 ++++++-- src/kb/api/routes/schemas.py | 8 ++++---- src/kb/query/engine.py | 3 +-- src/kb/query/search.py | 4 +++- src/kb/vector/qdrant_store.py | 6 ++---- 7 files changed, 32 insertions(+), 23 deletions(-) diff --git a/.github/workflows/eval.yml b/.github/workflows/eval.yml index 60a0185..fae86fd 100644 --- a/.github/workflows/eval.yml +++ b/.github/workflows/eval.yml @@ -26,13 +26,6 @@ jobs: qdrant: image: qdrant/qdrant:v1.12.4 ports: ["6333:6333"] - minio: - image: minio/minio:RELEASE.2024-10-13T13-34-11Z - env: - MINIO_ROOT_USER: kbminio - MINIO_ROOT_PASSWORD: kbminio-secret - ports: ["9000:9000"] - options: --health-cmd "curl -fsS http://localhost:9000/minio/health/live" --health-interval 3s --health-retries 20 steps: - uses: actions/checkout@v4 @@ -41,6 +34,21 @@ jobs: version: "0.11.17" - run: uv python install 3.11 - run: uv sync --all-extras + - name: Start MinIO + # minio/minio image requires "server /data" as the CMD argument; GitHub Actions service + # containers have no way to pass CMD args, so we start minio as a background container step. + run: | + docker run -d --name minio \ + -p 9000:9000 \ + -e MINIO_ROOT_USER=kbminio \ + -e MINIO_ROOT_PASSWORD=kbminio-secret \ + minio/minio:RELEASE.2024-10-13T13-34-11Z server /data + for i in $(seq 1 20); do + if curl -fsS http://localhost:9000/minio/health/live; then + echo "MinIO is ready"; break + fi + sleep 3 + done - name: Lint + unit tests run: | uv run ruff check src tests diff --git a/src/kb/api/routes/infer.py b/src/kb/api/routes/infer.py index cac70fa..d5610e5 100644 --- a/src/kb/api/routes/infer.py +++ b/src/kb/api/routes/infer.py @@ -139,9 +139,7 @@ async def infer_from_files( ) remaining = max(sample_count - len(samples), 0) if remaining: - samples.extend( - _sample_texts_from_elements(elements, sample_count=remaining) - ) + samples.extend(_sample_texts_from_elements(elements, sample_count=remaining)) except Exception as e: errors.append({"filename": filename, "error": str(e)}) diff --git a/src/kb/api/routes/ingest_data.py b/src/kb/api/routes/ingest_data.py index 37c4181..e8bce28 100644 --- a/src/kb/api/routes/ingest_data.py +++ b/src/kb/api/routes/ingest_data.py @@ -223,7 +223,9 @@ async def ingest_record(body: RecordIn) -> RecordOut: "is_parent": False, "source": "record", }, - content_hash=chunk_content_hash(f"record:{body.project}:{body.kind}:{body.type}:{excerpt}"), + content_hash=chunk_content_hash( + f"record:{body.project}:{body.kind}:{body.type}:{excerpt}" + ), ) ) upserted += 1 @@ -233,7 +235,9 @@ async def ingest_record(body: RecordIn) -> RecordOut: await store.delete_by_file(body.kind, file_id) await store.upsert(body.kind, chunks) except Exception as e: - await repo.set_file_status(file_id, "failed", error=f"record vector indexing failed: {e}"[:500]) + await repo.set_file_status( + file_id, "failed", error=f"record vector indexing failed: {e}"[:500] + ) raise HTTPException(503, f"record stored but vector indexing failed: {e}") from e return RecordOut( diff --git a/src/kb/api/routes/schemas.py b/src/kb/api/routes/schemas.py index 5696f6b..a95ad10 100644 --- a/src/kb/api/routes/schemas.py +++ b/src/kb/api/routes/schemas.py @@ -118,9 +118,7 @@ async def apply_draft(draft_id: str, body: ApplyDraftIn | None = None) -> dict: @router.post("/drafts/{draft_id}/discard") async def discard_draft(draft_id: str, body: DraftProjectIn | None = None) -> dict: body = body or DraftProjectIn() - row = await repo.update_schema_draft_status( - draft_id, project=body.project, status="discarded" - ) + row = await repo.update_schema_draft_status(draft_id, project=body.project, status="discarded") if not row: raise HTTPException(404, "schema draft not found") return row @@ -147,7 +145,9 @@ async def reprocess_for_active_schema(domain: str, body: ReprocessIn | None = No body = body or ReprocessIn() sch = await get_active_schema(domain, project=body.project) if not sch: - raise HTTPException(404, f"No active schema for domain '{domain}' in project '{body.project}'") + raise HTTPException( + 404, f"No active schema for domain '{domain}' in project '{body.project}'" + ) enqueued = await reindex_domain_with_schema( project=body.project, domain=domain, diff --git a/src/kb/query/engine.py b/src/kb/query/engine.py index 963271d..9bc13b7 100644 --- a/src/kb/query/engine.py +++ b/src/kb/query/engine.py @@ -679,8 +679,7 @@ def _section_score(h: Any) -> float: and ( hard_citation_gate or not ( - crag_score >= verify_skip_threshold - and confidence_value >= verify_skip_threshold + crag_score >= verify_skip_threshold and confidence_value >= verify_skip_threshold ) ) ) diff --git a/src/kb/query/search.py b/src/kb/query/search.py index a472fae..e47035f 100644 --- a/src/kb/query/search.py +++ b/src/kb/query/search.py @@ -24,7 +24,9 @@ _TOKEN_RE = re.compile(r"[A-Za-z0-9][A-Za-z0-9_-]{2,}") -def _explicit_filters(scope: dict[str, Any] | None, filters: dict[str, Any] | None) -> dict[str, Any]: +def _explicit_filters( + scope: dict[str, Any] | None, filters: dict[str, Any] | None +) -> dict[str, Any]: out: dict[str, Any] = {} if scope: for key in ("entity_id", "file_id", "parent_id"): diff --git a/src/kb/vector/qdrant_store.py b/src/kb/vector/qdrant_store.py index c301fbe..bfaf371 100644 --- a/src/kb/vector/qdrant_store.py +++ b/src/kb/vector/qdrant_store.py @@ -176,12 +176,10 @@ async def upsert(self, domain: str, chunks: list[Chunk]) -> None: collection_name=_collection(domain), scroll_filter=qm.Filter( must=[ - qm.FieldCondition( - key="project", match=qm.MatchValue(value=project) - ), + qm.FieldCondition(key="project", match=qm.MatchValue(value=project)), qm.FieldCondition( key="content_hash", match=qm.MatchAny(any=list(set(hashes))) - ) + ), ] ), limit=len(hashes) * 2,