feat: add sitecustomize import hook
This commit is contained in:
parent
a342e3fcec
commit
436104b944
91
sitecustomize_hook.py
Normal file
91
sitecustomize_hook.py
Normal file
@ -0,0 +1,91 @@
|
||||
"""
|
||||
sitecustomize hook — Claude Code OAuth bypass for hermes-agent.
|
||||
===============================================================
|
||||
|
||||
This file is installed into the hermes-agent venv's site-packages as
|
||||
``sitecustomize.py`` by ``install.sh``. It runs once at Python interpreter
|
||||
startup (before any user code) and hooks the import of
|
||||
``agent.anthropic_adapter`` so that the billing bypass patch is applied
|
||||
immediately after the module loads.
|
||||
|
||||
To disable: run ``uninstall.sh`` or delete the sitecustomize.py from the
|
||||
venv's site-packages and restart hermes-gateway.
|
||||
|
||||
DO NOT EDIT THIS FILE IN THE VENV — it will be overwritten on next install.
|
||||
Edit the source in the hermes-claude-auth repo instead.
|
||||
"""
|
||||
# hermes-claude-auth managed — do not remove this marker
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
_PATCHES_DIR = os.environ.get(
|
||||
"HERMES_PATCHES_DIR",
|
||||
os.path.expanduser("~/.hermes/patches"),
|
||||
)
|
||||
_TARGET_MODULE = "agent.anthropic_adapter"
|
||||
|
||||
if os.path.isdir(_PATCHES_DIR) and _PATCHES_DIR not in sys.path:
|
||||
sys.path.insert(0, _PATCHES_DIR)
|
||||
|
||||
|
||||
def _install_hook() -> None:
|
||||
try:
|
||||
from importlib.abc import MetaPathFinder
|
||||
from importlib.util import find_spec
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
class _ClaudeCodeBypassFinder(MetaPathFinder):
|
||||
_patched = False
|
||||
|
||||
def find_spec(self, fullname, path=None, target=None): # type: ignore[override]
|
||||
if fullname != _TARGET_MODULE or self._patched:
|
||||
return None
|
||||
|
||||
# Temporarily remove ourselves to avoid recursion during find_spec.
|
||||
if self in sys.meta_path:
|
||||
sys.meta_path.remove(self)
|
||||
try:
|
||||
spec = find_spec(fullname)
|
||||
finally:
|
||||
if self not in sys.meta_path:
|
||||
sys.meta_path.insert(0, self)
|
||||
|
||||
if spec is None or spec.loader is None:
|
||||
return None
|
||||
|
||||
original_exec = getattr(spec.loader, "exec_module", None)
|
||||
if not callable(original_exec):
|
||||
return None
|
||||
|
||||
finder = self
|
||||
|
||||
def patched_exec(module): # type: ignore[no-untyped-def]
|
||||
original_exec(module)
|
||||
finder._patched = True
|
||||
try:
|
||||
import anthropic_billing_bypass
|
||||
|
||||
anthropic_billing_bypass.apply_patches(module)
|
||||
except Exception as exc:
|
||||
import traceback
|
||||
|
||||
sys.stderr.write(
|
||||
f"[hermes-claude-auth] bypass failed: "
|
||||
f"{type(exc).__name__}: {exc}\n"
|
||||
)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
|
||||
spec.loader.exec_module = patched_exec # type: ignore[attr-defined]
|
||||
return spec
|
||||
|
||||
sys.meta_path.insert(0, _ClaudeCodeBypassFinder())
|
||||
|
||||
|
||||
try:
|
||||
_install_hook()
|
||||
except Exception as _exc:
|
||||
sys.stderr.write(f"[hermes-claude-auth] hook install failed: {_exc}\n")
|
||||
Loading…
x
Reference in New Issue
Block a user