Workflow

Agent Search Tool Health Check

Automated cron that tests each agent search tool endpoint, validates responses, measures latency, and alerts on failures or degradation.

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

1

Define test fixtures

Load a set of known-good queries for each platform that should always return results.

2

Execute health checks

Call the Scavio API for each platform with the test query and record status code, latency, and result count.

3

Validate response schema

Check that required fields (organic, status) exist and that result counts are above zero for known-good queries.

4

Compare against thresholds

Flag any tool where latency exceeds 5 seconds, result count is zero, or status code is not 200.

5

Send alert on degradation

Push a formatted alert to Slack or PagerDuty with the degraded tool name, failure type, and timestamp.

6

Log results for trending

Append results to a JSON log for historical latency and availability trending.

Python Implementation

Python
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

JavaScript
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

Google

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

Reddit

Community, posts & threaded comments from any subreddit

Frequently Asked Questions

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.

This workflow uses a cron schedule (every hour). Runs every hour via cron.

This workflow uses the following Scavio platforms: google, youtube, amazon, walmart, reddit. Each platform is called via the same unified API endpoint.

Yes. Scavio's free tier includes 250 credits per month with no credit card required. That is enough to test and validate this workflow before scaling it.

Agent Search Tool Health Check

Automated cron that tests each agent search tool endpoint, validates responses, measures latency, and alerts on failures or degradation.