Skip to content

Commit d5ea8cf

Browse files
tylerslatonmxmzb
andcommitted
docs: explain personal toolkit setup and approval behavior
Document shared and personal scopes, connection flows, auth requirements, deployment configuration, and the coordinated runtime and Channel upgrade. Co-authored-by: Maxim Zubarev <maxim.zubarev@icloud.com>
1 parent cebdcb8 commit d5ea8cf

3 files changed

Lines changed: 289 additions & 36 deletions

File tree

‎AGENTS.md‎

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ files.
4242
| Agent | `agent/agent.py` | LangGraph deep agent served over AG-UI |
4343
| AG-UI adapter | `agent/agui.py` | Slack recursion limit and user-facing graph-stop handling |
4444
| Persona | `agent/prompts/` | `system.py` is the base system prompt |
45-
| Approval gate | `agent/write_confirmation.py` | Emits `confirm_write` before Linear or Notion writes |
45+
| Approval gate | `agent/write_confirmation.py` | Emits `confirm_write` before a Linear, Notion, or Composio write |
46+
| Composio | `agent/composio_tools/` | Toolkit sessions, per-person identity, effect classification, connect links |
4647
| Coder | `agent/coding/` | GitHub credentials, Daytona sandbox, repository publish tools, coder prompt |
4748
| Coder skills | `agent/coding/skills/` | Committed skills. Do not put them in `agent/skills/` |
4849
| Deployment | `.railway/railway.ts` | Two services, declared as code |
@@ -80,10 +81,21 @@ you actually ran; do not claim a check that did not run.
8081
- **Channel names claim deliveries.** Two runtimes declaring the same name in one
8182
Intelligence project race per delivery and the loser is silently starved. Give a
8283
local runtime its own project, key, and Channel name — never reuse `open-tag`.
84+
- **Socket Mode stays off on the Slack app.** With it on, Slack delivers events
85+
over the socket and stops posting them to the Request URL, so Intelligence —
86+
and therefore your runtime — receives nothing while the app still reads as
87+
installed. Do not turn it on to "test locally"; there is nothing here that
88+
needs it.
89+
- **Personal Composio toolkits are Slack-only, and need a non-empty
90+
`AGENT_AUTH_HEADER` on both services.** The speaker arrives as
91+
`forwardedProps.channelActor`, and `agent/composio_tools/state.py` is the one
92+
place that decides what counts as an identity — `agent/agui.py` applies it to
93+
every run. `agent/agent_auth.py` treats an empty secret as unconfigured and
94+
refuses to mint a connect link on that basis.
8395
- **Slash commands and modals are registered but unverified on the managed
84-
path.** Delivery depends on the generated Slack manifest declaring
85-
`slash_commands`; as of the 0.7.0 verification it declared none. Do not describe
86-
them as working without sending a real command.
96+
path.** Delivery depends on the generated Slack manifest, which Intelligence
97+
produces server-side — nothing in this repository decides it. Do not describe
98+
them as working without sending a real command against your own Channel.
8799
- **Trigger routing is not symmetric.** A mentioned turn goes to `onMention` if
88100
registered and falls back to `onMessage`; an unmentioned turn reaches
89101
`onMessage` only. `onMention` subscribes the thread. Always verify with a
@@ -94,12 +106,20 @@ you actually ran; do not claim a check that did not run.
94106

