Skip to content

feat(hosted-data): consolidate cross-region replay repository MVP - #3201

Closed
xiaoyaoqilan wants to merge 59 commits into
dimensionalOS:mainfrom
xiaoyaoqilan:codex/issue3158-unified-replay
Closed

feat(hosted-data): consolidate cross-region replay repository MVP#3201
xiaoyaoqilan wants to merge 59 commits into
dimensionalOS:mainfrom
xiaoyaoqilan:codex/issue3158-unified-replay

Conversation

@xiaoyaoqilan

@xiaoyaoqilan xiaoyaoqilan commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Contribution path

Problem

Sharing a memory2 replay currently requires manual file transfer and local path setup.

Solution

This draft proves an upload-to-replay path:

dimos data upload recording.db --owner alice --repo go2
dimos --replay --replay-db 'dimos-replay://alice/go2/<object-id>' run unitree-go2-memory

The intended first reviewable scope is limited to:

  • filesystem-backed repository;
  • resumable, SHA-256-verified transfer;
  • dimos data upload/list/download;
  • memory2 snapshot upload;
  • trusted remote replay resolution and local caching.

WebRTC, S3, regional selection, CDN, continuous publishing, browser UI, and production hardening are deferred. The current draft will be reduced or replaced with a smaller PR after agreement in #3260.

How to Test

uv run pytest dimos/hosted_data

No hardware-motion claim is made.

AI assistance

OpenAI Codex with GPT-5 assisted extensively with implementation, tests, and documentation.

Checklist

  • I have read and approved the CLA.

@codecov

codecov Bot commented Jul 26, 2026

Copy link
Copy Markdown

❌ 17 Tests Failed:

Tests completed Failed Passed Skipped
3544 17 3527 39
View the top 2 failed test(s) by shortest run time
dimos.web.relay_bridge.test_relay_bridge_e2e::test_full_session_flow_and_lazy_encode
Stack Traces | 0.214s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................................./usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f50e3cdf650>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................................./usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f50e4d67710>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f50e4d67710>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f50e3c7b0b0>
        response   = <http.client.HTTPResponse object at 0x7f50e3c80c40>
        self       = <urllib.request.OpenerDirector object at 0x7f50e3cdf650>
        timeout    = 60
................................./usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f50e3c81070>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f50e3c7b0b0>
        response   = <http.client.HTTPResponse object at 0x7f50e3c80c40>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f50e4d67710>
................................./usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f50e3c7b0b0>, <http.client.HTTPResponse object at 0x7f50e3c80c40>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f50e3cdc710>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f50e3cdc710>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f50e3c7b0b0>, <http.client.HTTPResponse object at 0x7f50e3c80c40>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f50e3c81070>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f50e3cdf650>
................................./usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f50e3c7b0b0>, <http.client.HTTPResponse object at 0x7f50e3c80c40>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f50e3c81070>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f50e3cdc710>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f50e3cdc710>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f50e3cdf650>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>
req = <urllib.request.Request object at 0x7f50e3c7b0b0>
fp = <http.client.HTTPResponse object at 0x7f50e3c80c40>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f50e3c81070>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f50e3c80c40>
hdrs       = <http.client.HTTPMessage object at 0x7f50e3c81070>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f50e3c7b0b0>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f50e3cdc740>

................................./usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def bridge() -> Iterator[RelayBridgeModule]:
>       module, _, _ = _start_bridge()


.../web/relay_bridge/test_relay_bridge_e2e.py:108: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/test_relay_bridge_e2e.py:102: in _start_bridge
    module.start()  # spawns the Deno relay, connects, registers
        image_tr   = <dimos.core.transport.pLCMTransport object at 0x7f50e3c41f10>
        module     = <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>
        odom_tr    = <dimos.core.transport.pLCMTransport object at 0x7f50e3c42a20>
dimos/core/module.py:192: in start
    self._start_main()
        self       = <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>
dimos/core/module.py:569: in _start_main
    asyncio.run_coroutine_threadsafe(gen.__anext__(), loop).result()
        gen        = <async_generator object RelayBridgeModule.main at 0x7f50e3966bd0>
        loop       = <_UnixSelectorEventLoop running=True closed=False debug=False>
        main_fn    = <function RelayBridgeModule.main at 0x7f50e8dd9c60>
        self       = <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>
