fix(skills): route the ClawHub owner lookup through the hub connection pool

`ClawHubSource._fetch_owner_handle` was the last one-shot GET in
tools/skills_hub*.py still calling bare `httpx.get`, so an inspect
opened a fresh connection for the owner lookup even inside
`skills_hub_http_session()`. Route it through
`hub()._skills_hub_http_get` like the models/search/github siblings;
behaviour is identical outside a session.

PROOF: the existing pool test now also calls `_fetch_owner_handle`
inside the fake `Source.inspect`; reverting the clawhub change makes it
fail with "index fetch bypassed the pool" (httpx.get is patched to
pytest.fail). grep shows no bare `httpx.get(` left in
tools/skills_hub*.py besides `_skills_hub_http_get`'s own fallback.
tests/hermes_cli/test_skills_hub.py: 12 passed.
This commit is contained in:
kshitijk4poor
2026-09-22 15:14:55 +05:30
committed by kshitij
parent fb9e90889a
commit 4036ba8c17
2 changed files with 5 additions and 2 deletions

View File

@@ -290,6 +290,7 @@ def test_inspect_reuses_one_ssrf_safe_client_for_metadata_and_bundle(monkeypatch
import hermes_cli.skills_hub as cli_hub
import tools.skills_hub as hub
import tools.skills_hub_search as search
import tools.skills_hub_clawhub as clawhub
from tools.skills_hub_models import SkillBundle, SkillMeta
clients = []
@@ -319,6 +320,8 @@ def test_inspect_reuses_one_ssrf_safe_client_for_metadata_and_bundle(monkeypatch
hub._guarded_http_get("https://example.com/metadata")
# The Hermes-index fetch must ride the same pool (no cache → real GET).
assert search._load_hermes_index() == {"skills": []}
# The ClawHub owner lookup must ride the same pool too.
assert clawhub.ClawHubSource()._fetch_owner_handle("slug") is None
return SkillMeta("example", "metadata", "test", "example/id", "community")
def fetch(self, _identifier):

View File

@@ -13,7 +13,7 @@ from agent.retry_utils import parse_retry_after_seconds
from tools.skills_hub import _guarded_http_stream
from tools.skills_hub_models import (
GuardedFetchMixin, SkillBundle, SkillMeta, SkillSource, _cache_metas, _cached_metas, _get_json,
_validate_bundle_rel_path,
_validate_bundle_rel_path, hub,
)
logger = logging.getLogger("tools.skills_hub")
@@ -381,7 +381,7 @@ class ClawHubSource(GuardedFetchMixin, SkillSource):
for attempt in range(max_attempts):
delay = 2.0 * (2 ** attempt)
try:
resp = httpx.get(url, timeout=20)
resp = hub()._skills_hub_http_get(url, timeout=20)
except (httpx.HTTPError, OSError):
reason = "transport error"
else: