@stratusagent/channel-slack 0.11.3 → 0.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -5
- package/dist/index.d.ts +32 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +379 -358
- package/dist/index.js.map +1 -1
- package/dist/mrkdwn.d.ts +43 -0
- package/dist/mrkdwn.d.ts.map +1 -0
- package/dist/mrkdwn.js +739 -0
- package/dist/mrkdwn.js.map +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Slack adapter for Stratus agents. **One Slack app per agent** — Slack has no way to give a single bot several identities with real avatars, presence, and DMs, so each agent gets its own app, and the adapter runs one Socket Mode connection per agent (no public ingress needed; Mac Minis behind NAT are fine).
|
|
4
4
|
|
|
5
5
|
- **Resumable conversations**: session keys are `slack:<agent>:<team>:<channel>:<thread_ts ?? ts>` (DMs: the DM channel id) — a thread is a conversation, it survives daemon restarts, and two agents sharing a thread keep fully separate sessions. A turn parked on a human when the daemon died is re-asked after the restart, and when it finishes its reply is posted into the thread as a fresh message — the placeholder it would have edited belonged to the old process.
|
|
6
|
-
- **
|
|
7
|
-
- **Markdown is translated to Slack's mrkdwn** on the way out — `**bold**` to `*bold*`, `*italic*` to `_italic_`, `~~struck~~` to `~struck~`, `[text](https://…)` to `<https://…|text>`, and a `#` heading to a bold line, since mrkdwn has no headings
|
|
6
|
+
- **Replies post when they are ready**: by default the reply is posted once, finished, with Slack's loading status (`assistant.threads.setStatus` — "is thinking…", "is running shell.run…") shown while the turn works, so the notification carries the answer. The `stream` reply mode (`slack.replies` in the [config](../../docs/guides/slack.md#how-replies-appear)) keeps the placeholder-and-edit rendering instead: post `…`, edit as deltas arrive (throttled for `chat.update` limits), show `⚙ tool…` status lines, finalize with the full reply. Either way a reply that outgrows one message is split across several.
|
|
7
|
+
- **Markdown is translated to Slack's mrkdwn** on the way out — `**bold**` to `*bold*`, `*italic*` to `_italic_`, `~~struck~~` to `~struck~`, `[text](https://…)` to `<https://…|text>`, and a `#` heading to a bold line, since mrkdwn has no headings. The reply is read once into tokens and written back from those, so what counts as code is decided one time rather than by each rule in turn. Three things follow from that. **A code run is one token**: nothing reads or rewrites inside it, an unclosed fence included, and the newlines in a fence are not line breaks — so a `#` on a line of somebody's shell script is not a heading. A run of N backticks opens code and only a run of exactly N closes it, which is what lets ``a span with a ` in it`` and a ````-fence holding a ```-fence work; one or two unmatched backticks are text, as they are in Markdown, but a pair is a span however far apart, because Slack pairs them too. **A delimiter is matched to its partner**, across whatever sits between — ``**the `fs.read` tool**`` is bold around a snippet, not four literal asterisks — though never across a line, so a marker still being streamed stays literal until its closing half arrives. A run is spent rather than matched whole, so the three asterisks ending `**bold and *italic***` close the italic with one and the bold with two; what no pair spends stays on the line as text, and what a run cannot buy — the third tilde of `~~~struck~~~`, a style that does not exist — is never charged for. **A wrapper is only written where its own character is not already loose** in what it wraps: Slack has one delimiter per style and no way to nest it, so a heading that already contains bold keeps the bold it has rather than gaining a second pair that would print instead of render, and `# glob *.ts` keeps an asterisk that was never a marker. A heading sheds its hashes and its trailing spaces from the prose that holds them, never from a snippet. Anything whose spelling already matches — lists, block quotes, inline code — is untouched.
|
|
8
8
|
- **Mention to start, then it stays in the thread.** A mention opens a conversation; every reply in that thread reaches the agent without tagging it again, and free-form DMs are unchanged. Who an untagged reply is for is decided by [Who a message is for](#who-a-message-is-for). Inbound mentions of other users are humanized to `@Display Name` for the model; redeliveries are deduped so a slow turn never runs twice.
|
|
9
9
|
- **Approval buttons** for the gateway's `remote` permission mode: a gated tool call parks the turn and asks in its thread with **Allow once** / **Always allow** / **Deny**. See [Approving tool calls](#approving-tool-calls) — clicks are authorized by *who clicked*, never by who can see the message, and **Always allow** is offered only where the daemon would actually remember it.
|
|
10
10
|
- **Tokens are gateway infrastructure secrets**, stored in the `channels` namespace of `~/.stratus/credentials.json` — never in an agent's credential allowlist:
|
|
@@ -127,9 +127,10 @@ thread.
|
|
|
127
127
|
An OpenAI-compatible model that takes only text needs `"vision": false` in
|
|
128
128
|
config, which turns every image into that note; see the
|
|
129
129
|
[Slack guide](../../docs/guides/slack.md#sending-an-image). Whether the model actually *sees* the image depends on the
|
|
130
|
-
agent's runtime: the Anthropic API
|
|
131
|
-
as image content; the
|
|
132
|
-
so there the agent is told the image's name and that it cannot
|
|
130
|
+
agent's runtime: the Anthropic API, OpenAI-compatible providers, and the
|
|
131
|
+
Claude Code runtime send it as image content; the Codex harness takes a
|
|
132
|
+
text prompt, so there the agent is told the image's name and that it cannot
|
|
133
|
+
see it.
|
|
133
134
|
**Every other attachment is unreadable** — a log, a PDF, an image that was
|
|
134
135
|
too large — so the message reaches the agent naming those files and saying
|
|
135
136
|
they cannot be opened, which is what lets it answer honestly instead of as
|
|
@@ -317,12 +318,62 @@ With no list at all, every Slack sender is `unknown`, and `stratus serve`
|
|
|
317
318
|
says so at startup. An agent's own entry replaces the shared list;
|
|
318
319
|
`"slackUsers": []` excludes an agent from it.
|
|
319
320
|
|
|
321
|
+
The list also decides how a speaker is *named* in a channel turn, which
|
|
322
|
+
the model reads as `Name: text`. A principal is their display name — one
|
|
323
|
+
line, at most 80 characters, control characters and Unicode bidi controls
|
|
324
|
+
spelled out — because
|
|
325
|
+
their profile is trusted the way their messages are. With a list in force,
|
|
326
|
+
everyone else is their user id, exactly as an `@mention` of them already
|
|
327
|
+
is: a display name is text its owner typed, and the speaker position of a
|
|
328
|
+
user turn is not a place a stranger gets to put a sentence. With no list
|
|
329
|
+
at all there is nobody to prefer, so every author keeps their name — and
|
|
330
|
+
"no list" is the key being absent; `"slackUsers": []` is a list that
|
|
331
|
+
prefers nobody, so under it every author is an id.
|
|
332
|
+
|
|
320
333
|
The sender is judged on **every message**, not once per thread. A thread
|
|
321
334
|
keys one session for everyone in it, so an authorized member can open one
|
|
322
335
|
and a stranger can mention the agent inside it afterwards — the stranger's
|
|
323
336
|
turn lowers the session, and the authorized member's next turn does not
|
|
324
337
|
raise it back.
|
|
325
338
|
|
|
339
|
+
The list is a **label** by default: an unlisted sender still gets a turn,
|
|
340
|
+
marked `unknown`. For an agent that holds tools that is not enough — a
|
|
341
|
+
stranger's message is not merely uncertain, it is a prompt they chose, and
|
|
342
|
+
`unknown` does not stop `shell.run` from running on it once a listed
|
|
343
|
+
approver clicks. `admit` makes the list a **door**:
|
|
344
|
+
|
|
345
|
+
```jsonc
|
|
346
|
+
{
|
|
347
|
+
"principals": {
|
|
348
|
+
"slackUsers": ["U01DYLAN"],
|
|
349
|
+
"admit": "principals",
|
|
350
|
+
"agents": {
|
|
351
|
+
"bea": { "admit": "anyone" }
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Under `"admit": "principals"` a sender not in `slackUsers` gets no turn:
|
|
358
|
+
the message is refused before it takes a place in the queue, the agent
|
|
359
|
+
does not overhear it into a thread's transcript either, and nothing is
|
|
360
|
+
posted back — a reply is a conversation the operator chose not to have.
|
|
361
|
+
The refusal is one line in the daemon log naming the agent and the user
|
|
362
|
+
id — one per message, however many times Slack delivers it, and only for a
|
|
363
|
+
message the agent would have taken up: a mention, or a reply in a thread
|
|
364
|
+
the agent holds, whether the daemon remembers that or its sessions do. A
|
|
365
|
+
stranger's reply in a thread the agent was never part of is dropped
|
|
366
|
+
without a line. `"anyone"` is
|
|
367
|
+
the default and today's behavior; the key inherits per agent like
|
|
368
|
+
`slackUsers`, so Bea above stays open while everyone else is closed. A value
|
|
369
|
+
that is neither word is a config error, never `anyone`: this is the one
|
|
370
|
+
setting here whose misspelling would open the door. So is a `slackUsers`
|
|
371
|
+
that is not a list of user ids, and so is a block or a per-agent entry that
|
|
372
|
+
is not an object: dropped for its shape, a per-agent list would fall back to
|
|
373
|
+
the shared one, the broader list it existed to narrow, and the block itself
|
|
374
|
+
would fall back to `anyone`.
|
|
375
|
+
`stratus serve` says at startup which agents refuse unlisted senders.
|
|
376
|
+
|
|
326
377
|
Like `approvals`, this block is read only from a config you chose —
|
|
327
378
|
`--config`, `STRATUS_CONFIG`, or the global `~/.stratus/config.json`. A
|
|
328
379
|
project-local `stratus.config.json` cannot appoint itself the principal.
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,20 @@ export interface SlackAgentConfig {
|
|
|
31
31
|
* nobody is, and every sender is `unknown`.
|
|
32
32
|
*/
|
|
33
33
|
principals?: string[];
|
|
34
|
+
/**
|
|
35
|
+
* Whether an unlisted sender gets a turn at all. `anyone` (the default)
|
|
36
|
+
* admits them as `unknown`; `principals` refuses them before a turn
|
|
37
|
+
* starts and does not let the agent overhear them either — the text
|
|
38
|
+
* would be in the transcript, which is what this mode exists to keep
|
|
39
|
+
* out. The label above is provenance; this is authorization.
|
|
40
|
+
*/
|
|
41
|
+
admit?: 'anyone' | 'principals';
|
|
42
|
+
/**
|
|
43
|
+
* How replies appear. `final` (the default) shows Slack's loading status
|
|
44
|
+
* while the turn runs and posts the reply once, finished; `stream` posts
|
|
45
|
+
* a `…` placeholder at once and edits it as the reply is written.
|
|
46
|
+
*/
|
|
47
|
+
replies?: 'final' | 'stream';
|
|
34
48
|
}
|
|
35
49
|
export interface SlackSocketEventArgs {
|
|
36
50
|
ack: (response?: unknown) => Promise<void>;
|
|
@@ -195,6 +209,21 @@ export interface SlackWebLike {
|
|
|
195
209
|
thread_ts?: string;
|
|
196
210
|
}): Promise<unknown>;
|
|
197
211
|
};
|
|
212
|
+
/**
|
|
213
|
+
* Slack's loading status for a thread — "is thinking…" under the agent's
|
|
214
|
+
* name until it replies. Optional: an older SDK, or a fake, without it
|
|
215
|
+
* leaves a `final` reply with no status, never without the reply.
|
|
216
|
+
* `chat:write` is enough for it in channels since March 2026.
|
|
217
|
+
*/
|
|
218
|
+
assistant?: {
|
|
219
|
+
threads: {
|
|
220
|
+
setStatus(args: {
|
|
221
|
+
channel_id: string;
|
|
222
|
+
thread_ts: string;
|
|
223
|
+
status: string;
|
|
224
|
+
}): Promise<unknown>;
|
|
225
|
+
};
|
|
226
|
+
};
|
|
198
227
|
files: {
|
|
199
228
|
uploadV2(args: {
|
|
200
229
|
channel_id: string;
|
|
@@ -286,7 +315,9 @@ export declare const createSlackFileFetcher: (fetchImpl: typeof fetch) => SlackF
|
|
|
286
315
|
* Session keys are `slack:<agent>:<team>:<channel>:<thread_ts ?? ts>`
|
|
287
316
|
* (DMs: the DM channel id alone), so threads are resumable conversations
|
|
288
317
|
* and two agents sharing a thread keep fully separate sessions. Replies
|
|
289
|
-
*
|
|
318
|
+
* post once, finished, behind Slack's loading status — or, in the `stream`
|
|
319
|
+
* reply mode, stream via placeholder-then-edit, throttled for chat.update
|
|
320
|
+
* limits.
|
|
290
321
|
*
|
|
291
322
|
* A mention starts a thread conversation; inside one, the agent keeps
|
|
292
323
|
* listening without being tagged again — see `couldBeFollowUp` and
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|