@stratusagent/channel-slack 0.11.2 → 0.11.3

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 CHANGED
@@ -4,7 +4,7 @@ Slack adapter for Stratus agents. **One Slack app per agent** — Slack has no w
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
6
  - **Streaming replies**: post a placeholder, edit as deltas arrive (throttled for `chat.update` limits), show `⚙ tool…` status lines, finalize with the full reply — split across messages when it outgrows one.
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 — unless the heading already carries an asterisk of its own, which is left as it is: Slack has one bold delimiter and no way to nest it, so a second pair would print rather than render. Code spans and fences are left exactly as written, an unclosed fence included, so a `**` inside a snippet stays part of the snippet — 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 literal text, as they are in Markdown. Anything whose spelling already matches — lists, block quotes, inline code — is untouched. A marker still being streamed stays literal until its closing half arrives.
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 — unless the heading already carries an asterisk of its own, which is left as it is: Slack has one bold delimiter and no way to nest it, so a second pair would print rather than render. Code spans and fences are left exactly as written, an unclosed fence included, so a `**` inside a snippet stays part of the snippet — 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 literal text, as they are in Markdown. A run that has code inside it is still one run — ``**the `fs.read` tool**`` is bold around a snippet, not four literal asterisks — because the whole reply is rewritten at once, with the code held out of the rewrite rather than cut out of the text. Anything whose spelling already matches — lists, block quotes, inline code — is untouched. A marker still being streamed stays literal until its closing half arrives.
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:
@@ -44,20 +44,104 @@ they are the whole model:
44
44
  straight after it reaches the agent you just named, and the agent that
45
45
  *had* the thread stands down at the same instant rather than whenever its
46
46
  own app next catches up.
47
+ 5. **How an agent listens is the soul's to say.** Rules 3 and 4 are the
48
+ `thread` mode, the default. A soul with `listens: mentions` takes only
49
+ messages that name it, and hears the rest. One with `listens: judge`
50
+ hears everything and, while attentive — eight messages or fifteen
51
+ minutes after it last answered a message that named it, whichever ends
52
+ first — runs a turn nobody asked for on each untagged message, told it
53
+ may answer with nothing; past the window a message is heard with no
54
+ turn at all, and a mention re-arms it. A reply it chose to give on its
55
+ own does not: it takes the thread for the thread rule, and counts
56
+ against its own window like any other message. A turn that decides on silence posts nothing: its
57
+ placeholder is opened only on the first text it streams, never on a
58
+ tool line, and a failed one posts no error note — one the daemon died
59
+ inside, failed at the next start, included, a line it had already
60
+ streamed staying as it was. A line an attempt the
61
+ provider abandoned had already posted is taken back when the retry
62
+ decides on silence. Neither mode takes
63
+ part in the holder rule — that rule answers whose an untagged reply is,
64
+ and for these two the soul already has — so a thread-rule agent stands
65
+ down for a judging or mentions-only one that spoke last: the judging
66
+ one decides for itself, and the mentions-only one is being talked to
67
+ and waits to be named. A judging agent that chooses to speak takes the
68
+ thread the way any speaker does, recorded once its reply has landed —
69
+ so a message typed while it was still deciding may be answered by both
70
+ it and a thread-rule colleague that held the thread before. "Spoke
71
+ last" is read off the thread, not the clock: the holder is whichever
72
+ agent's reply sits lowest, since that is the one a reader answers, and
73
+ a placeholder posted early and filled in slowly sits above a reply
74
+ posted while it was being written. A colleague's reply is never
75
+ judged, only heard.
76
+ The window also counts messages this daemon has dispatched that the
77
+ session does not hold yet, so a burst typed inside one turn is judged
78
+ up to the window and heard past it.
79
+ 6. **Standing down is not leaving.** An agent in a thread hears what is
80
+ said to the other agent in it — the question that named its colleague,
81
+ the untagged replies that were the colleague's to answer, and what the
82
+ colleague *replied* — into its own session, with no turn run and
83
+ nothing posted. The next time it is asked, it answers as someone who
84
+ followed the conversation rather than one who stepped out of the room.
85
+ What it hears is marked as said to somebody else, so a stranger's words
86
+ in a shared thread never read to it as an instruction; and a stranger
87
+ overheard lowers its session's trust label exactly as one who addressed
88
+ it would, since their text is in the transcript either way. A
89
+ colleague's reply is heard under the colleague's own label, never as a
90
+ person's: an agent's word is at most `agent`, and carries whatever its
91
+ session has been exposed to. Replies only — a turn that said nothing,
92
+ or failed, is nothing to hear — and only while the hearer's app is
93
+ still in the channel, which is asked of Slack per reply: a person's
94
+ message reaches an agent through its own socket, so an app removed
95
+ from a private channel stops hearing on its own, but a reply is
96
+ forwarded by the daemon and would otherwise keep arriving.
47
97
 
