跳到正文
cccskills
免费在 GitHub 公开

slack-a2a-rooms

Create Slack group DMs where a human and multiple NanoClaw bots can converse. Admit bot messages only in approved rooms, use mentions to direct replies, and limit consecutive bot messages until a human speaks.

中文简介正在准备中。当前显示英语简介。

原文查看原文说明

Agent-to-agent Slack rooms — a group DM (MPIM) holding a human plus two or more NanoClaw sibling bots, where each bot hears the room over its own Socket Mode connection. Registers the admission policy on the Slack channel's bot-inbound guard so bot-authored inbound is admitted only for rooms allowlisted in SLACK_A2A_ROOMS (re-attributed as slack:bot:<botId>, hop-limited via SLACK_A2A_MAX_HOPS), plus scripts/open-a2a-room.ts to open a room and register it.

集成工具Slack
查看安装方法

适用场景

  • Discussing a topic with multiple bots in one Slack group DM
  • Creating a room for a human and two NanoClaw bots
  • Allowing bot messages only in selected rooms
  • Limiting consecutive bot messages during agent conversations

包含的文件(4)

  • SKILL.md11.8 KB
  • scripts/open-a2a-room.ts7.7 KB
  • src/channels/slack-a2a.test.ts9.0 KB
  • src/channels/slack-a2a.ts5.4 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Slack agent-to-agent rooms (SLACK_A2A_ROOMS)

Lets two or more NanoClaw Slack bots talk to each other — and to a human — in a shared group DM (MPIM). Empirically established against live Slack: conversations.open with users=[<human>, <other bot user id>…] works from a bot token holding mpim:write and returns an is_mpim channel, and bots receive each other's messages over their own Socket Mode connections as plain message events with channel_type: "mpim", bot_id set, and subtype null.

Canonical home. This directory on main is the skill's canonical source — the setup wizard and any direct apply read it from the checkout. The copy on the channels branch is a compatibility mirror for older checkouts whose setup fetches companions from there; edits land here, never there.

Where sibling-bot messages die today. The adapter/Chat-SDK stack's only bot filter is self-protection (isMe); a sibling bot's message arrives with isMe: false, isBot: true and flows into the Slack channel's bot-inbound guard (src/channels/slack-a2a-guard.ts, installed with /add-slack), which drops all bot-authored inbound at the bridge boundary by default — before the router, before any sender-approval flow. The guard exposes a single admission seam, setBotInboundPolicy; this skill registers the policy that opens it up selectively:

  • Rooms listed in SLACK_A2A_ROOMS: bot-authored inbound passes, attributed to the user id slack:bot:<botId>, under a consecutive-hop limit.
  • Everywhere else: bot-authored inbound stays dropped at the bridge, exactly as the guard's default already does.

Loop safety. After N consecutive bot-authored inbound messages in an A2A room without a human message (N = SLACK_A2A_MAX_HOPS, default 6), further bot messages are dropped with a log line until a human speaks. The counter is per bot identity and per room; any human message resets it.

Requires:

  • The Slack channel installed (/add-slack), current enough to ship the bot-inbound guard (src/channels/slack-a2a-guard.ts with the setBotInboundPolicy seam). The default drop arrives with that payload; this skill only adds the allowlisted-room admission on top.
  • At least two Slack bot identities on this host (or sibling bots on other hosts sharing the workspace). Named identities are registered natively by the adapter from SLACK_INSTANCES — see the slack-multi-instance skill for the env-key format. scripts/open-a2a-room.ts reads tokens by that convention (SLACK_BOT_TOKEN_<NAME>; default → SLACK_BOT_TOKEN).
  • Every participating app's manifest must carry the MPIM scopes and event: mpim:write (open the room), mpim:history + mpim:read (see it), and the message.mpim bot event (hear it). Apps provisioned through the managed flow (apps.manifest.create + apps.managedInstall) already include all of these.

Apply

1. Verify the installed Slack channel ships the bot-inbound guard

The policy module copied next imports setBotInboundPolicy from the installed src/channels/slack-a2a-guard.ts. On a Slack payload that predates the guard, that import takes down the channel barrel — and with it every adapter — so verify the seam first. If the check fails, stop: re-run /add-slack from a channels branch that ships the guard, then re-apply this skill.

grep -sq 'export function setBotInboundPolicy' src/channels/slack-a2a-guard.ts || { echo 'slack-a2a-rooms: src/channels/slack-a2a-guard.ts is missing or does not export setBotInboundPolicy. Installing anyway would break the channel barrel and take down every channel adapter. Update the installed Slack channel first (re-run /add-slack from a channels branch that ships the bot-inbound guard), then re-apply this skill.' >&2; exit 1; }

