fix(deps): raise molecule-ai-workspace-runtime floor to >=0.1.129 (#5)
Some checks failed
CI / test (3.11) (push) Successful in 2m57s
CI / test (3.12) (push) Successful in 3m30s
Publish to PyPI / build (push) Successful in 3m43s
Publish to PyPI / publish (push) Failing after 1m1s

Closes molecule-ai/internal#424.
This commit is contained in:
devops-engineer 2026-05-15 22:54:24 +00:00
commit d57392df4d
2 changed files with 120 additions and 2 deletions

View File

@ -4,14 +4,26 @@ build-backend = "setuptools.build_meta"
[project]
name = "codex-channel-molecule"
version = "0.1.2"
version = "0.1.3"
description = "Bridge daemon for codex CLI ↔ Molecule platform — long-polls the platform inbox, runs `codex exec --resume <session>` per inbound message, replies via send_message_to_user MCP tool. Counterpart to hermes-channel-molecule."
readme = "README.md"
requires-python = ">=3.11"
license = { text = "Apache-2.0" }
authors = [{ name = "Molecule AI" }]
dependencies = [
"molecule-ai-workspace-runtime>=0.1.110",
# Floor raised from 0.1.110 → 0.1.129 to pull in the SSOT A2A response
# parser (a2a_response.py, introduced 0.1.129). Pre-0.1.129 the legacy
# inline sniffer in a2a_client.send_a2a_message treated the poll-mode
# ``{"status": "queued", "delivery_mode": "poll", "method": "..."}``
# envelope as malformed and surfaced ``[A2A_ERROR] unexpected response
# shape (no result, no error): ...`` on every reply attempt — that
# then propagated to canvas as the workspace's task label and triggered
# a ~3s retry storm. The 0.1.129+ runtime classifies the envelope as
# ``Queued`` and short-circuits to the durable /delegate-poll path
# (a2a_tools_delegation._delegate_sync_via_polling). See
# ``molecule-ai/internal#424`` and ``molecule-core#2967`` for the
# full incident + fix history.
"molecule-ai-workspace-runtime>=0.1.129",
]
[project.optional-dependencies]

View File

@ -0,0 +1,106 @@
"""Pin the minimum molecule-ai-workspace-runtime version that ships
the SSOT A2A response parser.
Background see ``molecule-ai/internal#424``:
Pre-runtime-0.1.129 the inline sniffer in ``a2a_client.send_a2a_message``
checked for ``result`` or ``error`` keys and routed everything else to
``[A2A_ERROR] unexpected response shape (no result, no error): ...``.
That branch fired on every reply attempt to a poll-mode peer because the
platform proxy synthesizes the success envelope as
``{"status": "queued", "delivery_mode": "poll", "method": "..."}``
which has NEITHER ``result`` NOR ``error``. The retry loop hammered the
caller's canvas with the error string every ~3s.
Version 0.1.129 introduced ``a2a_response.py`` a typed parser with an
explicit ``Queued`` variant and the matching ``[A2A_QUEUED]`` sentinel
in ``a2a_client.py``. ``a2a_tools_delegation.tool_delegate_task`` then
falls back to the durable ``/delegate`` + ``/delegations`` polling path,
which IS the correct synchronous facade for poll-mode peers.
This test asserts the floor is held at ``>=0.1.129`` so a future
dependency-housekeeping pass cannot silently lower it back into the
broken range. If the floor is ever raised further (e.g. to require a
later SSOT parser feature), update the constant below the lower bound
must never go below 0.1.129.
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
import pytest
if sys.version_info >= (3, 11):
import tomllib
else: # pragma: no cover - Python 3.11+ required by pyproject anyway
import tomli as tomllib
# The earliest runtime version that ships the SSOT A2A response parser
# with the typed ``Queued`` variant. Bumping this floor MUST be paired
# with a comment update in pyproject.toml's dependencies block.
_MINIMUM_RUNTIME_VERSION = (0, 1, 129)
def _parse_version(spec: str) -> tuple[int, int, int]:
"""Extract the lower-bound version from a dependency specifier.
Supports the common shapes used in our pyproject files:
* ``pkg>=1.2.3`` (1, 2, 3)
* ``pkg>=1.2.3,<2`` (1, 2, 3)
* ``pkg~=1.2.3`` (1, 2, 3)
Raises ``ValueError`` on anything else so the test fails loud rather
than silently passing on a malformed specifier.
"""
m = re.search(r"(?:>=|~=)\s*(\d+)\.(\d+)\.(\d+)", spec)
if not m:
raise ValueError(f"no lower-bound version in specifier: {spec!r}")
return (int(m.group(1)), int(m.group(2)), int(m.group(3)))
@pytest.fixture(scope="module")
def runtime_specifier() -> str:
"""Return the raw dependency specifier for molecule-ai-workspace-runtime."""
root = Path(__file__).resolve().parent.parent
pyproject = root / "pyproject.toml"
with pyproject.open("rb") as f:
data = tomllib.load(f)
deps = data["project"]["dependencies"]
for dep in deps:
# match the package name allowing a hyphen-or-underscore in case
# the spec ever normalizes — PEP 503 treats them equivalently.
if re.match(r"^molecule[-_]ai[-_]workspace[-_]runtime\b", dep):
return dep
raise AssertionError(
"pyproject.toml is missing a molecule-ai-workspace-runtime dependency"
)
def test_runtime_floor_includes_a2a_response_parser(runtime_specifier: str) -> None:
"""The runtime floor must be at or above the SSOT parser release."""
bound = _parse_version(runtime_specifier)
assert bound >= _MINIMUM_RUNTIME_VERSION, (
f"runtime floor {bound} is below {_MINIMUM_RUNTIME_VERSION}"
f"pre-0.1.129 the A2A response parser misclassifies the poll-mode "
f"queued envelope as malformed and surfaces "
f"'[A2A_ERROR] unexpected response shape' on every poll-mode peer "
f"reply. See molecule-ai/internal#424."
)
def test_runtime_specifier_uses_a_lower_bound(runtime_specifier: str) -> None:
"""A bare ``pkg`` or upper-only spec would silently install ANY version
on a fresh ``pip install`` including the buggy pre-0.1.129 range.
Require an explicit lower bound (``>=`` or ``~=``).
"""
assert re.search(r">=|~=", runtime_specifier), (
f"runtime dependency {runtime_specifier!r} has no lower bound — "
f"a fresh install could resolve to a pre-0.1.129 wheel with the "
f"broken poll-mode parser"
)