Plugin previously had no way for an agent to send text into a specific
channel proactively — outbound went only through the channel-reply
path (responds to the channel that woke the agent). discussion-complete
internally called client.postMessage but only for the close-time
summary, no general-purpose surface.
Three new tools (+ declare existing fabric-canvas / fabric-channel that
were registered but missing from contracts.tools so agents couldn't
see them per the openclaw plugin contract):
* fabric-send-message {guildNodeId, channelId, content}
→ {ok, messageId, seq}
Author = calling agent. Use for ARD broadcasts, follow-ups in a
different channel, etc.
* fabric-channel-list {guildNodeId, nameFilter?, xType?, includeClosed?}
→ {ok, count, channels[]}
Backend filters to public + member channels; nameFilter is client-
side case-insensitive substring; xType / includeClosed apply post-
fetch. Returns id/name/xType/lastSeq so callers can pipe into the
other tools.
* fabric-message-history {guildNodeId, channelId, seqFrom?, seqTo?, limit?}
→ {ok, page, messages[]}
Tail-by-default: omit seqFrom/seqTo and the tool fetches the
channel head from listChannels then asks for [head-limit+1, head].
Limit default 20, max 200. Backend rejects non-participants.
Plus 3 supporting client methods (listChannels, listMessages — both
GET via existing req helper).
contracts.tools updated to declare these 5 (3 new + 2 previously-
silent ones). Verified earlier in sim restart logs: openclaw warned
'plugin tool is undeclared (fabric): fabric-canvas / fabric-channel'
so agents couldn't use them despite registerTool firing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
86 lines
2.9 KiB
JSON
86 lines
2.9 KiB
JSON
{
|
|
"id": "fabric",
|
|
"kind": "channel",
|
|
"channels": ["fabric"],
|
|
"name": "Fabric",
|
|
"description": "Fabric channel plugin — OpenClaw agents speak in Fabric guilds",
|
|
"activation": {
|
|
"onStartup": true
|
|
},
|
|
"contracts": {
|
|
"tools": [
|
|
"fabric-register",
|
|
"create-chat-channel",
|
|
"create-work-channel",
|
|
"create-report-channel",
|
|
"create-discussion-channel",
|
|
"discussion-complete",
|
|
"fabric-canvas",
|
|
"fabric-channel",
|
|
"fabric-send-message",
|
|
"fabric-channel-list",
|
|
"fabric-message-history"
|
|
]
|
|
},
|
|
"configSchema": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"identityFilePath": {
|
|
"type": "string",
|
|
"description": "Path to the agent identity registry JSON (agentId -> Fabric API key). Default ~/.openclaw/fabric-identity.json"
|
|
},
|
|
"debugMode": { "type": "boolean", "default": false }
|
|
},
|
|
"required": []
|
|
},
|
|
"channelConfigs": {
|
|
"fabric": {
|
|
"schema": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"centerApiBase": {
|
|
"type": "string",
|
|
"description": "Fabric Center API base, e.g. http://localhost:7001/api"
|
|
},
|
|
"commandsSyncKey": {
|
|
"type": "string",
|
|
"minLength": 1,
|
|
"description": "Shared secret that must equal the guild's FABRIC_BACKEND_GUILD_COMMANDS_SYNC_KEY. Required to register the slash-command catalog (Guild C-2). Read it from the guild via: docker exec fabric-backend-guild node dist/cli/print-commands-sync-key.js"
|
|
},
|
|
"coalesce": {
|
|
"type": "boolean",
|
|
"description": "Merge a split agent turn (text → thinking/tool → text) into ONE Fabric message. Flushed deterministically on the agent_end hook. Default true; false = raw per-segment posting."
|
|
},
|
|
"dmSecurity": { "type": "string" },
|
|
"dmPolicy": { "type": "string" },
|
|
"enabled": { "type": "boolean" },
|
|
"allowFrom": { "type": "array", "items": { "type": "string" } },
|
|
"defaultAccount": { "type": "string" },
|
|
"accounts": {
|
|
"type": "object",
|
|
"description": "agent = account; key is the openclaw agentId",
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"fabricApiKey": { "type": "string" },
|
|
"centerApiBase": { "type": "string" },
|
|
"enabled": { "type": "boolean" },
|
|
"dmPolicy": { "type": "string" },
|
|
"allowFrom": { "type": "array", "items": { "type": "string" } }
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"required": ["commandsSyncKey"]
|
|
},
|
|
"uiHints": {
|
|
"centerApiBase": { "label": "Center API base" },
|
|
"commandsSyncKey": { "label": "Commands sync key" }
|
|
}
|
|
}
|
|
}
|
|
}
|