10 Commits

Author SHA1 Message Date
8774cfd7cc feat(fabric): coalesce a split agent turn into ONE message (deterministic)
OpenClaw delivers an agent turn whose blocks are text -> thinking/tool
-> text via multiple inbound deliver() calls (a non-text block is a
delivery boundary), so one turn became N Fabric messages.

Fix: buffer deliver() segments per channel (src/coalesce.ts) and flush
them as ONE postMessage at a deterministic boundary — the finally after
dispatchInboundReplyWithBase() resolves, which provably runs only after
every deliver() of the turn (verified: deliver,deliver -> dispatch
returned -> flush). No hooks, no timers, no idle guessing. The
agent_end hook was rejected: it fires BEFORE deliver(). gateway_stop
flushes any leftover; a long safety timeout is a leak-guard only.
channels.fabric.coalesce=false restores raw per-segment posting.

Verified on local openclaw + Fabric with a fake text/thinking/text
model: single trigger -> exactly one merged message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:15:46 +01:00
ab126825ef feat(security): commandsSyncKey is a required channel-config field (Guild C-2)
The slash-command sync secret now comes from
channels.fabric.commandsSyncKey (configSchema marks it required) and
is no longer read from FABRIC_COMMANDS_SYNC_KEY env. command-sync
resolves it from config and threads it into client.syncCommands;
when absent, sync is skipped with a clear warning. README updated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:44:25 +01:00
fc6edaabfd docs: slash-command catalog section
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 16:15:03 +01:00
fac6debfa5 feat(plugin): fabric-channel tool (members / join / leave)
One tool, three actions backed by FabricClient channelMembers (GET
/channels/:id/members -> [{userId,bypass}]), joinChannel, and new
leaveChannel (POST /channels/:id/leave).

Verified: client-level smoke against the running guild — members
initial=[tester], after join echo2 present, after leave echo2 gone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:33:47 +01:00
aaabb0ddb0 feat(plugin): fabric-canvas tool; fabric-register env=AGENT_ID only
- bin/fabric-register.mjs: only AGENT_ID is read from the environment;
  --api-key is flag-only (no FABRIC_API_KEY); dropped FABRIC_CENTER_API_BASE
  / FABRIC_IDENTITY_FILE / OPENCLAW_PATH env fallbacks (flags + sensible
  defaults; --center still falls back to openclaw.json).
- New fabric-canvas tool (one tool, four actions): read / share / update /
  close the channel's single pinned canvas. Backed by FabricClient
  get/share/update/removeCanvas (GET/PUT/PATCH/DELETE; empty 2xx body ->
  null). update/close are sharer-only server-side.
- README updated.

Verified: client-level smoke against the running guild —
read(empty→null) → share(v1) → read → update(v2) → close(→null) all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 15:28:13 +01:00
26c12533fb refactor(plugin): fabric-register is a script, not a tool
Binding an agent's Fabric API key was an OpenClaw tool; make it a
self-contained Node script installed to ~/.openclaw/bin/fabric-register
instead.

- bin/fabric-register.mjs: no plugin deps; AGENT_ID env wins, else
  --agent-id required; --api-key validated via POST /auth/agent/login;
  on success upserts ~/.openclaw/fabric-identity.json (format matches
  IdentityRegistry). Flags/env for center, identity-file, openclaw-path.
- install.mjs: copy the script to ~/.openclaw/bin (chmod 0755) on
  install, remove on uninstall; Next-steps updated.
- tools.ts: drop the fabric-register tool; ctxGuild error now points to
  the script / static accounts config.
- README updated.

Verified: missing-id -> exit 2; --agent-id and AGENT_ID both bind and
write a valid identity file; bad key -> 401, no write.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 13:12:48 +01:00
9d0fa1d5c8 docs: rewrite README to match current architecture
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 12:53:25 +01:00
25473384d8 docs: require cfg.bindings entry for account->agent routing
agent=account only routes correctly when openclaw cfg.bindings has a
{agentId, match:{channel:fabric, accountId}} entry; else falls back to
the default agent. Verified: with the binding, account echo -> agent
echo, reply posted back as the agent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:35:49 +01:00
9221664428 feat: Fabric channel plugin for OpenClaw (Phase 1, B1)
OpenClaw channel plugin: defineChannelPluginEntry + createChatChannelPlugin.
Inbound via channel-turn kernel (wakeup -> admission: true=dispatch,
else drop+recordHistory). One Fabric socket per agent identity in the
plugin runtime (no sidecar). Center API-key agent auth. Tools:
fabric-register, create-{chat,work,report,discussion}-channel,
discussion-complete (post summary + close channel).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 17:13:26 +01:00
nav
21475eb72b chore: initialize repository 2026-05-08 14:25:51 +00:00