................................./usr/lib/python3.12....../concurrent/futures/_base.py:456: in result
    return self.__get_result()
        self       = None
        timeout    = None
................................./usr/lib/python3.12....../concurrent/futures/_base.py:401: in __get_result
    raise self._exception
        self       = None
.../web/relay_bridge/relay_bridge_module.py:239: in main
    self._url = await _blocking_call(self._spawn_relay, self.config.open_browser)
        allowed    = None
        self       = <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>
        supervisor = None
.../web/relay_bridge/relay_bridge_module.py:91: in _blocking_call
    result = work.result()
        args       = (False,)
        cancelled  = None
        func       = <bound method RelayBridgeModule._spawn_relay of <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>>
        work       = <Task finished name='Task-50' coro=<to_thread() done, defined at ................................./usr/lib/python3.12/asyncio/threads.py:12> exception=...deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/')>
................................./usr/lib/python3.12/asyncio/threads.py:25: in to_thread
    return await loop.run_in_executor(None, func_call)
        args       = (False,)
        ctx        = <_contextvars.Context object at 0x7f50e39bb880>
        func       = <bound method RelayBridgeModule._spawn_relay of <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>>
        func_call  = functools.partial(<built-in method run of _contextvars.Context object at 0x7f50e39bb880>, <bound method RelayBridgeModule._spawn_relay of <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>>, False)
        kwargs     = {}
        loop       = <_UnixSelectorEventLoop running=True closed=False debug=False>
................................./usr/lib/python3.12.../concurrent/futures/thread.py:58: in run
    result = self.fn(*self.args, **self.kwargs)
        self       = None
.../web/relay_bridge/relay_bridge_module.py:271: in _spawn_relay
    info = self._relay.start()
        open_browser = False
        self       = <dimos.web.relay_bridge.relay_bridge_module.RelayBridgeModule object at 0x7f50e3c41fa0>
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f50e3cdc830>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_bridge_e2e::test_relay_child_death_respawns_and_recovers
Stack Traces | 5.34s run time
request = <SubRequest 'monitor_threads' for <Function test_relay_child_death_respawns_and_recovers>>

    @pytest.fixture(autouse=True)
    def monitor_threads(request):
        # Capture threads before test runs
        test_name = request.node.nodeid
        with _seen_threads_lock:
            _before_test_threads[test_name] = {
                t.ident for t in threading.enumerate() if t.ident is not None
            }
    
        yield
    
        with _seen_threads_lock:
            before = _before_test_threads.get(test_name, set())
    
        # Threads intentionally left running for the whole process and cleaned up on
        # exit, so they don't count as per-test leaks.
        expected_persistent_thread_prefixes = [
            "Dask-Offload",
            # HuggingFace safetensors conversion thread - no user cleanup API
            # https://github..../transformers/issues/29513
            "Thread-auto_conversion",
        ]
    
        def live_new_threads():
            # Threads created during this test that are still running. A thread that
            # has already stopped is not a leak -- it's done, just not yet reaped
            # from threading's registry -- so we key on is_alive(), not presence.
            result = []
            for t in threading.enumerate():
                if t.ident is None or t.ident in before or t.name == "MainThread":
                    continue
                if any(t.name.startswith(prefix) for prefix in expected_persistent_thread_prefixes):
                    continue
                if t.is_alive():
                    result.append(t)
            return result
    
        # Some C extensions tear their callback threads down asynchronously, so a
        # thread can stay alive briefly after the test cleaned up its owner (notably
        # zenoh's pyo3-closure threads, freed shortly after the session is closed).
        # A single snapshot races that teardown and flags a thread that is about to
        # exit. Give new threads a grace period to drain; only ones that stay alive
        # are real leaks (a genuinely leaked thread never exits).
        deadline = time.monotonic() + 5.0
        leaked = live_new_threads()
        while leaked and time.monotonic() < deadline:
            time.sleep(0.02)
            leaked = live_new_threads()
    
        if not leaked:
            return
    
        with _seen_threads_lock:
            # Report each leaked thread only once across the session.
            truly_new = [t for t in leaked if t.ident not in _seen_threads]
            for t in leaked:
                _seen_threads.add(t.ident)
    
        if not truly_new:
            return
    
        thread_names = [t.name for t in truly_new]
    