95107
- **Pinned SDK versions live in `package.json` and nowhere else.** Do not restate
96108
`@copilotkit/channels` or `@copilotkit/runtime` versions in prose or in a test
97-
assertion. Three copies of `0.7.0` drifted at once when the deps were bumped,
98-
and one of them broke the build. `app/cleanup.test.ts` asserts the pin *shape*
109+
assertion. Three copies of an earlier pin drifted at once when the deps were
110+
bumped, and one broke the build. `app/cleanup.test.ts` asserts the pin *shape*
99111
for this reason.
100-
- **No Slack or Teams credential belongs in this repository.** Intelligence owns
101-
the adapters. One root `.env` configures both services; the Python agent loads
102-
it explicitly for local development.
112+
- **No platform credential belongs here.** Intelligence owns the adapters, so no
113+
Slack or Teams token, signing secret, or app token goes in this repository and
114+
this app attaches no adapter of its own. It briefly held `SLACK_BOT_TOKEN` and
115+
`SLACK_APP_TOKEN` so a Composio connect link could reach one person privately;
116+
the managed adapter in the pair pinned in `package.json` does that itself, and
117+
the pair was worse than useless — a second Slack ingress answered every message
118+
twice, and its Socket Mode connection stopped Slack delivering events to
119+
Intelligence from 24 August until it was turned off. Both tokens and the
120+
adapter are gone from this repository; `app/server.test.ts` pins the removal.
121+
One root `.env` configures both services; the Python agent loads it explicitly
122+
for local development.
103123
- **`@copilotkit/channels` and `@copilotkit/runtime` upgrade together.** They ship
104124
as a tested pair.
105125
- Commit messages follow the conventional prefixes already in the log (`feat:`,

‎README.md‎

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,16 @@ For Microsoft Teams, use `--adapter teams`. Two Teams steps stay yours because
146146
nothing can work around them: granting tenant admin consent, and uploading the
147147
app package through **Apps → Manage your apps → Upload an app**.
148148

149-
#### Three Slack details that cost the most time
149+
#### Four Slack details that cost the most time
150150

151151
These apply on either path. Follow the CLI's emitted `nextAction` rather than
152152
remembered Slack steps, and watch for:
153153

154+
- **Leave Socket Mode off.** Managed delivery never uses it, and a Slack app with
155+
Socket Mode on installs green and delivers nothing to the Request URL — so
156+
nothing reaches Intelligence and nothing reaches your runtime. It is the one
157+
failure here that looks exactly like success. See
158+
[`setup.md`](./setup.md#leave-socket-mode-off).
154159
- After creating the app from the link, open **OAuth & Permissions** and choose
155160
**Reinstall to Workspace**. Slack applies the manifest's real scopes only on
156161
reinstall.
@@ -320,7 +325,8 @@ agent (Python + LangGraph deepagents)
320325
├── GitHub MCP (optional, read-only)
321326
├── PostHog MCP (optional, read-only)
322327
├── Linear MCP (optional)
323-
└── Notion MCP (optional remote server)
328+
├── Notion MCP (optional remote server)
329+
└── Composio toolkits (optional; shared or per-person accounts)
324330
```
325331

326332
| You run | CopilotKit Intelligence manages |
@@ -329,16 +335,27 @@ agent (Python + LangGraph deepagents)
329335
| The long-running Node Channels runtime | Platform ingress and credentialed delivery |
330336
| Deployment, state, and logs | Runtime registration, health, and reconnects |
331337

332-
Neither leg is Socket Mode, and neither needs a tunnel or a public URL of your
333-
own. Slack reaches Intelligence over HTTPS, authenticated by the signing secret
334-
Intelligence holds. Intelligence reaches your runtime over a websocket your
335-
process opens outbound, authenticated by `INTELLIGENCE_API_KEY`.
338+
Neither of those legs is Socket Mode, and neither needs a tunnel or a public URL
339+
of your own. Slack reaches Intelligence over HTTPS, authenticated by the signing
340+
secret Intelligence holds. Intelligence reaches your runtime over a websocket
341+
your process opens outbound, authenticated by `INTELLIGENCE_API_KEY`.
336342

337343
There is one canonical runtime host: [`server.ts`](./server.ts).
338344
[`app/index.ts`](./app/index.ts) composes one `CopilotKitIntelligence`, one
339-
`CopilotRuntime`, and one adapter-free managed Channel. Intelligence owns the
340-
Slack and Microsoft Teams adapters, their credentials, and attachments — no
341-
platform credential belongs in this repository's environment.
345+
`CopilotRuntime`, and one adapter-free managed Channel.
346+
Intelligence owns the Slack and Microsoft Teams adapters, their credentials, and
347+
attachments.
348+
349+
No platform credential belongs here at all. Composio's per-person toolkits need
350+
a connect link to reach one person privately, and the managed adapter delivers
351+
that itself with the SDK pair pinned in [`package.json`](./package.json) —
352+
proven end to end on Slack.
353+
Teams has no private message, so a Teams-backed Channel cannot deliver a connect
354+
link and says so rather than posting one in the thread. What per-person toolkits
355+
do need is `AGENT_AUTH_HEADER`, a shared secret between the two services, set to
356+
a **non-empty** value: the agent treats an empty string as unconfigured and
357+
refuses to mint. Leave it unset and nothing else changes.
358+
See [`setup.md`](./setup.md#composio).
342359

343360
`@copilotkit/channels` and `@copilotkit/runtime` are pinned for reproducible
344361
deploys. [`package.json`](./package.json) is the source of truth for both
@@ -361,6 +378,7 @@ knowledge work, and renders UI from model knowledge.
361378
| `GITHUB_PERSONAL_ACCESS_TOKEN` | Read-only repository, code, PR, and CI search |
362379
| `POSTHOG_PERSONAL_API_KEY` | PostHog analytics, read-only (use the **MCP Server** key preset) |
363380
| `LINEAR_API_KEY` | Hosted Linear MCP |
381+
| `COMPOSIO_API_KEY` | Composio toolkits, under one shared team account or under each person's own (per-person accounts are Slack-only and need `AGENT_AUTH_HEADER`; see setup.md) |
364382
| `NOTION_MCP_URL` + `NOTION_MCP_AUTH_TOKEN` | Remote Notion MCP; setting only one disables it |
365383
| `DAYTONA_API_KEY` + a PAT or GitHub App | Coding subagent: edit in Daytona, then push and publish a draft PR after `confirm_write` |
366384

0 commit comments

Comments
 (0)