"""InvalidateCacheTool -- clear validation cache for a subject. Wraps the KV API ``/api/truth/subjects/:subject/invalidate`` endpoint, which clears all cached validation results for a specific subject (e.g., "economics", "terminology", "safety"). """ from __future__ import annotations import os from typing import Any, ClassVar import httpx from ..base import Tool, ToolParameter, ToolResult # Read from KV_API_URL environment variable, fallback to localhost _DEFAULT_KV_API_URL = os.environ.get("KV_API_URL", "http://localhost:41233") _REQUEST_TIMEOUT = 30.0 class InvalidateCacheTool(Tool): """Clear validation cache for a specific subject. Forces revalidation of all content related to a subject by clearing the cache. Use this after updating documentation for a subject to ensure that subsequent validations reflect the latest knowledge. """ name: ClassVar[str] = "invalidate_cache" description: ClassVar[str] = ( "Clear validation cache for a specific subject (e.g., 'economics', " "'terminology', 'safety'). Forces fresh validation on next check. " "Use this after updating documentation to ensure validations reflect " "the latest knowledge base state." ) parameters: ClassVar[list[ToolParameter]] = [ ToolParameter( name="subject", type="string", description=( "Subject identifier to invalidate (e.g., 'economics', 'terminology', " "'safety', 'competitors', 'jurisdiction'). Matches the subject " "categories used in content validation." ), ), ToolParameter( name="kv_api_url", type="string", description="KV API base URL", required=False, default=_DEFAULT_KV_API_URL, ), ] async def execute(self, **kwargs: Any) -> ToolResult: subject: str = kwargs["subject"] kv_api_url: str = kwargs.get("kv_api_url", _DEFAULT_KV_API_URL) if not subject: return ToolResult.fail("Subject identifier is required") async with httpx.AsyncClient( base_url=kv_api_url, timeout=_REQUEST_TIMEOUT ) as client: try: resp = await client.post( f"/api/truth/subjects/{subject}/invalidate", json={}, ) except httpx.ConnectError: return ToolResult.fail( f"Cannot connect to KV API at {kv_api_url}. " "Start it with: cd codebase/tools/platform-knowledge-ai && ./run start" ) except httpx.TimeoutException: return ToolResult.fail( f"Cache invalidation timed out after {_REQUEST_TIMEOUT}s" ) if resp.status_code == 404: return ToolResult.fail( f"Subject '{subject}' not found. Available subjects are determined " "by the content classification system." ) if resp.status_code == 400: error_data = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {} error_msg = error_data.get("error", "Invalid request") return ToolResult.fail(f"Bad request: {error_msg}") if resp.status_code >= 500: return ToolResult.fail( f"KV API internal error (HTTP {resp.status_code}). " "Check service logs for details." ) if resp.status_code != 200: return ToolResult.fail( f"KV API returned unexpected status {resp.status_code}" ) data = resp.json() success = data.get("success", False) if not success: return ToolResult.fail( f"Cache invalidation for subject '{subject}' failed. " "Check KV API logs for details." ) keys_invalidated = data.get("keysInvalidated", 0) affected_locale_files = data.get("affectedLocaleFiles", []) return ToolResult.success( { "subject": subject, "keys_invalidated": keys_invalidated, "affected_locale_files": affected_locale_files, "success": True, }, subject=subject, keys_invalidated=keys_invalidated, )