2. Copy the policy module, its guard test, and the room-opener script

This skill ships three files alongside this document; copy them into the tree at the same relative paths (overwrite; the skill's copies are canonical):

src/channels/slack-a2a.ts
src/channels/slack-a2a.test.ts
scripts/open-a2a-room.ts
  • slack-a2a.ts — the admission policy: SLACK_A2A_ROOMS / SLACK_A2A_MAX_HOPS parsing (re-read with a ~30s cache so a freshly opened room needs no restart), the per-room, per-identity consecutive-hop counter with human reset, and the slack:bot:<botId> re-attribution. The module registers itself onto the guard's admission seam on import.
  • slack-a2a.test.ts — the guard: drives the real channel barrel and the real bot-inbound guard end-to-end (see step 4 for what it pins).
  • open-a2a-room.ts — operator CLI to open a room (see Configuration).

3. Register the policy module

Append the self-registration import to the channel barrel (skipped if the line is already present). Appending at the end keeps it after the Slack channel's own imports:

import './slack-a2a.js';

4. Build and validate

Build first — it guards the typed setBotInboundPolicy call against guard drift. The test imports the real channel barrel (a deleted or broken barrel line goes red) and asserts the policy end-to-end: allowlisted-room admission with slack:bot:<botId> re-attribution, non-listed-room drop, the hop limit with human reset, per-room/per-identity budgets, and that a downstream throw consumes no hop budget:

pnpm run build
pnpm exec vitest run src/channels/slack-a2a.test.ts

Configuration

.env keys (both re-read with a ~30s cache — no restart needed after edits):

  • SLACK_A2A_ROOMS — comma-separated raw Slack channel ids (the MPIM ids the opener script prints, e.g. G0AAAAAAA — note MPIM ids may start with G or C depending on workspace vintage). Only these rooms admit bot-authored inbound.
  • SLACK_A2A_MAX_HOPS — consecutive bot-authored inbound messages allowed in an A2A room without a human message before further bot messages are dropped. Default 6.

Opening a room

pnpm exec tsx scripts/open-a2a-room.ts --instances dana,eli --user U0AAAAAAA

The first listed instance opens the conversation (via conversations.open with the human + the other bots' user ids, resolved through auth.test per token) and posts an intro message. The script prints the channel id and appends it to SLACK_A2A_ROOMS in .env. Without --user you get a bots-only room, which needs at least three instances (Slack collapses a two-party open into a 1:1 IM).

Letting bot senders through the access gate

The room allowlist gets bot messages to the router; the permissions module still gates them like any sender. Bot senders arrive as user id slack:bot:<botId>, which starts unknown. After the first human mention in the room auto-creates its messaging group, either set the room public:

pnpm exec tsx scripts/q.ts data/v2.db "UPDATE messaging_groups SET unknown_sender_policy='public' WHERE platform_id='slack:<channel id>'"

or keep request_approval and approve each slack:bot:<botId> sender once (or add them as members of the agent group). A private A2A room with known humans is a reasonable place for public.

<botId> is the sibling bot's user id (U…) from @chat-adapter/slack 4.40, and its bot_id (B…) before. After that upgrade, bots approved under their B… id arrive as new senders and need approving once more.

Engagement: A2A conversation is mention-driven

An MPIM is a group context in NanoClaw's channel-defaults model (Slack DMs are only D… channels), so the Slack group defaults apply: engage_mode: mention-sticky, per-thread stickiness. That means a bot replies when it is @-mentioned (then stays engaged in that thread) — it does not answer every room message. Bot-to-bot conversation is therefore mention-driven by design: bot A's reply reaches bot B's agent when it @-mentions bot B, and the chain continues only as long as each reply mentions the next speaker. Slack does not emit app_mention for bot-authored messages, but mention detection still works: the Chat SDK's text-level detector matches the bot's own <@U…> token, which the adapter deliberately leaves unresolved in the text. This is the intended loop governor alongside the hop limit — prompt the agents (group CLAUDE.md / personality) to @-mention the sibling they want an answer from, and to stop mentioning anyone when the exchange has converged.

Remove

  1. Delete the three copied files: src/channels/slack-a2a.ts, src/channels/slack-a2a.test.ts, scripts/open-a2a-room.ts.
  2. Delete the import './slack-a2a.js'; line from src/channels/index.ts.
  3. Remove SLACK_A2A_ROOMS and SLACK_A2A_MAX_HOPS from .env.
  4. Optionally re-tighten any messaging groups you set to unknown_sender_policy='public', and archive/leave the MPIMs from Slack (the rooms themselves are ordinary Slack conversations; NanoClaw holds no other state for them beyond the usual messaging-group/session rows).
  5. Rebuild (pnpm run build).

With the skill removed, the channel guard's default applies everywhere again: bot-authored inbound is dropped in every room.

Notes

  • Bot senders outside A2A rooms: the Slack channel's bot-inbound guard drops bot-authored messages in rooms not listed in SLACK_A2A_ROOMS at the bridge — before the router and before any sender-approval flow — with or without this skill applied. If an install relies on a bot sender (another workspace app posting into a channel the agent watches), add that room to SLACK_A2A_ROOMS. Human messages are never affected.
  • Access-gate story is manual. The recipe deliberately leaves letting slack:bot:<botId> senders through the gate as an operator step (public policy or per-bot approval). Should open-a2a-room.ts instead pre-create the messaging group + wirings + members via ncl so a room works with zero extra steps? That needs the host running and a choice of agent group per bot — deferred.
  • Hop-counter scope. The counter counts bot-authored inbound per bot identity (bridge instance). A bot's own outbound is invisible to it (isMe dropped upstream), so with two bots the effective conversation length is roughly 2×maxHops messages; with k bots each message increments k−1 counters. If per-room total (not per-identity) semantics are wanted, the counter needs to live host-side (router/session), not in the channel layer.
  • Cross-host rooms. For sibling bots on different NanoClaw hosts, each host needs this skill (its own allowlist entry). The opener script only handles co-hosted tokens; opening a cross-host room means running it where the first bot's token lives and adding the room id to the other host's .env manually.
  • message_changed / edited bot messages are not admitted (the adapter only forwards unfurl data for edits) — fine for v1.
  • Attribution name. The users row for slack:bot:<botId> takes whatever display name the bridge serialized (often unknown for bot events, since event.username is frequently absent and event.user is unset). A nicety would be resolving the bot's profile name via bots.info — deferred.
  • MPIM id prefix. Older workspaces mint MPIM ids starting with G, newer ones with C. The allowlist matches exact ids so both work, but the adapter's getChannelVisibility calls C… ids "workspace"-visible — cosmetic only, nothing here branches on it.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Equip NanoClaw agents to convert attached office documents into Markdown locally using Firecrawl AnyDoc. Agents can read Word, PowerPoint, Excel, and text-based PDF files without uploading them to an external parsing service.

中文简介正在准备中。当前显示英语简介。

  • Reading and summarizing attached office documents
  • Converting documents without uploading them to an external service
  • Extracting text from text-based PDFs
nanocoai/nanoclaw3.1万2026年10月22日 更新

Let a NanoClaw container agent call local models running in Atomic Chat. The skill adds an MCP server, a connection that exposes model listing and text generation as tools, while Claude continues to coordinate the work.

中文简介正在准备中。当前显示英语简介。

  • Delegate part of Claude's work to a local model
  • List models available in Atomic Chat
  • Generate an answer with a specified local model
nanocoai/nanoclaw3.1万2026年10月22日 更新

Add a read-only web dashboard for browsing NanoClaw agents, sessions, and other resources. It builds tables from command-line JSON output and includes message activity charts, recent logs, and a viewer for skills, profiles, and CLAUDE.md files.

中文简介正在准备中。当前显示英语简介。

  • Check agent and session status in a browser
  • Review message counts and daily activity
  • Read recent host logs
nanocoai/nanoclaw3.1万2026年10月22日 更新

add-codex

免费

Add Codex as the agent that plans tasks and coordinates tools in NanoClaw. Choose it for individual groups alongside Claude, with conversation history and session resume using a ChatGPT subscription or OpenAI API key.

中文简介正在准备中。当前显示英语简介。

  • Adding Codex as a NanoClaw agent provider
  • Choosing Claude or Codex for each group
  • Setting up ChatGPT or API key authentication
nanocoai/nanoclaw3.1万2026年10月22日 更新

Install Cursor as an agent backend for NanoClaw groups using its local SDK. Set up authentication and container integration so groups can use Cursor for planning, MCP tools, streaming responses, and session continuation.

中文简介正在准备中。当前显示英语简介。

  • Install Cursor as a NanoClaw agent backend
  • Configure Cursor account sign-in or API key authentication
  • Switch a specific NanoClaw group to Cursor
nanocoai/nanoclaw3.1万2026年10月22日 更新

Install a local NanoClaw dashboard to inspect agents, sessions, channels, messages, and users. It displays token usage, context usage, activity, and live logs using periodic data snapshots and a log forwarding module.

中文简介正在准备中。当前显示英语简介。

  • Checking agent and session status in one place
  • Reviewing token and context usage
  • Following live logs with level filters
nanocoai/nanoclaw3.1万2026年10月22日 更新

查看 nanocoai 的全部技能

报告此技能的问题