Skip to content

Follow-up (#2229): expose sessions_spawn to headless/CLI OpenClaw sessions (packaging patch) #2257

Open

Description

@dezren39

Follow-up to #2229 (method 2 of 3). Method 3 — the opencode-route provider front — shipped as the priority build (PR #2250, live-proven). This method was descoped by Drew on 2026-10-29 to a follow-up: sometime soon / when an OpenClaw-origin workload needs to spawn subagents from headless/CLI sessions.

What it adds

sessions_spawn exposed to headless/CLI OpenClaw sessions, so a CLI-driven agent turn can spawn subagents — including ACP-runtime targets such as the opencode-acp entry (the method-1 follow-up), whose live proof depends on this surface.

Determination (already made, 2026-10-29 — this is a packaging patch, not config)

  • In the pinned OpenClaw 2026.10.7 dist, createSessionsSpawnTool is gated by !embedded || options?.allowGatewaySubagentBinding === true (chunk openclaw-tools-QaFYBVQi.mjs). isEmbeddedMode() is a process-local flag set only by EmbeddedTuiBackend.start(), and openclaw agent CLI turns run through that embedded backend even when gateway-attached. allowGatewaySubagentBinding: true is passed only by gateway/channel-side runners. No config key or tool profile feeds either flag — the tool sits in the "sessions" group with profiles ["coding","messaging"]; profile is not the blocker.
  • Empirically absent on every surface tried: CLI via the live gateway, CLI --local, and a server-side chat.send turn (the agent reported sessions_spawn is not in its loadable tool set; the deferred-tool layer answers select:sessions_spawn with "No deferred tool matched").
  • Route: nix-openclaw's instance options expose gatewayPath + gatewayPnpmDepsHash; when gatewayPath is set, the module builds the gateway from that source. So: commit a .patch against the pinned upstream source flipping the gate condition, wire gatewayPath to a patched-source derivation in the fleet config, and document plainly that it is a source patch carried by the packaging, not an upstream config option.

Proof when built

Patch a copied dist tree first for a fast mechanism proof (spawn with agentId="opencode" and agentId="opencode-acp" → check acp_sessions in the OpenClaw state plus a new row in OpenCode session_v2), then land the durable source patch.

Activity

  1. developing-today commented on Oct 29, 2026

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

    @dezren39
    MemberAuthor

    Drew's directive (2026-10-29 21:44 CDT, main chat): "I want the other options built and functional." This issue (headless/CLI sessions_spawn exposure) is one of those options — build it and prove it functional alongside #2256. Scope note (Drew, 21:45 CDT): sessions_spawn is explicit task dispatch, so OpenCode running the task is correct there; the routing-only principle applies to the opencode-route model door (see the new follow-up issue), not to dispatch paths.

  3. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    Triage @ current main (2026-11-03) — still live, fix path re-confirmed

    Verdict: the gap is real on the pinned package and on upstream main. Nothing has shipped since the 2026-10-29 determination; this issue is a scoped, buildable packaging task, not a config task.

    Evidence (fresh at this triage)

    • Pinned dist still gates the tool. Installed gateway openclaw-2026.10.7:
      /nix/store/f2crizywkx7d7k8831xmnhjx4kcm2ki4-openclaw-gateway-2026.10.7/lib/node_modules/openclaw/dist/openclaw-tools-QaFYBVQi.mjs:16699
      still reads !embedded || options?.allowGatewaySubagentBinding === true ? createSessionsSpawnTool({…}) : null.
    • Upstream main still gates it the same way. src/agents/openclaw-tools.ts:646-647 (raw main, fetched 2026-11-03) carries the identical condition.
    • Still no config key feeds it. allowGatewaySubagentBinding is an internal option param (src/plugins/tools.ts:89,111, src/agents/runtime-plugins.ts:61,86,188), not a config keyspace entry. A settings/profile workaround does not exist — as the issue body already concluded.
    • Version bump does not fix it. npm openclaw latest is 2026.10.10; pinned nix package is 2026.10.7; upstream main is unchanged, so a plain bump buys nothing.
    • The packaging escape hatch is still the only one. nix-openclaw pin 4b261b08c173467dc41db7b43d8265529c435055 (2026-10-30) is the repo HEAD today; gatewayPath + gatewayPnpmDepsHash remain the only source override (nix/modules/home-manager/openclaw/options-instance.nix:61-71).
    • No competing work. No open PR/branch claims Follow-up (#2229): expose sessions_spawn to headless/CLI OpenClaw sessions (packaging patch) #2257 (searched issues, PRs, branches). The only adjacent open work is draft PR Wire OpenClaw ACP adapters to Nix runtime plugin #3275 (ACP adapter wiring, Nix-package the Claude/Codex ACP adapters — repoint OpenClaw acpx off tmp/plugin-captures #1711) — it touches adapters, not this gate; do not fold this into it.

    One design decision blocks implementation

    gatewayPath is typed nullOr str, documented "dev only", and consumed as builtins.path { path = inst.gatewayPath; } (instance.nix:60-63) — it must be a real filesystem path at evaluation time. A pkgs.applyPatches-derived store path is therefore IFD-fragile: it only exists after it is realized, so home-manager switch would fail on a cold store and succeed on a warm one. Options, in order of cleanliness:

    1. Upstream nix-openclaw: add a gatewayPatches (or gatewaySrc) option to the instance module — then this repo carries only a .patch file. Needs a PR to openclaw/nix-openclaw + a pin bump. Cleanest, slowest.
    2. Follow-able fork pin: point the nix-openclaw flake input at a developing-today fork carrying the patch + option, owned by us, maintained with the fork-sync discipline. No upstream dependency. Recommended for this week.
    3. Pre-realized store path: build the patched source first, then point gatewayPath at its store path. Works, but makes the rebuild order-dependent and rejects one-command rebuilds. Not recommended.

    Recommendation: (2) now, (1) as upstream follow-through. This is a packaging-mechanism call inside the worker's remit, so it is not escalated; the follow-up build task below carries the decision.

    Implementation scope when built

    1. patches/openclaw/sessions-spawn-headless.patch — one hunk on src/agents/openclaw-openclaw-tools.ts at the !embedded || gate (exact hunk context: openclaw-tools.ts:646). Simplest faithful change for this fleet: drop the embedded exclusion at build time, keeping options?.allowGatewaySubagentBinding intact. Patch header must state it is carried by packaging, not an upstream config, and name the upstream lines it targets.
    2. Packaging wiring per option (2) above: fork pin in flake.nix/flake.lock + programs.openclaw.instance.gatewayPath/gatewayPnpmDepsHash in home/openclaw/default.nix (currently neither is set).
    3. Proof (mechanism-first, per the issue body): patched tree → CLI turn spawning agentId="opencode" and agentId="opencode-acp" → acp_sessions rows in OpenClaw state + new rows in OpenCode session_v2; also confirm select:sessions_spawn no longer answers "No deferred tool matched" and the tool appears in the CLI turn's loadable set (/tools).

    Ordering, blockers, risks

  4. added
    kind/featureNew feature or capability request
    priority/highImportant and time-sensitive
    meta/follow-upFollow-up spun out of earlier work
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 3, 2026
  5. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    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/none). 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

  6. added
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  7. 38 remaining items

  8. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 3, 2026
  9. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: picked up

    • Agent: repo-worker-code (OpenChamber scheduled lane)
    • Session / ID: ses_e5e5c92c9fcffeeodrfOl1h0DB / queue task 8042
    • Found via: atomic queue claim
    • Task: Resume the headless sessions_spawn packaging fix from its implementation_complete checkpoint.
    • Expectation: Revalidate ownership and current PR state before touching the saved branch or worktree.
  10. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Nov 3, 2026
  11. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: parked

  12. added
    queue/blockedQueue or user escalation state
    status/blockedQueue or user escalation state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 3, 2026
  13. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1 — task 8042 blocked by lane code-m, 2026-11-03. Hard stop re-verified fresh: PR #5056 (feat(openclaw): pin nix-openclaw fork carrying the sessions_spawn headless patch, branch queue/8042-2257-sessions-spawn-headless) is OPEN, non-draft, authored and assigned to Drew (dezren39). Per the runbook, a Drew-owned PR is never touched — no PR internals, branch, or worktree were inspected or modified by this lane (the OpenChamber lane reached the same verdict at 22:14Z and parked; this claim arrived after that park expired, so the task is now blocked instead of re-parked). Resume condition: ownership of PR #5056 transfers, or Drew explicitly hands the work off under fleet protocol; then continue from the saved implementation_complete checkpoint (laptop worktree /home/user/git/fleet/8042-2257).

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

Metadata

Metadata

Assignees

Labels

kind/featureNew feature or capability requestmeta/follow-upFollow-up spun out of earlier workpriority/highImportant and time-sensitivequeue/blockedQueue or user escalation statesource/creatorFiled by the new-issue-creator jobstatus/blockedQueue or user escalation statetask/triageQueue packet kind: verify, reproduce, and route this itemwork/assignedQueue worker lifecycle state

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions