@open-everywhere/provider-slack 0.6.0 → 0.8.0
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/agent/access/slack-attachment-fetch.ts +2 -1
- package/agent/app-manifest.ts +15 -1
- package/agent/channels/slack-agent-session.ts +249 -0
- package/agent/channels/slack-attachments.ts +20 -11
- package/agent/channels/slack-bot-ask.ts +101 -0
- package/agent/channels/slack-commands.ts +178 -17
- package/agent/channels/slack-context.ts +0 -5
- package/agent/channels/slack-events.ts +110 -33
- package/agent/channels/slack-follow-ups.ts +148 -0
- package/agent/channels/slack-friendly-names.ts +55 -0
- package/agent/channels/slack-front.ts +262 -27
- package/agent/channels/slack-home.ts +9 -3
- package/agent/channels/slack-identity.ts +9 -1
- package/agent/channels/slack-memory-canvas.ts +197 -54
- package/agent/channels/slack-origin-codec.ts +9 -0
- package/agent/channels/slack-post-arm.ts +68 -11
- package/agent/channels/slack-read.ts +27 -2
- package/agent/channels/slack-reply-blocks.ts +180 -0
- package/agent/channels/slack-reply-feedback.ts +75 -0
- package/agent/channels/slack-shortcut.ts +1 -1
- package/agent/channels/slack-voice-clips.ts +82 -0
- package/agent/channels/slack-wake-backscroll.ts +0 -5
- package/agent/channels/slack-web-api.ts +4 -2
- package/agent/channels/slack.ts +81 -19
- package/agent/docs-generated.ts +1282 -2
- package/agent/ops.ts +14 -21
- package/agent/register.ts +25 -0
- package/agent/setup/credentials.ts +17 -0
- package/agent/setup/page.ts +6 -3
- package/agent/surface-parity.ts +2 -0
- package/dist/agent/access/slack-attachment-fetch.d.ts.map +1 -1
- package/dist/agent/access/slack-attachment-fetch.js.map +1 -1
- package/dist/agent/app-manifest.d.ts.map +1 -1
- package/dist/agent/app-manifest.js +15 -1
- package/dist/agent/app-manifest.js.map +1 -1
- package/dist/agent/channels/slack-agent-session.d.ts +81 -0
- package/dist/agent/channels/slack-agent-session.d.ts.map +1 -0
- package/dist/agent/channels/slack-agent-session.js +198 -0
- package/dist/agent/channels/slack-agent-session.js.map +1 -0
- package/dist/agent/channels/slack-attachments.d.ts +11 -0
- package/dist/agent/channels/slack-attachments.d.ts.map +1 -1
- package/dist/agent/channels/slack-attachments.js +21 -14
- package/dist/agent/channels/slack-attachments.js.map +1 -1
- package/dist/agent/channels/slack-bot-ask.d.ts +30 -0
- package/dist/agent/channels/slack-bot-ask.d.ts.map +1 -0
- package/dist/agent/channels/slack-bot-ask.js +91 -0
- package/dist/agent/channels/slack-bot-ask.js.map +1 -0
- package/dist/agent/channels/slack-commands.d.ts +113 -10
- package/dist/agent/channels/slack-commands.d.ts.map +1 -1
- package/dist/agent/channels/slack-commands.js +151 -18
- package/dist/agent/channels/slack-commands.js.map +1 -1
- package/dist/agent/channels/slack-context.d.ts +1 -2
- package/dist/agent/channels/slack-context.d.ts.map +1 -1
- package/dist/agent/channels/slack-context.js +0 -4
- package/dist/agent/channels/slack-context.js.map +1 -1
- package/dist/agent/channels/slack-events.d.ts +47 -97
- package/dist/agent/channels/slack-events.d.ts.map +1 -1
- package/dist/agent/channels/slack-events.js +90 -22
- package/dist/agent/channels/slack-events.js.map +1 -1
- package/dist/agent/channels/slack-follow-ups.d.ts +44 -0
- package/dist/agent/channels/slack-follow-ups.d.ts.map +1 -0
- package/dist/agent/channels/slack-follow-ups.js +129 -0
- package/dist/agent/channels/slack-follow-ups.js.map +1 -0
- package/dist/agent/channels/slack-friendly-names.d.ts +10 -0
- package/dist/agent/channels/slack-friendly-names.d.ts.map +1 -0
- package/dist/agent/channels/slack-friendly-names.js +45 -0
- package/dist/agent/channels/slack-friendly-names.js.map +1 -0
- package/dist/agent/channels/slack-front.d.ts +38 -46
- package/dist/agent/channels/slack-front.d.ts.map +1 -1
- package/dist/agent/channels/slack-front.js +230 -23
- package/dist/agent/channels/slack-front.js.map +1 -1
- package/dist/agent/channels/slack-home.d.ts.map +1 -1
- package/dist/agent/channels/slack-home.js +10 -3
- package/dist/agent/channels/slack-home.js.map +1 -1
- package/dist/agent/channels/slack-identity.d.ts +7 -21
- package/dist/agent/channels/slack-identity.d.ts.map +1 -1
- package/dist/agent/channels/slack-identity.js +3 -1
- package/dist/agent/channels/slack-identity.js.map +1 -1
- package/dist/agent/channels/slack-memory-canvas.d.ts +21 -5
- package/dist/agent/channels/slack-memory-canvas.d.ts.map +1 -1
- package/dist/agent/channels/slack-memory-canvas.js +166 -55
- package/dist/agent/channels/slack-memory-canvas.js.map +1 -1
- package/dist/agent/channels/slack-origin-codec.d.ts.map +1 -1
- package/dist/agent/channels/slack-origin-codec.js +10 -0
- package/dist/agent/channels/slack-origin-codec.js.map +1 -1
- package/dist/agent/channels/slack-post-arm.d.ts +21 -1
- package/dist/agent/channels/slack-post-arm.d.ts.map +1 -1
- package/dist/agent/channels/slack-post-arm.js +57 -10
- package/dist/agent/channels/slack-post-arm.js.map +1 -1
- package/dist/agent/channels/slack-read.d.ts +11 -1
- package/dist/agent/channels/slack-read.d.ts.map +1 -1
- package/dist/agent/channels/slack-read.js +27 -3
- package/dist/agent/channels/slack-read.js.map +1 -1
- package/dist/agent/channels/slack-reply-blocks.d.ts +29 -0
- package/dist/agent/channels/slack-reply-blocks.d.ts.map +1 -0
- package/dist/agent/channels/slack-reply-blocks.js +172 -0
- package/dist/agent/channels/slack-reply-blocks.js.map +1 -0
- package/dist/agent/channels/slack-reply-feedback.d.ts +23 -0
- package/dist/agent/channels/slack-reply-feedback.d.ts.map +1 -0
- package/dist/agent/channels/slack-reply-feedback.js +63 -0
- package/dist/agent/channels/slack-reply-feedback.js.map +1 -0
- package/dist/agent/channels/slack-shortcut.d.ts +10 -0
- package/dist/agent/channels/slack-shortcut.d.ts.map +1 -1
- package/dist/agent/channels/slack-shortcut.js +1 -1
- package/dist/agent/channels/slack-shortcut.js.map +1 -1
- package/dist/agent/channels/slack-voice-clips.d.ts +16 -0
- package/dist/agent/channels/slack-voice-clips.d.ts.map +1 -0
- package/dist/agent/channels/slack-voice-clips.js +80 -0
- package/dist/agent/channels/slack-voice-clips.js.map +1 -0
- package/dist/agent/channels/slack-wake-backscroll.d.ts +0 -2
- package/dist/agent/channels/slack-wake-backscroll.d.ts.map +1 -1
- package/dist/agent/channels/slack-wake-backscroll.js +0 -4
- package/dist/agent/channels/slack-wake-backscroll.js.map +1 -1
- package/dist/agent/channels/slack-web-api.d.ts.map +1 -1
- package/dist/agent/channels/slack-web-api.js +4 -2
- package/dist/agent/channels/slack-web-api.js.map +1 -1
- package/dist/agent/channels/slack.d.ts +22 -1
- package/dist/agent/channels/slack.d.ts.map +1 -1
- package/dist/agent/channels/slack.js +70 -16
- package/dist/agent/channels/slack.js.map +1 -1
- package/dist/agent/docs-generated.d.ts.map +1 -1
- package/dist/agent/docs-generated.js +1282 -2
- package/dist/agent/docs-generated.js.map +1 -1
- package/dist/agent/ops.d.ts +1 -1
- package/dist/agent/ops.d.ts.map +1 -1
- package/dist/agent/ops.js +15 -21
- package/dist/agent/ops.js.map +1 -1
- package/dist/agent/register.d.ts.map +1 -1
- package/dist/agent/register.js +22 -1
- package/dist/agent/register.js.map +1 -1
- package/dist/agent/setup/credentials.d.ts +12 -0
- package/dist/agent/setup/credentials.d.ts.map +1 -1
- package/dist/agent/setup/credentials.js +17 -0
- package/dist/agent/setup/credentials.js.map +1 -1
- package/dist/agent/setup/page.d.ts.map +1 -1
- package/dist/agent/setup/page.js +6 -3
- package/dist/agent/setup/page.js.map +1 -1
- package/dist/agent/surface-parity.d.ts.map +1 -1
- package/dist/agent/surface-parity.js +2 -0
- package/dist/agent/surface-parity.js.map +1 -1
- package/package.json +40 -3
package/agent/ops.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// registerSlackOps — the LIGHT ops-plane half of the slack bundle's boot wiring: the paste-ready
|
|
2
|
-
// app manifest
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
2
|
+
// app manifest. Split out of register.ts so the STANDALONE ops MCP entry (the app's
|
|
3
|
+
// scripts/ops-mcp.ts, which serves the setup tools with no agent boot) can register it without
|
|
4
|
+
// pulling the whole channel graph. registerSlackProvider() calls this too, so the agent runtime
|
|
5
|
+
// carries the same registrations.
|
|
6
6
|
//
|
|
7
7
|
// It imports core through the LIGHT door (`adapter-api-ops.js`), not the main barrel: the main
|
|
8
8
|
// barrel loads most of core, and that one import was most of the ops MCP server's start time.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
11
|
-
// are the bundle's vendor fingerprints (boundary-test.ts rule 6).
|
|
10
|
+
// The bundle (not core) owns the Slack env-key knowledge — SLACK_BOT_TOKEN / SLACK_SIGNING_SECRET
|
|
11
|
+
// are the bundle's vendor fingerprints (boundary-test.ts rule 6). agent/setup/credentials.ts reads
|
|
12
|
+
// both; this file reads neither.
|
|
12
13
|
//
|
|
13
14
|
// 🔴 THE QUICKSTART GOAL STEP IS GONE (OPE-2233). This file used to register a "slack" step and a
|
|
14
15
|
// Slack leg of a hosted `deploy` plan with core's `registerQuickstartSurfaceGoal`. That plan — and
|
|
@@ -18,13 +19,12 @@
|
|
|
18
19
|
// included. Nothing was dropped except the duplicate — and the retired step's own honesty about
|
|
19
20
|
// `/setup` moved with it, to that engine step's `detail`.
|
|
20
21
|
//
|
|
21
|
-
// 🔴
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// that the credential store is not read at all.
|
|
22
|
+
// 🔴 THE TELEMETRY CREDENTIAL PROBE IS NOT HERE (OPE-2241). The bundle resolves the bot token
|
|
23
|
+
// ENV-FIRST and then from the deployment's encrypted credential store, which is where a `/setup` run
|
|
24
|
+
// puts it (agent/setup/credentials.ts). The store is reachable only through the main barrel, which
|
|
25
|
+
// this light-door file must not load (boundary-test rule 4d). So register.ts registers the probe,
|
|
26
|
+
// next to the status reporter that reads the store for the same reason. An env-only probe here
|
|
27
|
+
// reported a `/setup`-configured deployment as having no Slack credentials while its agent worked.
|
|
28
28
|
|
|
29
29
|
import {
|
|
30
30
|
agentCommandName,
|
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
declaredMcpServers,
|
|
33
33
|
getSettings,
|
|
34
34
|
registerSurfaceAppManifest,
|
|
35
|
-
registerSurfaceCredentialProbe,
|
|
36
35
|
} from "@open-everywhere/core/agent/adapter-api-ops.js";
|
|
37
36
|
import { SLACK_AS_YOU_NAME } from "./slack-as-you.js";
|
|
38
37
|
import {
|
|
@@ -59,7 +58,7 @@ export function slackManifestOptionsFromSettings(opts: { readonly appName?: stri
|
|
|
59
58
|
};
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
/** Register the slack ops-plane
|
|
61
|
+
/** Register the slack ops-plane arm (the app manifest). */
|
|
63
62
|
export function registerSlackOps(): void {
|
|
64
63
|
// THE PASTE-READY APP MANIFEST (OPE-1603). Minting the Slack app stays human, so the ops plane's
|
|
65
64
|
// job is to hand the operator the exact document. The bundle owns the document (agent/
|
|
@@ -74,10 +73,4 @@ export function registerSlackOps(): void {
|
|
|
74
73
|
template: (opts) => slackAppManifestTemplate(slackManifestOptionsFromSettings(opts)),
|
|
75
74
|
appNameMax: SLACK_APP_NAME_MAX,
|
|
76
75
|
});
|
|
77
|
-
// THE PRESENCE PROBE IS ENV-ONLY, AND THAT IS A KNOWN GAP (OPE-2231). `registerSurfaceCredentialProbe`
|
|
78
|
-
// takes `() => boolean`; resolving the credential store is async, so a `/setup`-configured deployment
|
|
79
|
-
// reports Slack as having no credentials here while the agent is working. Widening the seam to
|
|
80
|
-
// `() => boolean | Promise<boolean>` touches every reader of the probe registry in core's
|
|
81
|
-
// observability/telemetry.ts, so it is a core change with its own review rather than a line here.
|
|
82
|
-
registerSurfaceCredentialProbe("slack", () => Boolean(process.env.SLACK_BOT_TOKEN));
|
|
83
76
|
}
|
package/agent/register.ts
CHANGED
|
@@ -51,10 +51,16 @@ import {
|
|
|
51
51
|
registerProviderDocs,
|
|
52
52
|
registerWebhookVerifier,
|
|
53
53
|
registerBootNotice,
|
|
54
|
+
registerSurfaceCredentialProbe,
|
|
54
55
|
registerSurfaceStatusReporter,
|
|
55
56
|
registerMemoryWriteObserver,
|
|
56
57
|
registerDomainMembershipProbe,
|
|
58
|
+
registerFriendlyNameResolver,
|
|
59
|
+
registerBotAskProbe,
|
|
60
|
+
registerSurfaceSessionState,
|
|
57
61
|
} from "@open-everywhere/core/agent/adapter-api.js";
|
|
62
|
+
import { slackSurfaceSessionPin, slackSurfaceSessionSetter } from "./channels/slack-agent-session.js";
|
|
63
|
+
import { slackFriendlyNameResolver } from "./channels/slack-friendly-names.js";
|
|
58
64
|
import { PROVIDER_DOCS } from "./docs-generated.js";
|
|
59
65
|
import { slackSurfaceStatus } from "./status.js";
|
|
60
66
|
import { SLACK_SURFACE_PARITY } from "./surface-parity.js";
|
|
@@ -80,8 +86,11 @@ import { slackWebhookVerifier } from "./channels/slack-webhook-verifier.js";
|
|
|
80
86
|
import { registerSlackOps } from "./ops.js";
|
|
81
87
|
import { coalescedRefresh, liveMemoryCanvasDeps } from "./channels/slack-memory-canvas.js";
|
|
82
88
|
import { slackDomainMembershipProbe } from "./channels/slack-home.js";
|
|
89
|
+
import { liveSlackBotAskDeps, slackBotAskProbe } from "./channels/slack-bot-ask.js";
|
|
90
|
+
import { resolveBotIdentity } from "./channels/slack-front.js";
|
|
83
91
|
import { announceSlackSetupCode } from "./setup/claim.js";
|
|
84
92
|
import { reopenSlackSetup, slackInstallState } from "./setup/install-state.js";
|
|
93
|
+
import { slackCredentialsConfigured } from "./setup/credentials.js";
|
|
85
94
|
|
|
86
95
|
/** Perform ALL of the slack bundle's registrations. Idempotent (each register call replaces);
|
|
87
96
|
* cheap and side-effect-free beyond the registry writes (every live Slack call inside the
|
|
@@ -113,6 +122,10 @@ export function registerSlackProvider(): void {
|
|
|
113
122
|
// bounds by it (OPE-1847). A wrong or missing unit bounds the seat out of its own window.
|
|
114
123
|
registerSeatCatchUp("slack", slackSeatCatchUpFetch, { timestampPrecisionMs: SLACK_TIMESTAMP_PRECISION_MS });
|
|
115
124
|
registerReactionSurface("slack");
|
|
125
|
+
// SLACK'S AGENT SESSION STATE (OPE-2519): `processing` while a turn runs (Slack then shows its Stop
|
|
126
|
+
// button), and `active` or `suspended` at the park. Core's turn-anchor hook drives it; the setter
|
|
127
|
+
// names the person's DM session from the wake's auth (channels/slack-agent-session.ts).
|
|
128
|
+
registerSurfaceSessionState("slack", slackSurfaceSessionSetter(), slackSurfaceSessionPin);
|
|
116
129
|
// The bot's own Slack display name (OPE-587) — the arm the instruction assembler renders as a
|
|
117
130
|
// HANDLE line on a Slack-pinned session ("your mention/handle here appears as X"), never as
|
|
118
131
|
// identity since OPE-610 settled the naming model. `botDisplayName` memoises one auth.test +
|
|
@@ -139,6 +152,10 @@ export function registerSlackProvider(): void {
|
|
|
139
152
|
// Home tab's own trust gate (full member, Slack-confirmed internal channel). Core owns the seam and
|
|
140
153
|
// the fail-closed default: a platform with no probe cannot ask a domain from a DM.
|
|
141
154
|
registerDomainMembershipProbe("slack", slackDomainMembershipProbe());
|
|
155
|
+
// Chief-of-staff delegation (OPE-2426): the probe that proves an ask to another bot was the person's own
|
|
156
|
+
// message and names that bot. Core owns the seam and the fail-closed default: a platform with no probe
|
|
157
|
+
// never opens an asked thread, so no other bot's message wakes the agent there through one.
|
|
158
|
+
registerBotAskProbe("slack", slackBotAskProbe(liveSlackBotAskDeps(slackForm, resolveBotIdentity)));
|
|
142
159
|
// The bundle→core bridge for the generic spine's slack branches (see file header).
|
|
143
160
|
registerSlackBridge({
|
|
144
161
|
form: slackForm,
|
|
@@ -158,9 +175,17 @@ export function registerSlackProvider(): void {
|
|
|
158
175
|
reopenSetup: reopenSlackSetup,
|
|
159
176
|
});
|
|
160
177
|
registerSlackOps();
|
|
178
|
+
// The friendly-names guard's Slack resolver (OPE-2482): a raw member, channel or workspace id in text
|
|
179
|
+
// a person reads renders as a display name, a #name or the workspace name.
|
|
180
|
+
registerFriendlyNameResolver("slack", slackFriendlyNameResolver());
|
|
161
181
|
// The deployment-status surface's slack arm (OPE-2230) — HERE and not in ops.ts, because it
|
|
162
182
|
// reads the operational store and ops.ts is the light-door half the standalone MCP server loads.
|
|
163
183
|
registerSurfaceStatusReporter("slack", () => slackSurfaceStatus());
|
|
184
|
+
// The telemetry heartbeat's credential-presence probe (OPE-2241). HERE and not in ops.ts for the same
|
|
185
|
+
// reason: it reads the encrypted credential store, where `/setup` puts the bot token, and the light
|
|
186
|
+
// door cannot reach the store. The heartbeat runs only in the agent runtime, so the standalone ops
|
|
187
|
+
// MCP server loses nothing.
|
|
188
|
+
registerSurfaceCredentialProbe("slack", () => slackCredentialsConfigured());
|
|
164
189
|
// Webhook-verifier plane (OPE-164, populated for slack by OPE-197): Slack's `v0=` HMAC scheme, so
|
|
165
190
|
// a GENERIC hook can declare `source: "slack"` and be verified the way Slack signs. Changes no
|
|
166
191
|
// existing route — `/eve/v1/slack` and `/eve/v1/slack/commands` keep their own inline gate over
|
|
@@ -249,6 +249,23 @@ export async function slackBotToken(deps: SlackCredentialDeps = {}): Promise<str
|
|
|
249
249
|
return (await resolveSlackSecret(SLACK_BOT_TOKEN_ENV, fromEnv, SLACK_BOT_TOKEN_REF, deps))?.value;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Does this deployment hold a Slack bot token in EITHER home? The telemetry heartbeat's
|
|
254
|
+
* credential-presence probe (OPE-2241). Same order as {@link slackBotToken}: env first, then the store.
|
|
255
|
+
*
|
|
256
|
+
* 🔴 A SET ENV VAR ANSWERS WITHOUT THE STORE. `slackBotToken` reads the store once per process even
|
|
257
|
+
* when the env var is set, for the env-shadows-store notice. On the heartbeat path that read would cost
|
|
258
|
+
* a process that does no Slack work a store round trip, and a slow store would lose the census's
|
|
259
|
+
* two-second race: an env-configured deployment, which reported `slack` before OPE-2241, would then
|
|
260
|
+
* report it absent. So the env home is checked here first, and only an empty env var reads the store,
|
|
261
|
+
* through the same memo as every outbound call.
|
|
262
|
+
*/
|
|
263
|
+
export async function slackCredentialsConfigured(deps: SlackCredentialDeps = {}): Promise<boolean> {
|
|
264
|
+
const env = deps.env ?? process.env;
|
|
265
|
+
if ((env[SLACK_BOT_TOKEN_ENV] ?? "").trim().length > 0) return true;
|
|
266
|
+
return (await slackBotToken(deps)) !== undefined;
|
|
267
|
+
}
|
|
268
|
+
|
|
252
269
|
/**
|
|
253
270
|
* Is `name`'s env var set, for the ONE caller that needs to ask without resolving — the `/setup`
|
|
254
271
|
* page's "this env var will shadow what you are about to store" notice.
|
package/agent/setup/page.ts
CHANGED
|
@@ -316,9 +316,12 @@ function doneScreen(state: SlackInstallState): Response {
|
|
|
316
316
|
`<pre style="${CODE_BLOCK_STYLE}">${escapeHtml(surfaceLine)}</pre>` +
|
|
317
317
|
`<p><strong>2.</strong> In <code>agent/memory/config/domains/org.ts</code>, replace the <code>admins</code> line:</p>` +
|
|
318
318
|
`<pre style="${CODE_BLOCK_STYLE}">${escapeHtml(adminLine)}</pre>` +
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
319
|
+
// OPE-2492 — this used to say "DM the bot and it will open a pull request". No config-change card
|
|
320
|
+
// writes the trust vouch or the admin roster, and on a fresh install no card can open a pull
|
|
321
|
+
// request at all (no config repo, admin channel or GitHub app yet).
|
|
322
|
+
`<p><strong>Then make the two edits by hand and push.</strong> The deploy that lands them is the ` +
|
|
323
|
+
`last step. The bot does not change its own admins from chat. To see what it can change from ` +
|
|
324
|
+
`chat, ask it.</p>` +
|
|
322
325
|
`<p>This page is now closed. An administrator can reopen it with the <code>reopen_slack_setup</code> ` +
|
|
323
326
|
`control call.</p>`,
|
|
324
327
|
);
|
package/agent/surface-parity.ts
CHANGED
|
@@ -57,6 +57,8 @@ export const SLACK_SURFACE_PARITY: SurfaceParityDeclaration = {
|
|
|
57
57
|
// the one "This should not have run" button, and `slack-front.ts` routes that tap back through
|
|
58
58
|
// core's shared `contradict` decision.
|
|
59
59
|
"judge-lift-notice": "supported",
|
|
60
|
+
// OPE-2513: `routeSupervisorEvent` asks core on every seated channel wake (slack-events.ts).
|
|
61
|
+
"out-of-office-cover": "supported",
|
|
60
62
|
|
|
61
63
|
// --- wake legs and conversation shapes -------------------------------------------------------
|
|
62
64
|
"addressed-leg": "supported",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-attachment-fetch.d.ts","sourceRoot":"","sources":["../../../agent/access/slack-attachment-fetch.ts"],"names":[],"mappings":"AAmCA,OAAO,EAIL,KAAK,eAAe,EAGrB,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"slack-attachment-fetch.d.ts","sourceRoot":"","sources":["../../../agent/access/slack-attachment-fetch.ts"],"names":[],"mappings":"AAmCA,OAAO,EAIL,KAAK,eAAe,EAGrB,MAAM,4CAA4C,CAAC;AAwBpD;kFACkF;AAClF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sFAAsF;IACtF,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2F/G"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-attachment-fetch.js","sourceRoot":"","sources":["../../../agent/access/slack-attachment-fetch.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,0EAA0E;AAC1E,EAAE;AACF,+FAA+F;AAC/F,iGAAiG;AACjG,8FAA8F;AAC9F,kGAAkG;AAClG,+FAA+F;AAC/F,yDAAyD;AACzD,EAAE;AACF,8FAA8F;AAC9F,iFAAiF;AACjF,4FAA4F;AAC5F,kGAAkG;AAClG,mGAAmG;AACnG,qFAAqF;AACrF,EAAE;AACF,iGAAiG;AACjG,iGAAiG;AACjG,kGAAkG;AAClG,EAAE;AACF,8EAA8E;AAC9E,gGAAgG;AAChG,gGAAgG;AAChG,oCAAoC;AACpC,EAAE;AACF,iGAAiG;AACjG,oGAAoG;AACpG,iGAAiG;AACjG,qGAAqG;AACrG,iGAAiG;AACjG,oGAAoG;AACpG,2FAA2F;AAC3F,8FAA8F;AAE9F,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,mBAAmB,GAIpB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"slack-attachment-fetch.js","sourceRoot":"","sources":["../../../agent/access/slack-attachment-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-manifest.d.ts","sourceRoot":"","sources":["../../agent/app-manifest.ts"],"names":[],"mappings":"AAeA;;mEAEmE;AACnE,eAAO,MAAM,6BAA6B,oBAAoB,CAAC;AAE/D;yFACyF;AACzF,eAAO,MAAM,sBAAsB,oBAAoB,CAAC;AAKxD,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,oGAAoG;AACpG,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;0GAC0G;AAC1G,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnE;AAED;;kFAEkF;AAClF,MAAM,WAAW,uBAAuB;IACtC;;yBAEqB;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;0CAEsC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;8CAC0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7F;AAED,8FAA8F;AAC9F,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAU/C;;6DAE6D;AAC7D,eAAO,MAAM,oCAAoC,uBAAuB,CAAC;AAEzE;iGACiG;AACjG,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,uBAA4B,GAAG,MAAM,CAM/E;AAQD;+DAC+D;AAC/D,wBAAgB,wBAAwB,CAAC,IAAI,GAAE,uBAA4B,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"app-manifest.d.ts","sourceRoot":"","sources":["../../agent/app-manifest.ts"],"names":[],"mappings":"AAeA;;mEAEmE;AACnE,eAAO,MAAM,6BAA6B,oBAAoB,CAAC;AAE/D;yFACyF;AACzF,eAAO,MAAM,sBAAsB,oBAAoB,CAAC;AAKxD,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,oGAAoG;AACpG,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;0GAC0G;AAC1G,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnE;AAED;;kFAEkF;AAClF,MAAM,WAAW,uBAAuB;IACtC;;yBAEqB;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;0CAEsC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;8CAC0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7F;AAED,8FAA8F;AAC9F,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAU/C;;6DAE6D;AAC7D,eAAO,MAAM,oCAAoC,uBAAuB,CAAC;AAEzE;iGACiG;AACjG,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,uBAA4B,GAAG,MAAM,CAM/E;AAQD;+DAC+D;AAC/D,wBAAgB,wBAAwB,CAAC,IAAI,GAAE,uBAA4B,GAAG,MAAM,CAsNnF;AAED,8CAA8C;AAC9C,eAAO,MAAM,qBAAqB,+BAA+B,CAAC;AAElE,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAQrD,CAAC;AAEF;;8BAE8B;AAC9B,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAKvD,CAAC"}
|
|
@@ -106,7 +106,7 @@ export function slackAppManifestTemplate(opts = {}) {
|
|
|
106
106
|
description: `${appName} control-plane commands (stop, status, budget) — no model turn.`,
|
|
107
107
|
// Every subcommand `parseOeCommandTokens` accepts (packages/core/agent/commands/core.ts).
|
|
108
108
|
// scripts/slack-app-manifest-test.ts fails if one is missing here.
|
|
109
|
-
usage_hint: "stop | status | budget [raise <usd> | clear] | rate <n> | optout [on | off] | help",
|
|
109
|
+
usage_hint: "stop | status | budget [raise <usd> | clear] | rate <n> | optout [on | off] | watch [more | less | none] | cover [on | off] | suggest [on | off] | help",
|
|
110
110
|
should_escape: false,
|
|
111
111
|
},
|
|
112
112
|
],
|
|
@@ -199,6 +199,17 @@ export function slackAppManifestTemplate(opts = {}) {
|
|
|
199
199
|
// knows. Without it the canvas refresh fails with `missing_scope`, logged and audited
|
|
200
200
|
// per channel, and memory itself is unaffected.
|
|
201
201
|
"canvases:write",
|
|
202
|
+
// canvases.sections.lookup — find a memory canvas made before the `memory_canvas` row
|
|
203
|
+
// existed, by the marker line it carries (OPE-2587, core channels/slack-canvas-list.ts
|
|
204
|
+
// `memoryCanvasAmong`). Without it such a canvas held only as a channel tab is not found:
|
|
205
|
+
// its refresh and take-down record `failed` and `clear-failed`, and nothing is overwritten.
|
|
206
|
+
"canvases:read",
|
|
207
|
+
// slackLists.items.list / .create / .update — the agent's own List writes (OPE-2521,
|
|
208
|
+
// core tools/update_list.ts): it reads a List's rows to match one by name, then adds or
|
|
209
|
+
// changes rows on a person's approval. `canvases:write` above also covers the agent's own
|
|
210
|
+
// canvas writes (canvases.create, canvases.edit; core tools/write_canvas.ts).
|
|
211
|
+
"lists:read",
|
|
212
|
+
"lists:write",
|
|
202
213
|
// The side panel (OPE-2457): Slack requires it for `app_context_changed`, the event whose
|
|
203
214
|
// subscription makes Slack attach the viewed room to each side-panel `message.im`.
|
|
204
215
|
"assistant:write",
|
|
@@ -227,6 +238,8 @@ export function slackAppManifestTemplate(opts = {}) {
|
|
|
227
238
|
// channel_shared → channels:read, groups:read (re-run the memory canvas gate, OPE-2451)
|
|
228
239
|
// user_change → users:read (automatic offboarding on a deactivated member, OPE-2423)
|
|
229
240
|
// app_context_changed → assistant:write (the side panel's viewed room, OPE-2457)
|
|
241
|
+
// agent_session_stopped → chat:write (Slack's native Stop button on an agent session,
|
|
242
|
+
// OPE-2519; Slack shows the button only to an app subscribed to it)
|
|
230
243
|
// scripts/slack-app-manifest-test.ts derives the handled set from the code and fails if
|
|
231
244
|
// this list drops one (OPE-2223).
|
|
232
245
|
bot_events: [
|
|
@@ -242,6 +255,7 @@ export function slackAppManifestTemplate(opts = {}) {
|
|
|
242
255
|
"channel_shared",
|
|
243
256
|
"user_change",
|
|
244
257
|
"app_context_changed",
|
|
258
|
+
"agent_session_stopped",
|
|
245
259
|
],
|
|
246
260
|
},
|
|
247
261
|
// The INTERACTIVITY Request URL — the SAME public route Event Subscriptions uses. Every
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-manifest.js","sourceRoot":"","sources":["../../agent/app-manifest.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"app-manifest.js","sourceRoot":"","sources":["../../agent/app-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { cancelAnchoredTurn, type AttachSessionForCancel, type CancelResult, type SurfaceSessionPinner, type SurfaceSessionSetter } from "@open-everywhere/core/agent/adapter-api.js";
|
|
2
|
+
import { type SlackEventEnvelope } from "./slack-events.js";
|
|
3
|
+
/** Slack's event for a press of the session's Stop button. */
|
|
4
|
+
export declare const AGENT_SESSION_STOPPED_EVENT = "agent_session_stopped";
|
|
5
|
+
/** The longest title OE sets. Slack accepts 200 characters; a session list shows far fewer. */
|
|
6
|
+
export declare const SLACK_SESSION_TITLE_MAX = 60;
|
|
7
|
+
/** The session states OE sets. */
|
|
8
|
+
export type SlackSessionStatus = "processing" | "active" | "suspended";
|
|
9
|
+
/** The form-call seam: `slackForm` in production, a recorder in the tests. */
|
|
10
|
+
export type SlackFormCall = (method: string, body: string) => Promise<Record<string, unknown> | undefined>;
|
|
11
|
+
/**
|
|
12
|
+
* The session title for a conversation that opens with `text`, or undefined when nothing readable is
|
|
13
|
+
* left. Pure. It keeps the first non-empty line, renders a link as its label, a channel as `#name`, and
|
|
14
|
+
* drops a member or group mention (no raw id reaches the title). It strips `*`, `~` and backticks, and
|
|
15
|
+
* keeps `_`, so an identifier such as `oe_config` stays intact. A long line is cut at a word and ends
|
|
16
|
+
* with `…`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function slackSessionTitle(text: string | undefined): string | undefined;
|
|
19
|
+
/** One `agents.sessions.setStatus` call. */
|
|
20
|
+
export interface SlackSessionStatusCall {
|
|
21
|
+
readonly channelId: string;
|
|
22
|
+
/** The session's thread root. */
|
|
23
|
+
readonly threadTs: string;
|
|
24
|
+
readonly status: SlackSessionStatus;
|
|
25
|
+
/** Applied only when this call creates the session. */
|
|
26
|
+
readonly title?: string;
|
|
27
|
+
}
|
|
28
|
+
/** The form body of {@link SlackSessionStatusCall}. Pure. */
|
|
29
|
+
export declare function slackSessionStatusForm(call: SlackSessionStatusCall): string;
|
|
30
|
+
/** Set a session's status (and, on creation, its title). True when Slack answered `ok`. Never throws. */
|
|
31
|
+
export declare function setSlackSessionStatus(call: SlackSessionStatusCall, form?: SlackFormCall): Promise<boolean>;
|
|
32
|
+
/**
|
|
33
|
+
* The session a delivery's auth attributes name, or undefined for none. Only a delivery the DM door
|
|
34
|
+
* stamped (`agent_session_ts`) names one: a shortcut, a group DM and every channel carry no stamp, so
|
|
35
|
+
* they never set a session's state, even on a threaded message. Pure.
|
|
36
|
+
*/
|
|
37
|
+
export declare function slackAgentSessionOf(attributes: Readonly<Record<string, unknown>>): {
|
|
38
|
+
readonly channelId: string;
|
|
39
|
+
readonly threadTs: string;
|
|
40
|
+
} | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* The Slack pinner (OPE-2536): the session a delivery names, as the setter's own id and the three
|
|
43
|
+
* attributes that name it again. A forwarded job keeps this, so its settlement can set the session
|
|
44
|
+
* `suspended` long after the delivery's auth is gone. Ids only, never text. Pure.
|
|
45
|
+
*/
|
|
46
|
+
export declare const slackSurfaceSessionPin: SurfaceSessionPinner;
|
|
47
|
+
/** The Slack setter core's turn-anchor hook calls (registered in register.ts). */
|
|
48
|
+
export declare function slackSurfaceSessionSetter(form?: SlackFormCall): SurfaceSessionSetter;
|
|
49
|
+
/** One press of the Stop button, as the route reads it. */
|
|
50
|
+
export interface ParsedSessionStop {
|
|
51
|
+
readonly channelId: string;
|
|
52
|
+
/** The session's thread root. */
|
|
53
|
+
readonly threadTs: string;
|
|
54
|
+
/** Who pressed Stop. */
|
|
55
|
+
readonly userId: string;
|
|
56
|
+
/** From the `event_callback` envelope: Slack does not put it in the event. */
|
|
57
|
+
readonly teamId?: string;
|
|
58
|
+
readonly eventTs?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Parse an `agent_session_stopped` envelope, or null for anything else. Pure. */
|
|
61
|
+
export declare function parseAgentSessionStopped(envelope: SlackEventEnvelope): ParsedSessionStop | null;
|
|
62
|
+
/** What the Stop route needs. */
|
|
63
|
+
export interface SessionStopDeps {
|
|
64
|
+
/** eve's I/O-free cancel door, the same one the ✋ arm uses. */
|
|
65
|
+
readonly attachSession: AttachSessionForCancel;
|
|
66
|
+
/** The cancel path. Absent means the live `cancelAnchoredTurn`. */
|
|
67
|
+
readonly cancel?: typeof cancelAnchoredTurn;
|
|
68
|
+
/** The status call. Absent means the live {@link setSlackSessionStatus}. */
|
|
69
|
+
readonly setStatus?: (call: SlackSessionStatusCall) => Promise<boolean>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Stop the turn a Stop press names, then set the session `active`.
|
|
73
|
+
*
|
|
74
|
+
* The turn is found by the session's thread first (the key the ✋ arm uses for a thread root). In the
|
|
75
|
+
* person's 1:1 DM it falls back to the DM's newest turn, because a top-level DM message keys its turn by
|
|
76
|
+
* the channel alone. In a shared channel it does not fall back: there the newest turn can belong to
|
|
77
|
+
* another thread, and cancelling nothing beats cancelling a guess. The status is set whatever the
|
|
78
|
+
* cancel answers, because a session left `processing` keeps its spinner for an hour. Never throws.
|
|
79
|
+
*/
|
|
80
|
+
export declare function routeAgentSessionStop(ev: ParsedSessionStop, deps: SessionStopDeps): Promise<CancelResult>;
|
|
81
|
+
//# sourceMappingURL=slack-agent-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-agent-session.d.ts","sourceRoot":"","sources":["../../../agent/channels/slack-agent-session.ts"],"names":[],"mappings":"AAqCA,OAAO,EACL,kBAAkB,EAIlB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC1B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAkC,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5F,8DAA8D;AAC9D,eAAO,MAAM,2BAA2B,0BAA0B,CAAC;AAEnE,+FAA+F;AAC/F,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,kCAAkC;AAClC,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAKvE,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;AAS3G;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAsB9E;AAID,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,uDAAuD;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,6DAA6D;AAC7D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAI3E;AAED,yGAAyG;AACzG,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,sBAAsB,EAAE,IAAI,GAAE,aAAyB,GAAG,OAAO,CAAC,OAAO,CAAC,CAU3H;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAMxJ;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,oBAOpC,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,yBAAyB,CAAC,IAAI,GAAE,aAAyB,GAAG,oBAAoB,CAO/F;AAID,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wBAAwB;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,iBAAiB,GAAG,IAAI,CAgB/F;AAOD,iCAAiC;AACjC,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,aAAa,EAAE,sBAAsB,CAAC;IAC/C,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,kBAAkB,CAAC;IAC5C,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAoB/G"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// THE SLACK AGENT SESSION (OPE-2519) — Slack's native Stop, the session title, and the "needs you" state.
|
|
2
|
+
//
|
|
3
|
+
// Slack's agent experience shows each conversation with the app as an AGENT SESSION, keyed by the
|
|
4
|
+
// channel and the thread root (docs.slack.dev/ai/agent-sessions, re-read 2026-10-14). A session has a
|
|
5
|
+
// lifecycle status (`processing`, `active`, `suspended`, `closed`) and a title. This file owns the three
|
|
6
|
+
// things OE does with it:
|
|
7
|
+
//
|
|
8
|
+
// • STOP. While a session is `processing`, Slack shows a Stop button, but only to an app that
|
|
9
|
+
// subscribes to `agent_session_stopped`. A press arrives as that event. It takes the SAME cancel
|
|
10
|
+
// path as the ✋ reaction and `/oe stop` (`cancelAnchoredTurn`): no session is minted, no model is
|
|
11
|
+
// called, nothing is spent. Slack does not move the status itself, so the route sets `active`.
|
|
12
|
+
// • TITLE. A top-level message the person sends in their DM with the app opens a new conversation,
|
|
13
|
+
// and gets a short title from the words the person TYPED (`authoredText`). The lines of a
|
|
14
|
+
// forwarded or quoted message are another conversation's words, so they never title it. The host
|
|
15
|
+
// derives the title in code: no model writes it. Slack applies a `title` only when the call
|
|
16
|
+
// CREATES the session, so a title the person typed over ours is never overwritten. A thread reply,
|
|
17
|
+
// a shortcut and a group DM get no title.
|
|
18
|
+
// • STATE. Core's turn-anchor hook sets the session `processing` when a turn starts, and at the park
|
|
19
|
+
// `suspended` when the turn reported through `update_status` that it waits on a person
|
|
20
|
+
// (`needs_input` or `blocked`), else `active` (channels/surface-session-state.ts). This file
|
|
21
|
+
// registers the Slack setter: it names the session from the delivery's auth attributes. The
|
|
22
|
+
// person's next message sets `processing`, then parks `active` unless it reports again that it
|
|
23
|
+
// waits on the person. A job's result wake names no session, so its turn sets no state.
|
|
24
|
+
// • A FORWARDED JOB's WAIT (OPE-2536). A job the DM seat forwards to the work session can end waiting
|
|
25
|
+
// on the person: it asked a question in the room (`ask_room`), or it needs their own sign-in. The
|
|
26
|
+
// work session has no `update_status`, so the host sets the session `suspended` at the job's
|
|
27
|
+
// settlement (core channels/work-surface-wait.ts). This file registers the PIN for that: the
|
|
28
|
+
// session's id and the three attributes that name it again, kept on the job.
|
|
29
|
+
//
|
|
30
|
+
// WHICH SESSIONS. Only the person's 1:1 DM with the app (the Messages tab and the side panel), where
|
|
31
|
+
// Slack lists the person's agent sessions. The DM door stamps the session's thread root on the wake's
|
|
32
|
+
// auth (`agent_session_ts`): a top-level message opens its own session, keyed by its own `ts`, and a
|
|
33
|
+
// thread reply belongs to its thread's session. A channel thread gets no state from OE.
|
|
34
|
+
//
|
|
35
|
+
// Every call here is best-effort. A workspace without Slack's agent features answers an error, which
|
|
36
|
+
// is logged and changes nothing else.
|
|
37
|
+
import { cancelAnchoredTurn, resolvePartition, turnAnchorKey, turnChannelKey, } from "@open-everywhere/core/agent/adapter-api.js";
|
|
38
|
+
import { bindableForSlackIds, slackForm } from "./slack-events.js";
|
|
39
|
+
/** Slack's event for a press of the session's Stop button. */
|
|
40
|
+
export const AGENT_SESSION_STOPPED_EVENT = "agent_session_stopped";
|
|
41
|
+
/** The longest title OE sets. Slack accepts 200 characters; a session list shows far fewer. */
|
|
42
|
+
export const SLACK_SESSION_TITLE_MAX = 60;
|
|
43
|
+
/** The auth attribute the DM door stamps with the session's thread root (slack-front.ts `scheduleDmWake`). */
|
|
44
|
+
const AGENT_SESSION_TS_ATTRIBUTE = "agent_session_ts";
|
|
45
|
+
// --- the title ------------------------------------------------------------------------------------
|
|
46
|
+
/** Slack's three escaped characters, decoded. */
|
|
47
|
+
function decodeSlackEntities(text) {
|
|
48
|
+
return text.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The session title for a conversation that opens with `text`, or undefined when nothing readable is
|
|
52
|
+
* left. Pure. It keeps the first non-empty line, renders a link as its label, a channel as `#name`, and
|
|
53
|
+
* drops a member or group mention (no raw id reaches the title). It strips `*`, `~` and backticks, and
|
|
54
|
+
* keeps `_`, so an identifier such as `oe_config` stays intact. A long line is cut at a word and ends
|
|
55
|
+
* with `…`.
|
|
56
|
+
*/
|
|
57
|
+
export function slackSessionTitle(text) {
|
|
58
|
+
if (typeof text !== "string")
|
|
59
|
+
return undefined;
|
|
60
|
+
const rendered = text
|
|
61
|
+
// A member mention, with or without a label: dropped.
|
|
62
|
+
.replace(/<@[A-Z0-9]+(?:\|[^>]*)?>/g, " ")
|
|
63
|
+
// A channel mention: its name when Slack sent one, else dropped.
|
|
64
|
+
.replace(/<#[A-Z0-9]+\|([^>]+)>/g, "#$1")
|
|
65
|
+
.replace(/<#[A-Z0-9]+>/g, " ")
|
|
66
|
+
// A special or group mention (`<!here>`, `<!subteam^S1|@team>`): dropped.
|
|
67
|
+
.replace(/<![^>]*>/g, " ")
|
|
68
|
+
// A link: its label, else the address.
|
|
69
|
+
.replace(/<[^>|]+\|([^>]+)>/g, "$1")
|
|
70
|
+
.replace(/<([^>]+)>/g, "$1");
|
|
71
|
+
const line = decodeSlackEntities(rendered)
|
|
72
|
+
.split(/\r?\n/)
|
|
73
|
+
.map((l) => l.replace(/[*~`]+/g, "").replace(/\s+/g, " ").trim())
|
|
74
|
+
.find((l) => l.length > 0);
|
|
75
|
+
if (line === undefined)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (line.length <= SLACK_SESSION_TITLE_MAX)
|
|
78
|
+
return line;
|
|
79
|
+
const head = line.slice(0, SLACK_SESSION_TITLE_MAX - 1);
|
|
80
|
+
const cut = head.lastIndexOf(" ");
|
|
81
|
+
return `${(cut >= SLACK_SESSION_TITLE_MAX / 2 ? head.slice(0, cut) : head).trimEnd()}…`;
|
|
82
|
+
}
|
|
83
|
+
/** The form body of {@link SlackSessionStatusCall}. Pure. */
|
|
84
|
+
export function slackSessionStatusForm(call) {
|
|
85
|
+
const body = new URLSearchParams({ channel_id: call.channelId, thread_ts: call.threadTs, status: call.status });
|
|
86
|
+
if (call.title !== undefined && call.title.length > 0)
|
|
87
|
+
body.set("title", call.title);
|
|
88
|
+
return body.toString();
|
|
89
|
+
}
|
|
90
|
+
/** Set a session's status (and, on creation, its title). True when Slack answered `ok`. Never throws. */
|
|
91
|
+
export async function setSlackSessionStatus(call, form = slackForm) {
|
|
92
|
+
try {
|
|
93
|
+
const res = await form("agents.sessions.setStatus", slackSessionStatusForm(call));
|
|
94
|
+
if (res?.ok === true)
|
|
95
|
+
return true;
|
|
96
|
+
console.warn(`[open-everywhere:slack-session] agents.sessions.setStatus ${call.status} was not applied (${call.channelId}/${call.threadTs}): ${String(res?.error ?? "no answer")}`);
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
console.warn(`[open-everywhere:slack-session] agents.sessions.setStatus ${call.status} failed (${call.channelId}/${call.threadTs}): ${String(err)}`);
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The session a delivery's auth attributes name, or undefined for none. Only a delivery the DM door
|
|
106
|
+
* stamped (`agent_session_ts`) names one: a shortcut, a group DM and every channel carry no stamp, so
|
|
107
|
+
* they never set a session's state, even on a threaded message. Pure.
|
|
108
|
+
*/
|
|
109
|
+
export function slackAgentSessionOf(attributes) {
|
|
110
|
+
if (attributes.channel_type !== "im")
|
|
111
|
+
return undefined;
|
|
112
|
+
const channelId = attributes.channel_id;
|
|
113
|
+
const stamped = attributes[AGENT_SESSION_TS_ATTRIBUTE];
|
|
114
|
+
if (typeof channelId !== "string" || channelId.length === 0 || typeof stamped !== "string" || stamped.length === 0)
|
|
115
|
+
return undefined;
|
|
116
|
+
return { channelId, threadTs: stamped };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The Slack pinner (OPE-2536): the session a delivery names, as the setter's own id and the three
|
|
120
|
+
* attributes that name it again. A forwarded job keeps this, so its settlement can set the session
|
|
121
|
+
* `suspended` long after the delivery's auth is gone. Ids only, never text. Pure.
|
|
122
|
+
*/
|
|
123
|
+
export const slackSurfaceSessionPin = (attributes) => {
|
|
124
|
+
const session = slackAgentSessionOf(attributes);
|
|
125
|
+
if (!session)
|
|
126
|
+
return undefined;
|
|
127
|
+
return {
|
|
128
|
+
id: `${session.channelId}:${session.threadTs}`,
|
|
129
|
+
attributes: { channel_id: session.channelId, channel_type: "im", [AGENT_SESSION_TS_ATTRIBUTE]: session.threadTs },
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
/** The Slack setter core's turn-anchor hook calls (registered in register.ts). */
|
|
133
|
+
export function slackSurfaceSessionSetter(form = slackForm) {
|
|
134
|
+
return async (attributes, status) => {
|
|
135
|
+
const session = slackAgentSessionOf(attributes);
|
|
136
|
+
if (!session)
|
|
137
|
+
return undefined;
|
|
138
|
+
await setSlackSessionStatus({ ...session, status }, form);
|
|
139
|
+
return `${session.channelId}:${session.threadTs}`;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Parse an `agent_session_stopped` envelope, or null for anything else. Pure. */
|
|
143
|
+
export function parseAgentSessionStopped(envelope) {
|
|
144
|
+
if (envelope?.type !== "event_callback")
|
|
145
|
+
return null;
|
|
146
|
+
const e = envelope.event;
|
|
147
|
+
if (!e || e.type !== AGENT_SESSION_STOPPED_EVENT)
|
|
148
|
+
return null;
|
|
149
|
+
const channelId = typeof e.channel === "string" ? e.channel : "";
|
|
150
|
+
const threadTs = typeof e.thread_ts === "string" ? e.thread_ts : "";
|
|
151
|
+
const userId = typeof e.user === "string" ? e.user : "";
|
|
152
|
+
if (!channelId || !threadTs || !userId)
|
|
153
|
+
return null;
|
|
154
|
+
const teamId = typeof envelope.team_id === "string" && envelope.team_id.length > 0 ? envelope.team_id : undefined;
|
|
155
|
+
return {
|
|
156
|
+
channelId,
|
|
157
|
+
threadTs,
|
|
158
|
+
userId,
|
|
159
|
+
...(teamId ? { teamId } : {}),
|
|
160
|
+
...(typeof e.event_ts === "string" ? { eventTs: e.event_ts } : {}),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** A 1:1 DM channel id. Only there does the stop fall back to the channel's newest turn. */
|
|
164
|
+
function isDmChannel(channelId) {
|
|
165
|
+
return channelId.startsWith("D");
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Stop the turn a Stop press names, then set the session `active`.
|
|
169
|
+
*
|
|
170
|
+
* The turn is found by the session's thread first (the key the ✋ arm uses for a thread root). In the
|
|
171
|
+
* person's 1:1 DM it falls back to the DM's newest turn, because a top-level DM message keys its turn by
|
|
172
|
+
* the channel alone. In a shared channel it does not fall back: there the newest turn can belong to
|
|
173
|
+
* another thread, and cancelling nothing beats cancelling a guess. The status is set whatever the
|
|
174
|
+
* cancel answers, because a session left `processing` keeps its spinner for an hour. Never throws.
|
|
175
|
+
*/
|
|
176
|
+
export async function routeAgentSessionStop(ev, deps) {
|
|
177
|
+
const p = resolvePartition(bindableForSlackIds({ teamId: ev.teamId, channelId: ev.channelId, userId: ev.userId }));
|
|
178
|
+
const anchorKey = turnAnchorKey("slack", ev.channelId, ev.threadTs);
|
|
179
|
+
const channelKey = isDmChannel(ev.channelId) ? turnChannelKey("slack", ev.channelId) : undefined;
|
|
180
|
+
let result;
|
|
181
|
+
try {
|
|
182
|
+
result = await (deps.cancel ?? cancelAnchoredTurn)({
|
|
183
|
+
org: p.org,
|
|
184
|
+
platform: "slack",
|
|
185
|
+
workspace: p.workspace,
|
|
186
|
+
requestedBy: ev.userId,
|
|
187
|
+
via: "stop-button",
|
|
188
|
+
query: { ...(anchorKey ? { anchorKey } : {}), ...(channelKey ? { channelKey } : {}) },
|
|
189
|
+
attachSession: deps.attachSession,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
result = { outcome: "error", message: `stop failed: ${String(err)}` };
|
|
194
|
+
}
|
|
195
|
+
await (deps.setStatus ?? setSlackSessionStatus)({ channelId: ev.channelId, threadTs: ev.threadTs, status: "active" }).catch(() => false);
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=slack-agent-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-agent-session.js","sourceRoot":"","sources":["../../../agent/channels/slack-agent-session.ts"],"names":[],"mappings":"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"}
|