Skip to content

XMPP MUC bridge + headless OpenRouter chat agent (prototypes)#11

Open
friedenberg wants to merge 2 commits into
masterfrom
claude/spinclass-xmpp-prototype-ch8gfh
Open

XMPP MUC bridge + headless OpenRouter chat agent (prototypes)#11
friedenberg wants to merge 2 commits into
masterfrom
claude/spinclass-xmpp-prototype-ch8gfh

Conversation

@friedenberg

Copy link
Copy Markdown

Two XMPP prototypes built on trapeze's existing mellium.im/xmpp client.

Prototype 1 β€” MUC ↔ clown-chat bridge

Lets a human in an XMPP client converse with an agent running under a spinclass/clown session, one MUC room per session.

  • internal/xmpp/muc.go β€” ConnectMUC joins a room (driven through a mux so join presence is observed), SendGroup posts groupchat, incoming bodies route to a handler with self-echo / subject / history-replay filtered. Shares session negotiation with the 1:1 path.
  • internal/xmppbridge + trapeze xmpp-bridge β€” one-room ↔ one-channel bridge. Inbound groupchat β†’ clown chat send; outbound polls clown chat read --json and posts agent messages back. Shells out to clown (does not link it); runs with its own clown identity so its relays self-suppress on read.
  • Unit tests (fake clown) + an env-gated MUC integration test (two occupants: delivery + self-echo suppression).

Prototype 2 β€” headless OpenRouter chat agent

trapeze xmpp-agent: a 1:1 XMPP chat bot that answers each DM with an OpenRouter completion (pure conversational, no TUI, no tools). This is the trapeze half of clown's --provider trapeze.

  • internal/openrouter β€” minimal OpenAI-compatible /chat/completions client.
  • internal/xmppagent β€” the loop: incoming messages enqueued off the serve goroutine and handled by a worker (avoids the mellium send-from-handler deadlock); per-peer bounded history; errors reported back to the peer.
  • Tests: openrouter client (httptest) + agent loop (history, per-peer isolation, error notice, bound).

Verification

go build / go test / go vet pass for all new packages. The live XMPP/OpenRouter round-trips need a real server + key; see the dev harness in circus/zz-pocs/xmpp-muc-dev/.

Related

  • amarbel-llc/circus β€” krone Prosody + dev harness + architecture docs
  • amarbel-llc/clown β€” --provider trapeze
  • amarbel-llc/spinclass β€” session-lifecycle integration note

πŸ€– Generated with Claude Code

https://claude.ai/code/session_01U5aBpoX43KwauCMRMR5UPR


Generated by Claude Code

claude added 2 commits June 17, 2026 14:45
Add a Multi-User Chat client and a MUC<->clown-chat bridge so a human in
an XMPP client can converse with an agent running under a spinclass/clown
session, with one MUC room per session.

- internal/xmpp/muc.go: ConnectMUC joins a room via mellium's muc package
  (driven through a mux so join presence is observed), SendGroup posts a
  groupchat message, and incoming bodies route to a GroupMessageHandler
  with self-echo / subject / history-replay filtered. Shares session
  negotiation with the 1:1 path via negotiateSession.
- internal/xmppbridge: one-room <-> one-channel bridge. Inbound groupchat
  -> `clown chat send`; outbound polls `clown chat read --json` and posts
  agent messages back. Shells out to clown (does not link it), running
  with its own clown identity so its relays self-suppress on read.
- trapeze xmpp-bridge subcommand wiring it up.
- Unit tests for the bridge wiring (fake clown) and an env-gated MUC
  integration test (two occupants, delivery + self-echo suppression).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01U5aBpoX43KwauCMRMR5UPR
Add a headless, pure-conversational XMPP agent: `trapeze xmpp-agent` logs
in as a 1:1 XMPP chat bot and answers each direct message with an
OpenRouter chat completion (per-peer history, no TUI, no tools). This is
the trapeze half of clown's headless `trapeze` provider (prototype 2).

- internal/openrouter: minimal OpenAI-compatible /chat/completions client
  (default base https://openrouter.ai/api/v1), pure chat β€” no tools/stream.
- internal/xmppagent: the loop. Incoming messages are enqueued off the
  XMPP serve goroutine and processed by a worker (avoids the mellium
  send-from-handler deadlock); per-peer bounded history; errors are
  reported back to the peer.
- trapeze xmpp-agent subcommand; reads OPENROUTER_API_KEY/MODEL/BASE_URL
  and TRAPEZE_XMPP_PASSWORD from env as fallbacks.
- Tests: openrouter client (httptest) and the agent loop (fake LLM/sender:
  history, per-peer isolation, error notice, history bound).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01U5aBpoX43KwauCMRMR5UPR
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