Skip to content

One OpenClaw Gateway session per Buzz channel, thread, and DM - #46

Open
jmfcamp wants to merge 1 commit into
mainfrom
cursor/openclaw-per-conversation-session-8e39
Open

One OpenClaw Gateway session per Buzz channel, thread, and DM#46
jmfcamp wants to merge 1 commit into
mainfrom
cursor/openclaw-per-conversation-session-8e39

Conversation

@jmfcamp

@jmfcamp jmfcamp commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Summary

Hula last-mile bots (buzz-acp@captain, etc.) exec one openclaw acp --session agent:<id>:buzz child for the life of the unit. That flag is process-lifetime defaultSessionKey. Every room mentioning Captain was writing into one Control UI session named ACP.

buzz-acp already does per-channel session/new. It never set _meta.sessionKey, so OpenClaw’s mapper (session-mapper.ts) fell through to --session agent:<id>:buzz. _meta.sessionTitle / compose_session_title (Agent · #channel) is display-only and does not split Gateway store files.

This change sends a stable Gateway key on every conversation session/new:

{ "_meta": { "sessionKey": "<stable key>", "sessionTitle": "<existing composed title>" } }

Key shape (Slack-like, buzz namespace, UUIDs never names):

Conversation Key
Channel (stream/private/group, no thread) agent:<agentId>:buzz:channel:<channelUuid>
Thread agent:<agentId>:buzz:channel:<channelUuid>:thread:<rootEventId>
DM (hidden NIP-29 t=dm) agent:<agentId>:buzz:direct:<channelUuid>
DM thread agent:<agentId>:buzz:direct:<channelUuid>:thread:<rootEventId>
Heartbeat omitted — falls through to --session agent:<id>:buzz

Thread id is the existing NIP-10 ThreadTags.root_event_id on the last batch event (parse_thread_tags). Same inbound again reuses the key. Different channel / thread / DM differ.

SessionState now caches ACP sessionId per conversation (channel + optional thread root) so a thread gets its own session/new instead of reusing the parent channel session. One last-mile child still hosts all of them — we do not respawn openclaw acp per room.

--session agent:<id>:buzz stays on the process. Existing leftover history is not deleted; new work does not keep appending there. Agent id is parsed from that leftover flag (--session / --session=).

Related issue

Hula last-mile OpenClaw session grain (VPS buzz-acp@*). None found in-repo.

Unchanged (on purpose)

  • No --url on openclaw acp
  • No OpenClaw Gateway config, channels.buzz, keys, install.sh, or subscribe=all
  • No playground, HTML preview, or branding
  • DM mention-gate (require_mention false only for channel_type == dm)
  • Last-mile publish still targets the triggering channel_id / thread
  • ignore_self stays on

VPS deploy: rebuild Linux buzz-acp into ~/.local/bin/buzz-acp and restart mo / captain / korg / quasar. A Desktop rebuild is not enough.

Test plan

  • Host-free key tests in crates/buzz-acp/src/openclaw_session.rs: stable per (agent, channel, thread-or-none, DM); different conversations differ; same inbound matches; leftover agent:<id>:buzz is not a conversation key; from_batch uses root_event_id
  • session/new wire test: _meta.sessionKey + _meta.sessionTitle on one request
  • SessionState: thread conversation does not reuse or invalidate the parent channel session
  • cargo test -p buzz-acp --lib (846 passed)
  • cargo clippy -p buzz-acp --lib -- -D warnings
  • After VPS binary swap + unit restart: mention Captain in two channels → two Control UI sessions; mention in a thread → third session, not the parent channel; mention again in the same room → same session reused; DM still wakes without @ and replies land in that DM
Open in Web Open in Cursor 

Last-mile OpenClaw was binding every room to the process leftover
`--session agent:<id>:buzz`. Conversation session/new now sends
`_meta.sessionKey` so each channel, thread, and DM gets a stable
Gateway key. Heartbeats still fall through to that leftover. The
stdio child is not respawned per room.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: jmfcamp <jmfcamp@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants