Commit Graph

4 Commits

Author SHA1 Message Date
4a8cd3648f fix(post-suspension): migrate github.com/Molecule-AI refs to git.moleculesai.app (Class G #168)
All checks were successful
CI / test (3.11) (pull_request) Successful in 2m43s
CI / test (3.12) (pull_request) Successful in 2m44s
The GitHub org Molecule-AI was suspended on 2026-05-06; canonical SCM
is now Gitea at https://git.moleculesai.app/molecule-ai/. Stale
github.com/Molecule-AI/... URLs return 404 and break tooling that
clones / pip-installs / curls them.

This bundles all non-Go-module URL fixes for this repo into a single PR.
Go module path references (in *.go, go.mod, go.sum) are out of scope
here -- tracked separately under Task #140.

Token-auth clone URLs also flip ${GITHUB_TOKEN} -> ${GITEA_TOKEN} since
the GitHub token does not auth against Gitea.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 13:02:40 -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
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
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