Overview
This workflow runs on a cron schedule to test every search tool your agents depend on. It sends known-good queries to each platform, validates the response schema, measures latency, and fires alerts when a tool degrades or fails. The goal is to catch tool failures before your agents do, so users never experience a broken search fallback.
Trigger
Cron schedule (every hour)
Schedule
Runs every hour via cron
Workflow Steps
Define test fixtures
Load a set of known-good queries for each platform that should always return results.
Execute health checks
Call the Scavio API for each platform with the test query and record status code, latency, and result count.
Validate response schema
Check that required fields (organic, status) exist and that result counts are above zero for known-good queries.
Compare against thresholds
Flag any tool where latency exceeds 5 seconds, result count is zero, or status code is not 200.
Send alert on degradation
Push a formatted alert to Slack or PagerDuty with the degraded tool name, failure type, and timestamp.
Log results for trending
Append results to a JSON log for historical latency and availability trending.
Python Implementation
import requests
import json
import time
from pathlib import Path
from datetime import datetime
API_KEY = "your_scavio_api_key"
SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
HEALTH_CHECKS = {
"google": "python programming",
"youtube": "coding tutorial",
"amazon": "bluetooth headphones",
"walmart": "paper towels",
"reddit": "programming advice",
}
LATENCY_THRESHOLD_MS = 5000
def check_platform(platform: str, query: str) -> dict:
start = time.time()
try:
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": platform, "query": query},
timeout=15,
)
latency_ms = int((time.time() - start) * 1000)
if res.status_code != 200:
return {"platform": platform, "status": "error", "code": res.status_code, "latency_ms": latency_ms}
data = res.json()
result_count = len(data.get("organic", []))
healthy = result_count > 0 and latency_ms < LATENCY_THRESHOLD_MS
return {
"platform": platform,
"status": "healthy" if healthy else "degraded",
"result_count": result_count,
"latency_ms": latency_ms,
}
except requests.exceptions.Timeout:
return {"platform": platform, "status": "timeout", "latency_ms": 15000}
except Exception as e:
return {"platform": platform, "status": "exception", "error": str(e)}
def send_alert(unhealthy: list[dict]):
message = f"Search Tool Health Alert - {len(unhealthy)} tools degraded:\n"
for item in unhealthy:
message += f" {item['platform']}: {item['status']} (latency: {item.get('latency_ms', 'N/A')}ms)\n"
requests.post(SLACK_WEBHOOK, json={"text": message}, timeout=10)
def run():
results = []
for platform, query in HEALTH_CHECKS.items():
result = check_platform(platform, query)
results.append(result)
unhealthy = [r for r in results if r["status"] != "healthy"]
if unhealthy:
send_alert(unhealthy)
print(f"ALERT: {len(unhealthy)} tools degraded")
else:
print(f"All {len(results)} tools healthy")
# Log for historical trending
log_path = Path("health_log.jsonl")
with log_path.open("a") as f:
f.write(json.dumps({"timestamp": datetime.utcnow().isoformat(), "results": results}) + "\n")
if __name__ == "__main__":
run()JavaScript Implementation
const API_KEY = "your_scavio_api_key";
const SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";
const HEALTH_CHECKS = {
google: "python programming",
youtube: "coding tutorial",
amazon: "bluetooth headphones",
walmart: "paper towels",
reddit: "programming advice",
};
const LATENCY_THRESHOLD_MS = 5000;
async function checkPlatform(platform, query) {
const start = Date.now();
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 15000);
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: { "x-api-key": API_KEY, "content-type": "application/json" },
body: JSON.stringify({ platform, query }),
signal: controller.signal,
});
clearTimeout(timeout);
const latencyMs = Date.now() - start;
if (!res.ok) return { platform, status: "error", code: res.status, latencyMs };
const data = await res.json();
const resultCount = (data.organic ?? []).length;
const healthy = resultCount > 0 && latencyMs < LATENCY_THRESHOLD_MS;
return { platform, status: healthy ? "healthy" : "degraded", resultCount, latencyMs };
} catch (err) {
return { platform, status: err.name === "AbortError" ? "timeout" : "exception", latencyMs: Date.now() - start };
}
}
async function sendAlert(unhealthy) {
const message = `Search Tool Health Alert - ${unhealthy.length} tools degraded:\n` +
unhealthy.map((i) => ` ${i.platform}: ${i.status} (latency: ${i.latencyMs ?? "N/A"}ms)`).join("\n");
await fetch(SLACK_WEBHOOK, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ text: message }),
});
}
async function run() {
const results = await Promise.all(
Object.entries(HEALTH_CHECKS).map(([platform, query]) => checkPlatform(platform, query))
);
const unhealthy = results.filter((r) => r.status !== "healthy");
if (unhealthy.length) {
await sendAlert(unhealthy);
console.log(`ALERT: ${unhealthy.length} tools degraded`);
} else {
console.log(`All ${results.length} tools healthy`);
}
// Log for historical trending
const fs = await import("fs/promises");
const entry = JSON.stringify({ timestamp: new Date().toISOString(), results }) + "\n";
await fs.appendFile("health_log.jsonl", entry);
}
run();Platforms Used
Web search with knowledge graph, PAA, and AI overviews
YouTube
Video search with transcripts and metadata
Amazon
Product search with prices, ratings, and reviews
Walmart
Product search with pricing and fulfillment data
Community, posts & threaded comments from any subreddit