>       pytest.fail(
            f"Non-closed threads created during this test. Thread names: {thread_names}. "
            "Please look at the first test that fails and fix that."
        )
E       Failed: Non-closed threads created during this test. Thread names: ['Thread-4579 (run_forever)', 'Thread-4580 (_lcm_loop)', 'Thread-4581 (_lcm_loop)', 'Thread-4582 (_lcm_loop)', 'asyncio_0']. Please look at the first test that fails and fix that.

before     = {139983721526976, 139985114097344, 139985354200768, 139985432868544, 139986343028416, 139986359809728, ...}
deadline   = 454.13350007
expected_persistent_thread_prefixes = ['Dask-Offload', 'Thread-auto_conversion']
leaked     = [<Thread(Thread-4579 (run_forever), started daemon 139983704745664)>, <Thread(Thread-4580 (_lcm_loop), started daemon ...<Thread(Thread-4582 (_lcm_loop), started daemon 139983453157056)>, <Thread(asyncio_0, started daemon 139983419594432)>]
live_new_threads = <function monitor_threads.<locals>.live_new_threads at 0x7f50e48cce00>
request    = <SubRequest 'monitor_threads' for <Function test_relay_child_death_respawns_and_recovers>>
t          = <Thread(asyncio_0, started daemon 139983419594432)>
test_name  = '.../web/relay_bridge/test_relay_bridge_e2e.py::test_relay_child_death_respawns_and_recovers'
thread_names = ['Thread-4579 (run_forever)', 'Thread-4580 (_lcm_loop)', 'Thread-4581 (_lcm_loop)', 'Thread-4582 (_lcm_loop)', 'asyncio_0']
truly_new  = [<Thread(Thread-4579 (run_forever), started daemon 139983704745664)>, <Thread(Thread-4580 (_lcm_loop), started daemon ...<Thread(Thread-4582 (_lcm_loop), started daemon 139983453157056)>, <Thread(asyncio_0, started daemon 139983419594432)>]

dimos/conftest.py:288: Failed
View the full list of 15 ❄️ flaky test(s)
dimos.web.relay_bridge.test_relay_e2e::test_close_signal_stops_writer_and_wakes_waiter

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.017s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c111b1010>
        response   = <http.client.HTTPResponse object at 0x7f2c111b0ee0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c111b2c30>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c111b1010>
        response   = <http.client.HTTPResponse object at 0x7f2c111b0ee0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c111b1010>, <http.client.HTTPResponse object at 0x7f2c111b0ee0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c111b1010>, <http.client.HTTPResponse object at 0x7f2c111b0ee0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c111b2c30>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c111b1010>, <http.client.HTTPResponse object at 0x7f2c111b0ee0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c111b2c30>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c111b1010>
fp = <http.client.HTTPResponse object at 0x7f2c111b0ee0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c111b2c30>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111b0ee0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c111b2c30>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c111b1010>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture
    def own_relay() -> Iterator[RelayProcess]:
        """A started relay process the test may stop itself (stop() is idempotent)."""
        process = RelayProcess()
        try:
>           process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c111b3c20>

.../web/relay_bridge/test_relay_e2e.py:61: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c111b3c20>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_duplicate_robot_id_is_terminal_until_first_disconnects

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_info_matches_ready_line

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.055s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_large_frame_1mib

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_latest_channel_newest_wins

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_latest_writer_resets_stale_stream

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_malformed_robot_frame_is_dropped

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_reliable_channel_is_complete_and_intact

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_reset_burst_does_not_wedge_robot_leg

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_reset_stale_discards_partial_frame

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_robot_handshake_and_datagram_rtt

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_robot_hello_without_identity_is_rejected

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_send_frame_paces_with_wait_delivered

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_stats_reflect_traffic

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError
dimos.web.relay_bridge.test_relay_e2e::test_unsub_stops_forwarding_and_bridge_hears_it

Flake rate in main: 11.11% (Passed 8 times, Failed 1 times)

Stack Traces | 0.001s run time
def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
>           _require_immutable_release()

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/utils/deno.py:81: in _require_immutable_release
    with urllib.request.urlopen(url, timeout=60) as resp:
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:215: in urlopen
    return opener.open(url, data, timeout)
        cadefault  = False
        cafile     = None
        capath     = None
        context    = None
        data       = None
        opener     = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
        url        = 'https://api.github..../releases/tags/v2.6.10'
................../usr/lib/python3.12/urllib/request.py:521: in open
    response = meth(req, response)
        data       = None
        fullurl    = 'https://api.github..../releases/tags/v2.6.10'
        meth       = <bound method HTTPErrorProcessor.http_response of <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>>
        meth_name  = 'https_response'
        processor  = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
        protocol   = 'https'
        req        = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
        timeout    = 60
................../usr/lib/python3.12/urllib/request.py:630: in http_response
    response = self.parent.error(
        code       = 403
        hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
        msg        = 'rate limit exceeded'
        request    = <urllib.request.Request object at 0x7f2c11177860>
        response   = <http.client.HTTPResponse object at 0x7f2c111760b0>
        self       = <urllib.request.HTTPErrorProcessor object at 0x7f2c11175b50>
................../usr/lib/python3.12/urllib/request.py:559: in error
    return self._call_chain(*args)
        args       = ({'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHa...ult', <urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, ...)
        dict       = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        http_err   = 1
        meth_name  = 'http_error_403'
        orig_args  = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        proto      = 403
        result     = None
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
................../usr/lib/python3.12/urllib/request.py:492: in _call_chain
    result = func(*args)
        args       = (<urllib.request.Request object at 0x7f2c11177860>, <http.client.HTTPResponse object at 0x7f2c111760b0>, 403, 'rate limit exceeded', <http.client.HTTPMessage object at 0x7f2c11176f00>)
        chain      = {'default': [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>], 301: [<urllib.request.HTTPRedirectHan...PRedirectHandler object at 0x7f2c11177890>], 303: [<urllib.request.HTTPRedirectHandler object at 0x7f2c11177890>], ...}
        func       = <bound method HTTPDefaultErrorHandler.http_error_default of <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>>
        handler    = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
        handlers   = [<urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>]
        kind       = 'default'
        meth_name  = 'http_error_default'
        self       = <urllib.request.OpenerDirector object at 0x7f2c111740e0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>
req = <urllib.request.Request object at 0x7f2c11177860>
fp = <http.client.HTTPResponse object at 0x7f2c111760b0>, code = 403
msg = 'rate limit exceeded'
hdrs = <http.client.HTTPMessage object at 0x7f2c11176f00>

    def http_error_default(self, req, fp, code, msg, hdrs):
>       raise HTTPError(req.full_url, code, msg, hdrs, fp)
E       urllib.error.HTTPError: HTTP Error 403: rate limit exceeded

code       = 403
fp         = <http.client.HTTPResponse object at 0x7f2c111760b0>
hdrs       = <http.client.HTTPMessage object at 0x7f2c11176f00>
msg        = 'rate limit exceeded'
req        = <urllib.request.Request object at 0x7f2c11177860>
self       = <urllib.request.HTTPDefaultErrorHandler object at 0x7f2c111777a0>

................../usr/lib/python3.12/urllib/request.py:639: HTTPError

The above exception was the direct cause of the following exception:

    @pytest.fixture(scope="module")
    def relay() -> Iterator[RelayReadyInfo]:
        process = RelayProcess()
        try:
>           yield process.start()

process    = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>

.../web/relay_bridge/test_relay_e2e.py:51: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../web/relay_bridge/relay_process.py:71: in start
    deno = ensure_deno()
        self       = <dimos.web.relay_bridge.relay_process.RelayProcess object at 0x7f2c11175fa0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def ensure_deno() -> str:
        which = shutil.which("deno")
        if which:
            return which
    
        exe_name = "deno.exe" if platform.system() == "Windows" else "deno"
        deno_dir = _DENO_CACHE_DIR / DENO_VERSION
        deno_path = deno_dir / exe_name
        if deno_path.exists():
            return str(deno_path)
    
        triple = _deno_triple()
        url = f"https://github..../deno/releases/download/{DENO_VERSION}/deno-{triple}.zip"
        logger.info(f"Downloading deno {DENO_VERSION} from {url}")
        deno_dir.mkdir(parents=True, exist_ok=True)
        try:
            _require_immutable_release()
            with tempfile.TemporaryDirectory(dir=str(deno_dir.parent)) as tmp:
                tmp_path = Path(tmp)
                zip_path = tmp_path / "deno.zip"
                with urllib.request.urlopen(url, timeout=60) as resp, open(zip_path, "wb") as f:
                    shutil.copyfileobj(resp, f)
                with zipfile.ZipFile(zip_path) as z:
                    z.extractall(tmp_path)
                extracted = tmp_path / exe_name
                if not extracted.exists():
                    raise RuntimeError(f"deno binary not found in archive from {url}")
                extracted.chmod(extracted.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
                extracted.replace(deno_path)
        except Exception as e:
>           raise RuntimeError(
                f"deno is required. Auto-download failed: {e}. Install manually from https://deno.com/"
            ) from e
E           RuntimeError: deno is required. Auto-download failed: HTTP Error 403: rate limit exceeded. Install manually from https://deno.com/

deno_dir   = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10')
deno_path  = PosixPath('............/home/runner/.cache............/dimos/deno/v2.6.10/deno')
exe_name   = 'deno'
triple     = 'x86_64-unknown-linux-gnu'
url        = 'https://github..../deno/releases/download/v2.6.10/deno-x86_64-unknown-linux-gnu.zip'
which      = None

dimos/utils/deno.py:66: RuntimeError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@xiaoyaoqilan

Copy link
Copy Markdown
Contributor Author

Deployment and CLI verification update:

  • fixed Windows upload rejection behavior in ea58334 by adding a body-free HEAD quota preflight before POST
  • focused hosted-data suite: 87 passed
  • Ruff and git diff --check: passed
  • local CLI smoke test: serveuploadlistdownload; source and downloaded SHA-256 matched
  • deployed ea58334 to the Beijing Aliyun node at 39.106.170.53:8765
  • systemd now runs python -m dimos.hosted_data.cli serve
  • server health: {"node":"cn-beijing","region":"china","status":"ok"}
  • server-side and public-client upload/download SHA-256:
    22531dca667485a7a9cdf8e1dea4798899cd2c1264a0bc69e03cb5671afd27f4
  • public repository smoke page:
    http://39.106.170.53:8765/r/codex/issue3158-deploy

The existing repository storage directory was preserved. The previous systemd unit is backed up as /etc/systemd/system/dimos-replay.service.bak-unified-20260727.

Copy link
Copy Markdown
Contributor Author

China-node deployment and direct DimOS integration verification:

The feature is wired into DimOS itself rather than remaining a standalone demo:

dimos data upload capture.mp4 --owner alice --repo go2 --resumable
dimos run unitree-go2-mid360-hosted-record
dimos --replay --replay-db 'dimos-replay://...' run unitree-go2-memory

The main dimos data Typer module, hosted Go2 recorder blueprint, DIMOS_REPLAY_DB configuration, and Go2 remote replay resolver are all present in this PR. The Beijing server is currently running deployment commit 064ee6a (operator dashboard follow-up) on top of PR head 3743d9a; the follow-up still needs to be pushed to the fork branch before this draft is marked ready.

Copy link
Copy Markdown
Contributor Author

Thanks — agreed. I read the Issues vs Discussions guidance and opened #3260 with the problem statement, intended user flow, architecture, alternatives, non-goals, and a staged implementation plan.

#3158 already captured the requirements, but it did not provide enough design context for a PR of this size. I will keep #3201 as a draft prototype and will not ask maintainers to review the whole diff as one unit. Once the discussion establishes the smallest accepted scope, I will reduce this PR to that phase or replace it with smaller linked PRs.

@xiaoyaoqilan

Copy link
Copy Markdown
Contributor Author

The first reviewable replacement is now open as Draft PR #3262: filesystem repository core only (2 files, 535 lines, no new dependencies). This keeps #3201 as the end-to-end prototype and moves review to small staged PRs described in Discussion #3260.

@xiaoyaoqilan

Copy link
Copy Markdown
Contributor Author

Closing this large draft to remove ambiguity for reviewers. It remains useful as an end-to-end prototype, but it is not a merge candidate.

The current and only reviewable PR is #3262, limited to the filesystem repository core. Later capabilities will be proposed separately only after that boundary is accepted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant