Skip to content

Consider: an acpx 'muse' agent — ACP adapter for the Muse CLI (plan-quota coding harness for OpenClaw) #1721

Open

Description

@dezren39

The idea (Drew, 2026-10-28 — filed for consideration, not yet a build order)

Give OpenClaw a fifth ACP coding harness, agentId muse, alongside opencode / claude / codex / agy: an ACP adapter that drives the Muse CLI the way the bundled adapters drive the Claude/Codex CLIs. OpenClaw's acpx has no built-in muse agent and no bundled adapter — this is new code, sized like the other adapters.

What already exists

  • The Muse CLI is installed and logged in on the laptop: Muse Code 1.4.13, ~/.config/muse/auth.json present. Drew's settled mapping (2026-10-25): the muse program's OAuth login draws on the Muse API High Usage plan — the SAME single Meta pool the meta provider uses. It never touches the assistant's own subscription.
  • Our muse-proxy (built 2026-10-21): an OpenAI-compatible proxy shelling to muse exec --json per request (codex-proxy pattern), formerly wiring an OpenCode muse provider on :18747. That provider was disabled by Drew's order 2026-10-25 as a second, wasteful door into the same pool for MODEL routing — the proxy service is inactive now. An ACP harness is a different surface from a model route (it runs Muse's own agent loop, tools and session handling, rather than putting Muse models inside OpenCode's loop), but the relationship needs an explicit ruling, see questions.
  • External precedent: pgquiles/opencode-muse bridges OpenCode to the official CLI via muse serve / the Muse SDK, sign-in and inference inside the CLI, subscription/plan-only. Proof the CLI route works as an agent host, from the OpenCode side.

What an adapter would need

  • ACP (stdio JSON-RPC: initialize / session-new / prompt / cancel / permissions) translated to the Muse CLI's interface — either muse serve (stateful, SDK protocol) or muse exec --json per turn (stateless; session resume semantics to design).
  • Packaging in the flake like the other adapters + a per-agent command override in home/openclaw (the pattern the claude/codex/agy enablement just used) + an allowedAgents entry.
  • A smoke test: ACP session spawn from OpenClaw, one real coding turn, plan usage visible in the High Usage pool readings afterwards.

