fix(plugins): share one cached handoff runtime and use version 0.3.2
This commit is contained in:
@@ -29,7 +29,7 @@ from typing import Any, Iterable
|
||||
import telemetry
|
||||
|
||||
DEFAULT_API_URL = "https://api.mem0.ai"
|
||||
PLUGIN_VERSION = "0.4.0"
|
||||
PLUGIN_VERSION = "0.3.2"
|
||||
|
||||
_harness_name: str = "generic"
|
||||
_harness_env_prefix: str = "MEM0_PLUGIN"
|
||||
|
||||
@@ -1,7 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Import an explicit native session or neutral handoff bundle into Codex."""
|
||||
"""Run the shared handoff engine locally or from its verified immutable cache."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from urllib.request import urlopen
|
||||
|
||||
ENGINE_FILES = {"claude_to_codex.py", "handoff_sources.py"}
|
||||
SOURCE_URL = "https://raw.githubusercontent.com/mem0ai/mem0"
|
||||
|
||||
|
||||
def _verified(path: Path, digest: str) -> bool:
|
||||
try:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest() == digest
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
|
||||
|
||||
def runtime_root(launcher_dir: Path | None = None) -> Path:
|
||||
here = launcher_dir or Path(__file__).resolve().parent
|
||||
if all((here / name).is_file() for name in ENGINE_FILES):
|
||||
return here # The canonical development checkout already has both engines.
|
||||
manifest = json.loads((here / "handoff-runtime.json").read_text(encoding="utf-8"))
|
||||
if not isinstance(manifest, dict):
|
||||
raise ValueError("invalid handoff runtime manifest")
|
||||
revision, files = manifest.get("revision"), manifest.get("files")
|
||||
if not isinstance(revision, str) or not re.fullmatch(r"[0-9a-f]{40}", revision):
|
||||
raise ValueError("handoff runtime revision must be an immutable commit SHA")
|
||||
if (
|
||||
not isinstance(files, dict)
|
||||
or set(files) != ENGINE_FILES
|
||||
or any(not isinstance(digest, str) or not re.fullmatch(r"[0-9a-f]{64}", digest) for digest in files.values())
|
||||
):
|
||||
raise ValueError("invalid handoff runtime file hashes")
|
||||
cache = Path.home() / ".mem0" / "handoff-runtime" / revision
|
||||
missing = {name: digest for name, digest in files.items() if not _verified(cache / name, digest)}
|
||||
if not missing:
|
||||
return cache
|
||||
cache.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
||||
with tempfile.TemporaryDirectory(prefix=f".{revision}-", dir=cache.parent) as temporary:
|
||||
staged = Path(temporary)
|
||||
for name, digest in missing.items():
|
||||
url = f"{SOURCE_URL}/{revision}/integrations/agent-plugin-core/python/{name}"
|
||||
try:
|
||||
with urlopen(url, timeout=30) as response:
|
||||
body = response.read()
|
||||
except OSError as exc:
|
||||
raise OSError(f"could not download pinned handoff runtime {name}: {exc}") from exc
|
||||
if hashlib.sha256(body).hexdigest() != digest:
|
||||
raise ValueError(f"SHA256 mismatch for pinned handoff runtime {name}; refusing to execute it")
|
||||
(staged / name).write_bytes(body)
|
||||
# All downloads are verified before publishing; each replacement is atomic.
|
||||
cache.mkdir(exist_ok=True, mode=0o700)
|
||||
for name in missing:
|
||||
os.replace(staged / name, cache / name)
|
||||
if not all(_verified(cache / name, digest) for name, digest in files.items()):
|
||||
raise ValueError("handoff runtime cache changed during installation; refusing to execute it")
|
||||
return cache
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
try:
|
||||
root = runtime_root()
|
||||
except (OSError, ValueError) as exc:
|
||||
print(f"handoff runtime unavailable: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
sys.path.insert(0, str(root))
|
||||
from claude_to_codex import main as engine_main
|
||||
|
||||
return engine_main(argv, default_source=None)
|
||||
|
||||
from claude_to_codex import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(default_source=None))
|
||||
raise SystemExit(main())
|
||||
|
||||
Reference in New Issue
Block a user