Thin agent-facing wrapper over the Guild backend's x-fabric-system-key path (see [[reference_fabric_system_msg_api]]). Posts a message into a specific channel as the guild sentinel author (00000000-0000-0000-0000-000000000000), not as the calling agent. Use case driver: Dialectic recruitment broadcasts. ClawSkills' `analyze-intel` Step 4 currently posts via `fabric-send-message` which attributes the message to the proposing agent; that's fine for DM fallbacks but for announce-channel broadcasts the message should look like a system lifecycle event, not a personal ping. Without this tool, the only way to get a system-authored post was the close-sub-discussion internal path — generic broadcast use cases had no door. Tool shape mirrors fabric-send-message but: - Reads channels.fabric.commandsSyncKey from openclaw config; empty → ok:false with a configuration error (no silent fallthrough to agent-bearer posting). - Optional `wakeupUserId` plumbs through to the backend's emitMessageTargeted path: precise wake one recipient or fully silent broadcast (default). For announce-channel broadcasts the silent path is right — agents poll/discover, they shouldn't be woken on broadcast. - Caller doesn't need to be a member of the channel (backend isSystem branch skips assertParticipant). Guild membership is still required because we resolve guild.endpoint from the agent's session. Manifest gets the tool name so it surfaces in the agent registry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
91 lines
3.1 KiB
JSON
91 lines
3.1 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",
|
|
"create-sub-discussion",
|
|
"discussion-complete",
|
|
"close-sub-discussion",
|
|
"fabric-canvas",
|
|
"fabric-channel",
|
|
"fabric-send-message",
|
|
"fabric-send-sys-msg",
|
|
"fabric-channel-list",
|
|
"fabric-message-history",
|
|
"fabric-guild-list",
|
|
"fabric-channel-set-purpose"
|
|
]
|
|
},
|
|
"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" }
|
|
}
|
|
}
|
|
}
|
|
}
|