Questions to settle before building

  1. Second-door ruling: does an ACP muse harness reopen the concern that closed the muse provider on 2026-10-25, or is the agent-loop distinction (Muse's own tools/session vs a model route) enough to make it a first-class door?
  2. Quota discipline: harness turns would draw the High Usage pool outside the stewardship measurement gate that governs session dispatch. How are they metered/capped — and does the pool's existing plan-only rule (never PAYG) hold for harness spend?
  3. serve vs exec: which CLI interface maps to ACP session semantics with less invention?
  4. Auth placement: the CLI OAuth lives on the laptop today; does the harness need its own login lifecycle handling (expiry, refresh) the way the proxies learned to?

Acceptance (if this graduates from consideration)

A short design note answering the four questions lands first; build only on Drew's go after that.

Acceptance criteria

  • A short design note answers the four questions in the issue body (adapter shape, pool accounting, session semantics, maintenance ownership) and is linked from this issue.
  • No build work starts before Drew's explicit go on that design note (this issue is a consideration, not a build order).
  • If it graduates: the adapter drives the Muse CLI over ACP alongside the existing opencode/claude/codex/agy agents, with the Meta pool mapping respected (the muse program's OAuth route only; never the disabled OpenCode muse provider).

Activity

  1. developing-today commented on Oct 28, 2026

    @developing-today
    Contributor
  2. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    Smoke test 2026-10-28: muse serve vs muse exec (laptop, Muse Code 1.4.13, plan login)

    Ran both routes with the same test (model muse-spark-1.3, reasoning effort low, identical prompt: write nth_prime(n), state the 100th prime, no tools). Serve was driven with the official @muse-code/sdk (1.4.14, zero-dependency) over stdio — first time serve has been run on our machines; everything before today was exec.

    Timings (laptop under heavy load ~18-22 during the runs, so absolutes are inflated; the relative gap is the signal):

    • exec, per call, all-in wall: 13.3s and 18.0s (process spawn + session + turn + teardown, paid every call)
    • serve: host spawn + initialize handshake 0.83s one-time, session start 0.65s, benchmark turn in a fresh session 7.2s, same prompt in a second fresh session on the warm host 7.8s, follow-up turn in the existing session 10.2s (trivial prompt; load noise)

    Quality: identical. Both routes returned the same correct answer (541; follow-up 101st = 547 also correct) with effectively the same code. Not a coincidence: exec's --json output is literally an MSP session event stream — exec is a one-shot session of the same stack, so there's no quality difference to buy either way. The difference is purely overhead: serve amortizes startup across sessions/turns, exec pays it per call — roughly half the wall time per turn in this test.

    Bearing on this issue: question 3 (serve vs exec) now has evidence — serve is the right substrate for an ACP adapter: persistent stdio host, JSON-RPC (NDJSON) wire, session/turn lifecycle that maps onto ACP concepts, and the SDK proves the client side. Questions 1 (second-door ruling), 2 (quota discipline), and 4 (auth lifecycle) still need Drew's rulings before any build.

    Raw artifacts: laptop /tmp/muse-bench/ (exec-1.jsonl, exec-2.jsonl, driver /tmp/serve-bench.mjs).

  3. added
    kind/questionQuestion or design decision to resolve
    source/humanFiled directly by a human
    priority/lowNice to have; do when convenient
    effort/mMedium: expected under 1 day of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 28, 2026
  4. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    Intake review

    • Related: Nix-package the Claude/Codex ACP adapters — repoint OpenClaw acpx off tmp/plugin-captures #1711 (Nix-packaging the Claude/Codex ACP adapters) is the sibling piece of OpenClaw ACP work filed today; this consideration would add a fifth harness beside opencode / claude / codex / agy.
    • Notes: Explicitly a consideration, not a build order — labelled kind/question, priority/low. The body's pool mapping is consistent with the standing rule: the muse program's OAuth login draws on the single Meta pool (Muse API High Usage plan); the OpenCode muse provider stays disabled and must not be used as the route.
    • Risks: Pool accounting is the main one — a new harness drawing on the Meta pool changes burn patterns for every other route; the design note should state the expected quota impact before any build.
    • Suggested approach: Answer the four questions in a short design note (adapter shape, pool accounting, session semantics, ownership) and get Drew's go before building, per the issue's own acceptance.
  5. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    Addendum 2026-10-28: the third route measured — direct API

    Drew's challenge on the benchmark above: exec is a retired route (muse-proxy, inactive), so the comparison that matters includes the method the fleet actually uses. Same prompt, same model/effort, run minutes later on the same loaded laptop:

    • Direct API (meta provider route, HTTPS to api.meta.ai, plan key): 4.29s, correct answer (541), 854 tokens total.
    • muse serve turn in a fresh session: 7.2–7.8s
    • muse exec per call: 13.3–18.0s

    Ordering as expected: the API route carries no agent-loop machinery at all, serve carries the session stack without process startup, exec pays everything per call. This does not change the ACP conclusion (an ACP harness needs the agent loop by definition — the API route cannot substitute for it), but the record now has all three.

  6. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed on Oct 28, 2026
  7. 18 remaining items

  8. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    Owner decision 2026-10-28 (main chat): GO — build it with the design note's rulings. Q1 first-class door (the OpenCode muse provider closure stands untouched); Q2 metering/capping as build-blocking acceptance criteria (plan-only by construction, per-session usage ledger, pre-dispatch pool check, turn budget); Q3 muse serve transport with exec only as the degraded fallback; Q4 the adapter owns no credentials — the CLI's laptop OAuth login is the only auth and expiry surfaces as an error. Implementation filed as #2012 and enqueued to the fleet queue from this decision. This issue's question is answered; it closes when #2012 lands.

  9. added
    queue/queuedHas a queued task in the Supabase agent queue
    task/triageQueue packet kind: verify, reproduce, and route this item
    and removed
    user/reviewNeeds a user-look: Muse reviews first and handles what it can
    on Oct 29, 2026
  10. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    state: triaged (coverage pass)
    Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/low). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
    Found via: coverage pass 2026-11-03

  11. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · triage re-check (already covered)

    Evidence trail at current main (1e3763faf, fetched 2026-11-03T13:02Z):

    Premise re-verified fresh at HEAD: home/openclaw/default.nix still lists allowedAgents = [ "opencode" "claude" "codex" "agy" ] — no muse harness, so the gap is real and unfixed. Nothing here is stale or superseded.

    Why no new work from this task: #2012 is currently queue/blocked + user/escalated on a Drew-authored draft PR #3275 that overlaps home/openclaw/default.nix and the ACP wrapper wiring. Building here would duplicate that, and a second design note would duplicate 2671. Cross-linking only.

    Ordering / blockers for the fleet: #1721 is pure tracking now — it needs no worker action until #2012 is unblocked (Drew's call on PR #3275). The queue should not re-enqueue triage for it on the next coverage pass; the live work item is #2012, and the coverage join should key on that instead.

  12. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

effort/mMedium: expected under 1 day of workkind/questionQuestion or design decision to resolvemeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/lowNice to have; do when convenientsource/humanFiled directly by a humantask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions