From afc0420892588fe0b019957285eebf92818c6912 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:21:10 +0000 Subject: [PATCH 1/4] Add production workflow for updated run --- .github/workflows/production-workflow.yml | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/production-workflow.yml diff --git a/.github/workflows/production-workflow.yml b/.github/workflows/production-workflow.yml new file mode 100644 index 0000000..073d6d0 --- /dev/null +++ b/.github/workflows/production-workflow.yml @@ -0,0 +1,29 @@ +name: Production Workflow + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: production-workflow + cancel-in-progress: true + +jobs: + production-check: + name: Run production workflow + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Verify key production assets + run: | + test -f index.html + test -f robots.txt + test -f sitemap.xml From 3e616709c86b49c490dca794fa77933334cc5440 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:21:57 +0000 Subject: [PATCH 2/4] Refine production workflow reliability --- .github/workflows/production-workflow.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/production-workflow.yml b/.github/workflows/production-workflow.yml index 073d6d0..f632d35 100644 --- a/.github/workflows/production-workflow.yml +++ b/.github/workflows/production-workflow.yml @@ -10,7 +10,7 @@ permissions: contents: read concurrency: - group: production-workflow + group: production-workflow-${{ github.ref }} cancel-in-progress: true jobs: @@ -24,6 +24,6 @@ jobs: - name: Verify key production assets run: | - test -f index.html - test -f robots.txt - test -f sitemap.xml + test -f index.html || { echo "Missing required file: index.html"; exit 1; } + test -f robots.txt || { echo "Missing required file: robots.txt"; exit 1; } + test -f sitemap.xml || { echo "Missing required file: sitemap.xml"; exit 1; } From 2cc3171b04032e05c9284261a7d0caad5177b2b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 22:22:23 +0000 Subject: [PATCH 3/4] Improve production workflow failure messages --- .github/workflows/production-workflow.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/production-workflow.yml b/.github/workflows/production-workflow.yml index f632d35..a4674f7 100644 --- a/.github/workflows/production-workflow.yml +++ b/.github/workflows/production-workflow.yml @@ -24,6 +24,6 @@ jobs: - name: Verify key production assets run: | - test -f index.html || { echo "Missing required file: index.html"; exit 1; } - test -f robots.txt || { echo "Missing required file: robots.txt"; exit 1; } - test -f sitemap.xml || { echo "Missing required file: sitemap.xml"; exit 1; } + test -f index.html || { echo "Production check failed: missing /index.html at repository root."; exit 1; } + test -f robots.txt || { echo "Production check failed: missing /robots.txt at repository root."; exit 1; } + test -f sitemap.xml || { echo "Production check failed: missing /sitemap.xml at repository root."; exit 1; } From 5afcb9b48e9d514e101bc19c06934fd72d386e82 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:08:59 +0000 Subject: [PATCH 4/4] Bring HAI workflow, script, and cached DB to main --- .github/workflows/hai-agent-check.yml | 31 +++++++ .gitignore | 2 + data/hai_cache.db | Bin 0 -> 12288 bytes scripts/run_hai_agent.py | 119 ++++++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 .github/workflows/hai-agent-check.yml create mode 100644 .gitignore create mode 100644 data/hai_cache.db create mode 100644 scripts/run_hai_agent.py diff --git a/.github/workflows/hai-agent-check.yml b/.github/workflows/hai-agent-check.yml new file mode 100644 index 0000000..1be54a9 --- /dev/null +++ b/.github/workflows/hai-agent-check.yml @@ -0,0 +1,31 @@ +name: HAI Agent Branch Check + +on: + push: + branches: + - "**" + pull_request: + branches: + - "**" + workflow_dispatch: + +jobs: + run-hai-agent: + if: github.event_name != 'push' || startsWith(github.ref, 'refs/heads/') + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Run HAI agent with cache fallback + env: + HAI_SOURCE_URL: ${{ vars.HAI_SOURCE_URL }} + run: python scripts/run_hai_agent.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a60b85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.pyc diff --git a/data/hai_cache.db b/data/hai_cache.db new file mode 100644 index 0000000000000000000000000000000000000000..76a7ccc8240847050d0a82336aa1536728e2de36 GIT binary patch literal 12288 zcmeI&%SyvQ6b9g#)C&q)H{y24rj=e8q81Ezi4vrk)>2?t;D45q=FO|y7MJ` zLh%`#DlVc6H;SA8kV$gpl8|qAhMb*x{Y0{>cyuEYwn0`1rDUHmLWrSTMz_zP`ex=c z(bsAIQy8Rt`?REI8OtvuyQ@zK2tWV=5P$##AOHafKmY;|fWRLMG>o~mLV>mt(Fvs* zhPv==D>)p?sQWd|95!9YcbV@TcrN=gHy?=`S=1}nANJ_{S}sQ)cix}b6aBV|#6b1p zM5PiV^}N&&%P%t44_LMCyGL%5HJa6$(`>P0x5b=u|D;;iYin-ZFY0+C*^Nhm4BEO_ z_uUJh)lYOg_q^$#ipQg_{N6thcVR4o_O*(m^yuRHv^J;NXQB@T1Rwwb2tWV=5P$## zAOHafKmY>&B5+A(No{pvajR0|m6B!omSt~ndyAL(Cg+vS0_Qg8O3GkjzV9mN?Ez`p z)>e7DXojLAL(?`pLdmcnNwa9GL?mOS`=(1|VBUY!|F0zb`Y#`dmqGvn5P$##AOHaf XKmY;|fB*y_@aqCAG?QCM{eAET-C>48 literal 0 HcmV?d00001 diff --git a/scripts/run_hai_agent.py b/scripts/run_hai_agent.py new file mode 100644 index 0000000..283feb5 --- /dev/null +++ b/scripts/run_hai_agent.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +"""Run HAI agent with network-first mode and SQLite cache fallback.""" + +from __future__ import annotations + +import json +import os +import sqlite3 +import sys +import urllib.error +import urllib.request +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + + +REPO_ROOT = Path(__file__).resolve().parents[1] +DEFAULT_DB_PATH = REPO_ROOT / "data" / "hai_cache.db" + + +def ensure_cache_schema(connection: sqlite3.Connection) -> None: + connection.execute( + """ + CREATE TABLE IF NOT EXISTS hai_snapshots ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + recorded_at TEXT NOT NULL, + source TEXT NOT NULL, + payload_json TEXT NOT NULL + ) + """ + ) + connection.commit() + + +def fetch_live_payload(url: str, timeout: int) -> dict[str, Any]: + request = urllib.request.Request( + url, + headers={"Accept": "application/json", "User-Agent": "pollnex-hai-agent/1.0"}, + ) + with urllib.request.urlopen(request, timeout=timeout) as response: + body = response.read().decode("utf-8") + parsed = json.loads(body) + if isinstance(parsed, dict): + return parsed + return {"value": parsed} + + +def save_snapshot(connection: sqlite3.Connection, source: str, payload: dict[str, Any]) -> None: + connection.execute( + """ + INSERT INTO hai_snapshots (recorded_at, source, payload_json) + VALUES (?, ?, ?) + """, + ( + datetime.now(timezone.utc).isoformat(), + source, + json.dumps(payload, sort_keys=True, separators=(",", ":")), + ), + ) + connection.commit() + + +def load_latest_snapshot(connection: sqlite3.Connection) -> dict[str, Any] | None: + row = connection.execute( + """ + SELECT payload_json + FROM hai_snapshots + ORDER BY id DESC + LIMIT 1 + """ + ).fetchone() + if not row: + return None + return json.loads(row[0]) + + +def normalize_payload(payload: dict[str, Any]) -> dict[str, Any]: + normalized = dict(payload) + if "hai_score" not in normalized and "score" in normalized: + normalized["hai_score"] = normalized["score"] + return normalized + + +def main() -> int: + db_path = Path(os.getenv("HAI_CACHE_DB", str(DEFAULT_DB_PATH))) + source_url = os.getenv("HAI_SOURCE_URL", "").strip() + timeout_seconds = int(os.getenv("HAI_REQUEST_TIMEOUT_SECONDS", "8")) + + db_path.parent.mkdir(parents=True, exist_ok=True) + with sqlite3.connect(db_path) as connection: + ensure_cache_schema(connection) + + runtime_mode = "cached" + payload: dict[str, Any] | None = None + + if source_url: + try: + payload = normalize_payload(fetch_live_payload(source_url, timeout_seconds)) + save_snapshot(connection, "network", payload) + runtime_mode = "network" + except (urllib.error.URLError, TimeoutError, OSError, json.JSONDecodeError) as error: + print(f"[WARN] Network source unavailable, falling back to cached DB: {error}") + + if payload is None: + payload = load_latest_snapshot(connection) + if payload is None: + print( + "[ERROR] No cached HAI snapshot found and network source is unavailable.", + file=sys.stderr, + ) + return 1 + + print(f"[INFO] HAI agent runtime mode: {runtime_mode}") + print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())