48
98
  Everyone in the thread is talking to the same agent — a reply from a second
49
99
  person is a follow-up like any other, and channel messages reach the model
50
100
  prefixed with the speaker's display name so it knows who said what. A reply
51
101
  carrying a file, or one the author also broadcast to the channel, is a
52
102
  follow-up too; what Slack marks as bookkeeping — an edit, a deletion, a
53
- join — is not, and nothing answers it. **Attachment contents are not
54
- readable** — the app does not ask for `files:read` — so a message with files
55
- reaches the agent naming them and saying they cannot be opened, which is
56
- what lets it answer honestly instead of as though it had read the log. A
57
- file dropped in with nothing said is not a question, and gets no reply. What is
58
- *not* shared is history: sessions are per agent, so an agent tagged into a
59
- thread halfway through starts from what it is told then, not from what the
60
- other agent was told. Bring it up to speed in the message that tags it.
103
+ join — is not, and nothing answers it. **Images are shown to the model.**
104
+ A PNG, JPEG, GIF, or WebP attached to a message is downloaded with the
105
+ bot token and sent with the message — a screenshot alone, with nothing
106
+ typed, is a question in its own right and gets an answer. That needs the
107
+ `files:read` scope, which the shipped manifest asks for; an app installed
108
+ without it should have the scope added under **OAuth & Permissions** and be
109
+ reinstalled once, and until then `stratus serve` warns, naming the scope,
110
+ each time an image arrives. An image over 5 MB or 8000 pixels a side (the
111
+ model API's limits) is not kept, and one message's images stop at 20 MB
112
+ together — a request has a size limit too, and images past it are named as
113
+ unreadable; send them in a message of their own. The same 20 MB — and 20
114
+ images — is what a whole thread's images may take on one request, spent
115
+ newest first — and the request as a whole has a limit too, so when the
116
+ rest of the conversation needs the room the oldest images give way to it.
117
+ Once a thread's images pass a limit the oldest are let
118
+ go of — the model is told an image was there and what it was called, and
119
+ the session keeps that record rather than the pixels, so a busy thread's
120
+ row stays bounded. A message's downloads share one 30-second deadline,
121
+ after which whatever has not arrived is named as unreadable, so a slow
122
+ link cannot hold the thread. And an image the model API itself refuses —
123
+ the adapter checks that a file opens and closes like the image it claims
124
+ to be, but that is not a decode — is dropped from the session and the turn
125
+ retried without it, so one bad file cannot fail every later turn of a
126
+ thread.
127
+ An OpenAI-compatible model that takes only text needs `"vision": false` in
128
+ config, which turns every image into that note; see the
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 and OpenAI-compatible providers send it
131
+ as image content; the Claude Code and Codex harnesses take a text prompt,
132
+ so there the agent is told the image's name and that it cannot see it.
133
+ **Every other attachment is unreadable** — a log, a PDF, an image that was
134
+ too large — so the message reaches the agent naming those files and saying
135
+ they cannot be opened, which is what lets it answer honestly instead of as
136
+ though it had read the log. Such a file dropped in with nothing said is not
137
+ a question, and gets no reply.
138
+ Sessions are still per agent: an agent hears a thread from the mention
139
+ that brought it in, and what was said before that — to the other agent, or
140
+ by it — is not backfilled ([#147](https://github.com/stratuslabs/agent/issues/147)).
141
+ Bring it up to speed in the message that tags it. A colleague's reply is
142
+ heard by the daemon that posted it, not through Slack — an agent served by
143
+ another daemon is a stranger's bot to this one, and its replies are not
144
+ heard at all.
61
145
 
62
146
  Three edges worth knowing. An agent whose app was installed before the
63
147
  history scopes below is told about mentions only, and behaves exactly as it
@@ -75,10 +159,10 @@ always given when an app is down.
75
159
  And the rules above are mechanical, which shows in a thread where people are
76
160
  mostly talking to *each other*: an agent invited into one answers every
77
161
  untagged reply in it, including the ones meant for somebody else. Give the
78
- side conversation its own thread. Teaching an agent to read the room
79
- instead — to follow a thread whether or not it is being spoken to, and
80
- answer only when it has something to add — is
81
- [roadmap step 31](../../docs/roadmap/31-reading-the-room.md).
162
+ side conversation its own thread. It can now *hear* a thread it is not
163
+ answering; teaching it to choose — to answer only when it has something to
164
+ add, and to let "thanks, we've got it" be a sentence it read — is the rest
165
+ of [roadmap step 31](../../docs/roadmap/31-reading-the-room.md).
82
166
 
83
167
  ## Installing
84
168
 
@@ -104,7 +188,7 @@ editing `credentials.json` by hand.
104
188
  The manual equivalent, if you prefer:
105
189
 
106
190
  1. https://api.slack.com/apps → **Create New App → From a manifest** → paste `manifest/stratus-agent.manifest.json` with `NAME` replaced by the agent's name.
107
- The manifest asks for the `channels:history` / `groups:history` / `mpim:history` scopes and the matching `message.*` events, which is what lets an agent [stay in a thread](#who-a-message-is-for) instead of needing a mention every time. An app created before those shipped needs them added under **OAuth & Permissions** and **Event Subscriptions** and reinstalled once; leave them off and it answers mentions and DMs, exactly as it did before.
191
+ The manifest asks for the `channels:history` / `groups:history` / `mpim:history` scopes and the matching `message.*` events, which is what lets an agent [stay in a thread](#who-a-message-is-for) instead of needing a mention every time, and for `files:read`, which is what lets it [see an attached image](#who-a-message-is-for). An app created before those shipped needs them added under **OAuth & Permissions** and **Event Subscriptions** and reinstalled once; leave the history scopes off and it answers mentions and DMs, exactly as it did before; leave `files:read` off and it hears about attachments by name only.
108
192
  2. **Basic Information → App-Level Tokens** → generate a token with `connections:write` (that's the `appToken`, `xapp-…`).
109
193
  3. **Install App** to the workspace → copy the **Bot User OAuth Token** (that's the `botToken`, `xoxb-…`).
110
194
  4. Upload the agent's avatar under **Display Information**.
@@ -128,12 +212,20 @@ the parser cannot reduce to a scope. The prompt says so instead, because a
128
212
  button that does exactly what **Allow once** does, under a label promising a
129
213
  standing grant, is worse than no button.
130
214
 
215
+ Where it is offered, a line beside the buttons says what it would do,
216
+ because that differs by tool and is the half of the question the button
217
+ widens: for most gated tools it is a **standing grant** to the agent that
218
+ lasts until an operator revokes it (`stratus grants <agent>` lists and
219
+ revokes; see [Approvals](../../docs/guides/approvals.md)); for a shell
220
+ command it is that command's scope; for a browser action it is the site;
221
+ and for a send outside a schedule it is the rest of this session.
222
+
131
223
  The resolved message describes what the daemon did rather than which button
132
224
  was pressed — `POST /approvals` accepts `always` whatever this channel
133
- rendered, so the answer can arrive from somewhere else. It states the floor
134
- rather than the ceiling: a remembered answer lasts *at least* the session,
135
- and whether a scoped one also survives a restart depends on the daemon
136
- writing the whitelist, which is not known when the message is sent.
225
+ rendered, so the answer can arrive from somewhere else — and names the grant
226
+ that was made, since the request said in advance which kind it would be.
227
+ The one thing it cannot promise is the disk write: a daemon that could not
228
+ read the whitelist does not write over it, and by then the message is sent.
137
229
  `stratus logs` has the exact line.
138
230
 
139
231
  Who may answer is configured per agent, in `~/.stratus/config.json`:
package/dist/index.d.ts CHANGED
@@ -81,19 +81,77 @@ export interface SlackInboundEvent {
81
81
  /**
82
82
  * Attachments on a `file_share` message. Slack puts the file metadata in
83
83
  * the event and the bytes behind an authenticated URL that needs
84
- * `files:read`, which this app does not ask for — so a turn learns that a
85
- * file arrived and what it is called, never what is in it.
84
+ * `files:read`. An image the model can take is downloaded and sent with
85
+ * the message (see `readImageAttachments`); anything else — a log, a
86
+ * PDF, an image too large or in a format the API refuses — reaches the
87
+ * turn by name only, told that it cannot be opened.
86
88
  */
87
- files?: Array<{
88
- name?: string;
89
- title?: string;
90
- }>;
89
+ files?: SlackInboundFile[];
90
+ }
91
+ /** The slice of Slack's file object the adapter reads. */
92
+ export interface SlackInboundFile {
93
+ id?: string;
94
+ name?: string;
95
+ title?: string;
96
+ /** Slack's own `image/png`-style type, decided by the uploader's client. */
97
+ mimetype?: string;
98
+ /** Bytes, as Slack reports them; checked before anything is downloaded. */
99
+ size?: number;
100
+ url_private?: string;
101
+ url_private_download?: string;
102
+ }
103
+ /**
104
+ * What came back from fetching a file's private URL. Slack answers a
105
+ * request the app is not allowed to make — a token without `files:read` —
106
+ * with a **200 and a sign-in page**, never an error status, which is why
107
+ * the content type travels: it is the only thing that tells an image from
108
+ * an HTML apology for one.
109
+ */
110
+ export interface SlackFileDownload {
111
+ status: number;
112
+ contentType?: string;
113
+ body: Buffer;
114
+ /**
115
+ * Set when the body was cut off at `maxBytes`: what is in `body` is not
116
+ * the file, only proof that the file was bigger than the caller would
117
+ * take.
118
+ */
119
+ truncated?: boolean;
91
120
  }
121
+ /**
122
+ * Fetches a file's private URL with the bot token. `signal` is the
123
+ * download's deadline, and a fetcher MUST stop on it — headers and body
124
+ * both: the download runs inside the session's intake chain, so one that
125
+ * stalls holds every later message in the thread, and `stop()` waits on
126
+ * the handler too. `maxBytes` is the most body a fetcher may buffer; one
127
+ * that reads past it MUST stop there and report `truncated`, because
128
+ * Slack's reported size is advisory and a response is not.
129
+ */
130
+ export type SlackFileFetcher = (url: string, botToken: string, signal: AbortSignal, maxBytes: number) => Promise<SlackFileDownload>;
92
131
  export interface SlackSocketLike {
93
132
  on(eventName: string, listener: (args: SlackSocketEventArgs) => void): void;
94
133
  start(): Promise<unknown>;
95
134
  disconnect(): Promise<void>;
96
135
  }
136
+ /**
137
+ * What `files.uploadV2` answers with, as much of it as is read here: the
138
+ * file's shares, each carrying the ts of the message the file became in a
139
+ * channel — where it sits in the thread. Whether a just-completed upload's
140
+ * shares are filled in yet is Slack's business, so every part is optional
141
+ * and a reader without one falls back (see `ReplyRenderer.queueUpload`).
142
+ */
143
+ export interface SlackUploadResult {
144
+ files?: Array<{
145
+ shares?: {
146
+ public?: Record<string, Array<{
147
+ ts?: string;
148
+ }>>;
149
+ private?: Record<string, Array<{
150
+ ts?: string;
151
+ }>>;
152
+ };
153
+ }>;
154
+ }
97
155
  export interface SlackWebLike {
98
156
  auth: {
99
157
  test(): Promise<{
@@ -117,6 +175,15 @@ export interface SlackWebLike {
117
175
  text: string;
118
176
  blocks?: SlackBlock[];
119
177
  }): Promise<unknown>;
178
+ /**
179
+ * Take a message back. The one caller is a turn nobody asked for that
180
+ * opened its placeholder for an attempt the provider then abandoned and
181
+ * decided on silence after all — see `ReplyRenderer.retract`.
182
+ */
183
+ delete(args: {
184
+ channel: string;
185
+ ts: string;
186
+ }): Promise<unknown>;
120
187
  /**
121
188
  * Visible only to `user`. Refusing a click needs to reach the person
122
189
  * who clicked without announcing to the channel that they tried.
@@ -135,7 +202,7 @@ export interface SlackWebLike {
135
202
  filename?: string;
136
203
  title?: string;
137
204
  thread_ts?: string;
138
- }): Promise<unknown>;
205
+ }): Promise<SlackUploadResult>;
139
206
  };
140
207
  conversations: {
141
208
  /**
@@ -178,7 +245,38 @@ export interface SlackAdapterOptions {
178
245
  createSocketClient?: (appToken: string) => SlackSocketLike;
179
246
  /** Test injection: build a Web API client for a bot token. */
180
247
  createWebClient?: (botToken: string) => SlackWebLike;
248
+ /**
249
+ * Test injection: fetch a file's private URL with the bot token. The
250
+ * Web API client has no call for this — file bytes are served from a
251
+ * plain authenticated URL — so it is its own seam.
252
+ */
253
+ fetchFile?: SlackFileFetcher;
254
+ /**
255
+ * How long one message's attachment downloads may take, all of them
256
+ * together, before the turn goes on without whatever has not arrived.
257
+ * Defaults to `DEFAULT_FILE_DOWNLOAD_TIMEOUT_MS`.
258
+ */
259
+ fileDownloadTimeoutMs?: number;
260
+ /**
261
+ * Test injection: the clock, in milliseconds, that an upload's place in
262
+ * the thread is read from (`ReplyOutcome.spokeAt`) when the upload's
263
+ * answer carries no share ts. Defaults to `Date.now`.
264
+ */
265
+ now?: () => number;
181
266
  }
267
+ /**
268
+ * The default fetcher over a `fetch`. Exported as a factory so the bounded
269
+ * read can be tested against a fake `fetch` with a body that never ends;
270
+ * the adapter uses it over the global one.
271
+ *
272
+ * The body is read a chunk at a time and abandoned the moment it passes
273
+ * `maxBytes`: `arrayBuffer()` would buffer the whole response first, and
274
+ * the size the adapter checked before asking came from Slack's metadata,
275
+ * which an oversized response is under no obligation to match. A
276
+ * `content-length` that already says too much is refused before a byte is
277
+ * read.
278
+ */
279
+ export declare const createSlackFileFetcher: (fetchImpl: typeof fetch) => SlackFileFetcher;
182
280
  /**
183
281
  * The Slack channel adapter. One Slack app per agent — Slack has no way to
184
282
  * give a single bot several identities with real avatars, presence, and
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}