Commit Graph

9 Commits

Author SHA1 Message Date
documentation-specialist
336d1beab1 docs(install): migrate github.com refs to git.moleculesai.app (#37)
Some checks failed
CI / test (3.12) (pull_request) Failing after 11s
CI / test (3.11) (pull_request) Failing after 11s
Two refs in README.md:
- Sister-repo cross-link `hermes-channel-molecule` (line 5)
- Anonymous `git clone` install command in Development section (line 73)

Both rewritten to the canonical Gitea path
(https://git.moleculesai.app/molecule-ai/...). Anonymous-clone semantics
preserved — no auth-shape change, repos are public on Gitea.

Other github.com refs in README (openai/codex links) are upstream
references and remain unchanged.

Refs: molecule-ai/internal#37, molecule-ai/internal#38
2026-05-06 23:17:51 -07:00
Hongming Wang
6f961d655c
Merge pull request #3 from Molecule-AI/fix/v0.1.2-codex-cli-shape-and-launchd-path
Some checks failed
CI / test (3.11) (push) Failing after 13m40s
Publish to PyPI / build (push) Failing after 13m38s
CI / test (3.12) (push) Failing after 13m39s
Publish to PyPI / publish (push) Has been cancelled
v0.1.2: codex CLI subcommand shape + inbox poller + launchd PATH
2026-05-04 21:23:10 -07:00
Hongming Wang
0f194d4507 v0.1.2: codex CLI subcommand shape + inbox poller activation + launchd PATH
Three production bugs caught by the codex agent live-testing the daemon
end-to-end against codex-cli 0.128 + a real LaunchAgent install:

1. Codex CLI 0.6+ moved `--resume` from a flag on `exec` to a
   `resume` subcommand. The daemon was sending
   `codex exec --skip-git-repo-check --resume <sid> <prompt>`, which
   parses on 0.5.x but fails on 0.6.x+. Fixed to:
     fresh:  codex exec --skip-git-repo-check <prompt>
     resume: codex exec resume --skip-git-repo-check <sid> <prompt>
   Verified on codex-cli 0.128 with a live binary; the 0.5.x behavior
   is preserved by the fake-codex test fixture, which now SystemExits
   if it sees the legacy `--resume` flag (regression gate).

2. wait_for_message() never returned anything because nothing in the
   daemon ever called molecule_runtime.inbox.activate() or started
   the poller thread. The wheel ships those primitives but expects
   the embedding runtime to wire them up — the workspace runtime
   does this in start.py, but a standalone daemon embedding the
   tools must do it itself. Added the activation + poller-thread
   start in _RealTools.__init__.

3. The codex binary is a `#!/usr/bin/env node` shim. Under launchd /
   stripped systemd units, the parent process PATH is `/usr/bin:/bin`
   and `env node` 127s out silently. CodexRunner now prepends the
   directory of the resolved codex binary to the subprocess PATH at
   spawn time — Node lives next to codex under nvm / brew /
   pnpm-global, so this restores the discovery without operators
   having to thread PATH through their LaunchAgent / unit file.
   README updated with a note on the launchd/systemd interaction.

Test:
- 31 passed (was 28). Three new regression gates: subcommand-shape,
  PATH-prepend (launchd-default PATH stripped), and PATH-no-double
  (idempotent when codex_bin_dir already present). Verified the two
  behavioural new tests FAIL on the old codex_runner.py by stashing
  the source change only and re-running.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 21:21:44 -07:00
Hongming Wang
9abf6bfa79
Merge pull request #2 from Molecule-AI/feat/v0.1.1-backoff-and-tests
Some checks failed
Publish to PyPI / build (push) Failing after 13m38s
Publish to PyPI / publish (push) Has been cancelled
v0.1.1: exponential backoff on platform errors + error-path tests
2026-05-04 20:11:25 -07:00
Hongming Wang
467d47e3a3 v0.1.1: exponential backoff on platform errors + error-path test coverage
Production fix:
- wait_for_message exceptions now trigger exponential backoff (1s → 60s
  cap, resets to 0 on first successful poll) instead of a flat 1s retry.
  Under platform outage, N daemons under flat 1Hz retry would hammer the
  endpoint unnecessarily; the cap-and-reset shape keeps the daemon
  responsive while being a good citizen.

Correctness gate:
- Test coverage for the six error branches that operators actually hit:
  the backoff progression itself, backoff reset on first success,
  inbox_pop failure (codex must not re-run the same message),
  peer_agent without peer_id (poison drained, not looped),
  unknown message kind (poison drained, not looped),
  empty codex output (placeholder reply, not silent drop),
  canvas_user falling back to workspace_id when arrival_workspace_id
  absent, and four malformed-payload shapes from wait_for_message
  (parametrised: invalid JSON, non-dict, timeout sentinel, missing
  activity_id).
- Backoff tests verified to FAIL on the old flat-1s code by stashing
  only bridge.py and re-running — pinning a real regression, not a
  tautology.

Cleanup:
- _RealTools imports molecule_runtime.a2a_tools once at construction
  instead of four times per message.
- README documents CODEX_CHANNEL_MOLECULE_STATE_DIR override.

Test: pytest -q → 28 passed (was 17).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 20:10:17 -07:00
Hongming Wang
3e428dde2b
Merge pull request #1 from Molecule-AI/chore/pypi-publish-workflow
Some checks failed
Publish to PyPI / build (push) Failing after 13m39s
Publish to PyPI / publish (push) Has been cancelled
chore(ci): tag-triggered PyPI publish via OIDC trusted-publisher
2026-05-04 18:38:38 -07:00
Hongming Wang
dba5970177 chore(ci): tag-triggered PyPI publish via OIDC trusted-publisher
Tag-on-push (`v0.1.0` shape) builds the sdist+wheel, smoke-imports the
console-script entry point from a fresh venv to catch packaging
regressions, then uploads to PyPI via trusted publisher OIDC — no
API token in repo secrets.

Includes a tag-vs-pyproject version-match guard: aborts the publish
if the tag doesn't match `pyproject.toml`'s `version`. Cheap defense
against the failure mode where the tag advances but pyproject doesn't,
which silently re-publishes the same wheel under a new tag.

README's "Releasing" section walks through the one-time PyPI trusted-
publisher registration the operator must do once before the first
tagged push.

After this lands and the PyPI registration is complete, the codex tab
in the External Connect modal can switch from
  pip install 'git+https://github.com/Molecule-AI/codex-channel-molecule.git'
to
  pip install codex-channel-molecule

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 18:37:17 -07:00
Hongming Wang
d6eb78dcee feat: initial bridge daemon
codex-channel-molecule is the codex-side counterpart to
hermes-channel-molecule. It long-polls the molecule platform inbox via
molecule_runtime.a2a_tools.tool_wait_for_message, runs `codex exec
--resume <session>` per inbound message, captures the assistant reply
from stdout, and routes it back through send_message_to_user (canvas
chat) or delegate_task (peer agent), then acks the inbox row.

Per chat thread (one canvas-user thread or one peer-workspace thread)
gets its own codex session_id, persisted to disk so daemon restarts
keep conversation context. Reply-routing failures skip the inbox_pop
ack so the platform's at-least-once delivery re-surfaces the row on
the next poll.

This daemon is the operator-unblock until openai/codex#17543 lands —
once codex itself accepts MCP custom notifications as Op::UserInput
through the wired-in MCP server, this daemon becomes redundant. The
README's deprecation-path section calls that out so future operators
know when to switch off.

Tests cover the dispatch loop with fake tools (8 tests asserting
exact contracts: canvas vs peer routing, session continuity,
persistence across restarts, timeout sentinel handling, at-least-once
on reply failure, exit-code surfacing, A2A multipart text). The
codex_runner tests are real-subprocess (fake codex script spawned via
asyncio.create_subprocess_exec) so the boot path matches production —
no in-process mocking of the spawn boundary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 18:09:09 -07:00
Hongming Wang
8c175af04b
Initial commit 2026-05-04 18:03:52 -07:00