Restrict recent-activity feedType to user|org; document following limitation
Browse files
.fast-agent/tool-cards/hf_api_tool.py
CHANGED
|
@@ -46,7 +46,10 @@ ALLOWED_ENDPOINT_PATTERNS: list[str] = [
|
|
| 46 |
r"^/collections/[^/]+/items$",
|
| 47 |
# Auth check
|
| 48 |
r"^/(models|datasets|spaces)/[^/]+/[^/]+/auth-check$",
|
| 49 |
-
# Recent activity feed (undocumented)
|
|
|
|
|
|
|
|
|
|
| 50 |
r"^/recent-activity$",
|
| 51 |
]
|
| 52 |
|
|
@@ -161,6 +164,44 @@ def _build_url(endpoint: str, params: dict[str, Any] | None) -> str:
|
|
| 161 |
return url
|
| 162 |
|
| 163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
def _request_once(
|
| 165 |
*,
|
| 166 |
url: str,
|
|
@@ -426,6 +467,7 @@ Returns:
|
|
| 426 |
raise ValueError("max_pages must be >= 1.")
|
| 427 |
|
| 428 |
req_params = dict(params or {})
|
|
|
|
| 429 |
url = _build_url(endpoint, req_params)
|
| 430 |
status_code, payload = _request_once(
|
| 431 |
url=url,
|
|
|
|
| 46 |
r"^/collections/[^/]+/items$",
|
| 47 |
# Auth check
|
| 48 |
r"^/(models|datasets|spaces)/[^/]+/[^/]+/auth-check$",
|
| 49 |
+
# Recent activity feed (undocumented).
|
| 50 |
+
# Note: this tool intentionally supports only `feedType=user|org` in params.
|
| 51 |
+
# `feedType=following` requires cookie/session auth in practice and is blocked
|
| 52 |
+
# with a clear error before making a network request.
|
| 53 |
r"^/recent-activity$",
|
| 54 |
]
|
| 55 |
|
|
|
|
| 164 |
return url
|
| 165 |
|
| 166 |
|
| 167 |
+
def _validate_recent_activity_params(endpoint: str, params: dict[str, Any]) -> None:
|
| 168 |
+
"""Validate /recent-activity query semantics for robust auth behavior.
|
| 169 |
+
|
| 170 |
+
We explicitly support only `feedType=user|org` with `entity`.
|
| 171 |
+
`feedType=following` is intentionally rejected because it requires browser
|
| 172 |
+
cookie/session auth and is not reliably accessible with bearer-token auth.
|
| 173 |
+
"""
|
| 174 |
+
normalized = _normalize_endpoint(endpoint)
|
| 175 |
+
if normalized != "/recent-activity":
|
| 176 |
+
return
|
| 177 |
+
|
| 178 |
+
feed_type = str(params.get("feedType", "")).strip().lower()
|
| 179 |
+
if not feed_type:
|
| 180 |
+
raise ValueError(
|
| 181 |
+
"For /recent-activity, set params.feedType to 'user' or 'org' "
|
| 182 |
+
"and include params.entity."
|
| 183 |
+
)
|
| 184 |
+
|
| 185 |
+
if feed_type == "following":
|
| 186 |
+
raise ValueError(
|
| 187 |
+
"feedType='following' is restricted (cookie/session auth only) and "
|
| 188 |
+
"is not supported by hf_api_request. Use feedType='user' or 'org'."
|
| 189 |
+
)
|
| 190 |
+
|
| 191 |
+
if feed_type not in {"user", "org"}:
|
| 192 |
+
raise ValueError(
|
| 193 |
+
f"Unsupported feedType='{feed_type}'. Supported values for "
|
| 194 |
+
"/recent-activity are 'user' and 'org'."
|
| 195 |
+
)
|
| 196 |
+
|
| 197 |
+
entity = str(params.get("entity", "")).strip()
|
| 198 |
+
if not entity:
|
| 199 |
+
raise ValueError(
|
| 200 |
+
f"For /recent-activity with feedType='{feed_type}', "
|
| 201 |
+
"params.entity is required."
|
| 202 |
+
)
|
| 203 |
+
|
| 204 |
+
|
| 205 |
def _request_once(
|
| 206 |
*,
|
| 207 |
url: str,
|
|
|
|
| 467 |
raise ValueError("max_pages must be >= 1.")
|
| 468 |
|
| 469 |
req_params = dict(params or {})
|
| 470 |
+
_validate_recent_activity_params(endpoint, req_params)
|
| 471 |
url = _build_url(endpoint, req_params)
|
| 472 |
status_code, payload = _request_once(
|
| 473 |
url=url,
|