mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(tests): CI runner-pod env parity
Test fixes for ARC runner pods (containers) vs GHA ubuntu-latest VMs: - test_gateway_wsl / test_copilot_acp_client: pin is_container=False on host-behavior tests — runner pods ARE containers and the prod code intentionally behaves differently there. Also drop inherited HERMES_REAL_HOME so nix dev shells don't leak into the assert. - honcho memo + skill-utils external-dirs cache: add st_size to the mtime_ns cache keys. overlayfs (runner pods) coalesces rapid writes into one mtime tick, so same-tick edits were served stale (3 honcho pin tests + skill cache invalidation test). Verified with KUBERNETES_SERVICE_HOST set to simulate the pod env.
This commit is contained in:
parent
5e936e8d71
commit
ede14b2426
2 changed files with 14 additions and 8 deletions
|
|
@ -471,7 +471,7 @@ def _normalize_string_set(values) -> Set[str]:
|
|||
# which becomes the dominant cost of ``hermes`` startup when ~120 skills
|
||||
# each trigger a category lookup during banner construction (10+ seconds
|
||||
# of pure waste).
|
||||
_EXTERNAL_DIRS_CACHE: Dict[Tuple[str, int], List[Path]] = {}
|
||||
_EXTERNAL_DIRS_CACHE: Dict[Tuple[str, int, int], List[Path]] = {}
|
||||
|
||||
|
||||
def _external_dirs_cache_clear() -> None:
|
||||
|
|
@ -496,11 +496,13 @@ def get_external_skills_dirs() -> List[Path]:
|
|||
if not config_path.exists():
|
||||
return []
|
||||
|
||||
# Cache key: (absolute path, mtime_ns). stat() is ~2us vs ~85ms for
|
||||
# the full YAML parse, so the fast path is nearly free.
|
||||
# Cache key: (absolute path, mtime_ns, size). stat() is ~2us vs ~85ms
|
||||
# for the full YAML parse, so the fast path is nearly free. Size is in
|
||||
# the key because overlayfs (CI runner pods) can coalesce rapid writes
|
||||
# into a single mtime_ns tick.
|
||||
try:
|
||||
stat = config_path.stat()
|
||||
cache_key: Tuple[str, int] = (str(config_path), stat.st_mtime_ns)
|
||||
cache_key: Tuple[str, int, int] = (str(config_path), stat.st_mtime_ns, stat.st_size)
|
||||
except OSError:
|
||||
cache_key = None # type: ignore[assignment]
|
||||
|
||||
|
|
|
|||
|
|
@ -21427,7 +21427,7 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
|
|||
"honcho.runtime_peer_prefix",
|
||||
"honcho.user_peer_aliases",
|
||||
)
|
||||
_HONCHO_CACHE_BUSTING_MEMO: dict[tuple[str, int | None], dict[str, Any]] = {}
|
||||
_HONCHO_CACHE_BUSTING_MEMO: dict[tuple[str, tuple[int, int] | None], dict[str, Any]] = {}
|
||||
|
||||
@classmethod
|
||||
def _empty_honcho_cache_busting_config(cls) -> dict[str, Any]:
|
||||
|
|
@ -21441,10 +21441,14 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
|
|||
|
||||
path = resolve_config_path()
|
||||
try:
|
||||
mtime_ns = path.stat().st_mtime_ns
|
||||
st = path.stat()
|
||||
# mtime alone is not enough: overlayfs (CI runner pods)
|
||||
# coalesces rapid writes into one mtime_ns tick. Size joins
|
||||
# the key so a same-tick content change still re-parses.
|
||||
stat_sig = (st.st_mtime_ns, st.st_size)
|
||||
except OSError:
|
||||
mtime_ns = None
|
||||
memo_key = (str(path), mtime_ns)
|
||||
stat_sig = None
|
||||
memo_key = (str(path), stat_sig)
|
||||
cached = cls._HONCHO_CACHE_BUSTING_MEMO.get(memo_key)
|
||||
if cached is not None:
|
||||
return dict(cached)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue