ml-knowledge-platform/knowledge_platform/tools/builtin/invalidate_cache.py
2026-02-16 04:50:51 -08:00

124 lines
4.3 KiB
Python

"""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,
)