@cuylabs/channel-slack 0.9.0 → 0.11.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/README.md +15 -2
- package/dist/adapter/index.d.ts +53 -0
- package/dist/adapter/index.js +13 -0
- package/dist/app-surface.d.ts +86 -0
- package/dist/app-surface.js +15 -0
- package/dist/app.d.ts +58 -0
- package/dist/app.js +86 -0
- package/dist/artifacts/index.d.ts +57 -3
- package/dist/artifacts/index.js +88 -0
- package/dist/assistant/index.d.ts +18 -53
- package/dist/assistant/index.js +15 -184
- package/dist/bolt-app-BM0tiL7c.d.ts +49 -0
- package/dist/{chunk-TWJGVDA2.js → chunk-37RN2YUI.js} +88 -1
- package/dist/chunk-IAQXQESO.js +1008 -0
- package/dist/chunk-LFQCINHI.js +187 -0
- package/dist/chunk-Q6YX7HHK.js +1062 -0
- package/dist/chunk-RHOIVQLD.js +127 -0
- package/dist/chunk-RTDLIYEE.js +446 -0
- package/dist/core.d.ts +5 -201
- package/dist/core.js +10 -12
- package/dist/feedback/index.d.ts +2 -2
- package/dist/feedback/index.js +5 -120
- package/dist/formatting-C-kwQseI.d.ts +25 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +18 -12
- package/dist/interactive/index.d.ts +4 -91
- package/dist/options-B0xQCaez.d.ts +221 -0
- package/dist/options-DQacQDmD.d.ts +368 -0
- package/dist/runtime/index.d.ts +46 -0
- package/dist/runtime/index.js +10 -0
- package/dist/socket.d.ts +142 -0
- package/dist/socket.js +77 -0
- package/dist/transports/index.d.ts +2 -1
- package/dist/transports/socket/index.d.ts +4 -49
- package/dist/turn-BGAXddH_.d.ts +178 -0
- package/dist/types-Cywfj8Mj.d.ts +91 -0
- package/dist/types-wLZzyI9r.d.ts +375 -0
- package/docs/reference/exports.md +5 -1
- package/package.json +28 -3
- package/dist/chunk-ISOMBQXE.js +0 -89
package/README.md
CHANGED
|
@@ -5,8 +5,9 @@ Agent-runtime-agnostic Slack channel primitives.
|
|
|
5
5
|
This package owns reusable Slack mechanics: event parsing, message admission,
|
|
6
6
|
history loading, formatting, setup inspection, auth helpers, entrypoint
|
|
7
7
|
normalization, artifact publishing, interactive request rendering/storage,
|
|
8
|
-
response sink contracts,
|
|
9
|
-
create or run an agent, and it does
|
|
8
|
+
response sink contracts, Slack Assistant/classic message mounting, and HTTP or
|
|
9
|
+
Socket Mode transport helpers. It does not create or run an agent, and it does
|
|
10
|
+
not depend on an agent SDK.
|
|
10
11
|
|
|
11
12
|
Runtime-specific adapters should compose these primitives with their own turn
|
|
12
13
|
types, event streams, tools, prompts, and deployment policy.
|
|
@@ -58,6 +59,18 @@ Most adapters follow the same shape:
|
|
|
58
59
|
4. Run the application-owned runtime.
|
|
59
60
|
5. Format the response for Slack.
|
|
60
61
|
|
|
62
|
+
For a runtime-neutral direct Slack mount, pass a `SlackTurnSource`:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { mountSlackAppSocket } from "@cuylabs/channel-slack/socket";
|
|
66
|
+
|
|
67
|
+
await mountSlackAppSocket({
|
|
68
|
+
source,
|
|
69
|
+
appToken: process.env.SLACK_APP_TOKEN,
|
|
70
|
+
botToken: process.env.SLACK_BOT_TOKEN,
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
61
74
|
## Documentation
|
|
62
75
|
|
|
63
76
|
- [Package boundary](docs/reference/channel-slack-boundary.md)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { a as SlackChannelOptions, S as SlackChannelAdapter } from '../types-wLZzyI9r.js';
|
|
2
|
+
export { b as SlackSessionStrategy, c as SlackStreamingMode, d as SlackToolStartEvent } from '../types-wLZzyI9r.js';
|
|
3
|
+
import { S as SlackActivityInfo } from '../activity-ByrD9Ftr.js';
|
|
4
|
+
import '../turn-BGAXddH_.js';
|
|
5
|
+
import '../interactive-CbKYkkc_.js';
|
|
6
|
+
import '../options-B0xQCaez.js';
|
|
7
|
+
import '../types-C8nkPuD4.js';
|
|
8
|
+
import '../types-Cywfj8Mj.js';
|
|
9
|
+
import '../logging-Bl3HfcC8.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Slack Channel Adapter
|
|
13
|
+
*
|
|
14
|
+
* Creates a configured Bolt handler that bridges a `SlackTurnSource` to Slack
|
|
15
|
+
* via @slack/bolt.
|
|
16
|
+
*
|
|
17
|
+
* The adapter mounts message/event handlers on a Bolt `App` instance and
|
|
18
|
+
* processes each turn by:
|
|
19
|
+
* 1. Parsing the Slack event into a `SlackActivityInfo`.
|
|
20
|
+
* 2. Resolving a session ID via the configured session strategy.
|
|
21
|
+
* 3. Calling `source.chat()` with the user message.
|
|
22
|
+
* 4. Streaming the response back to Slack via progressive updates or a
|
|
23
|
+
* single final post.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { App } from "@slack/bolt";
|
|
28
|
+
* import { createSlackChannelAdapter } from "@cuylabs/channel-slack/adapter";
|
|
29
|
+
*
|
|
30
|
+
* const app = new App({ token: process.env.SLACK_BOT_TOKEN, signingSecret: process.env.SLACK_SIGNING_SECRET });
|
|
31
|
+
* const adapter = createSlackChannelAdapter({ source });
|
|
32
|
+
* adapter.mount(app);
|
|
33
|
+
* await app.start(3000);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
declare function createSlackChannelAdapter(options: SlackChannelOptions): SlackChannelAdapter;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Session mapping — Slack activity info to runtime session IDs.
|
|
41
|
+
*
|
|
42
|
+
* The default strategy (`"thread-aware"`) produces natural conversation
|
|
43
|
+
* groupings by using the thread timestamp when present and falling back to
|
|
44
|
+
* the channel ID for DMs and top-level messages.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
interface SlackSessionMap {
|
|
48
|
+
/** Resolve (or create) a session ID for the given Slack activity. */
|
|
49
|
+
resolve(info: SlackActivityInfo): string | Promise<string>;
|
|
50
|
+
}
|
|
51
|
+
declare function createSlackSessionMap(options: SlackChannelOptions): SlackSessionMap;
|
|
52
|
+
|
|
53
|
+
export { SlackChannelAdapter, SlackChannelOptions, type SlackSessionMap, createSlackChannelAdapter, createSlackSessionMap };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSlackChannelAdapter,
|
|
3
|
+
createSlackSessionMap
|
|
4
|
+
} from "../chunk-RTDLIYEE.js";
|
|
5
|
+
import "../chunk-IAQXQESO.js";
|
|
6
|
+
import "../chunk-37RN2YUI.js";
|
|
7
|
+
import "../chunk-3KP3CBCC.js";
|
|
8
|
+
import "../chunk-FPCE5V5Y.js";
|
|
9
|
+
import "../chunk-6WHFQUYQ.js";
|
|
10
|
+
export {
|
|
11
|
+
createSlackChannelAdapter,
|
|
12
|
+
createSlackSessionMap
|
|
13
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { App } from '@slack/bolt';
|
|
2
|
+
import { WebClient } from '@slack/web-api';
|
|
3
|
+
import { k as SlackTurnRequestContext, e as SlackAssistantUtilities, j as SlackTurnPreparation } from './turn-BGAXddH_.js';
|
|
4
|
+
import { C as CreateSlackAssistantBridgeOptions, d as SlackAssistantFeedbackConfig, S as SlackAssistantBridge } from './options-DQacQDmD.js';
|
|
5
|
+
import { L as Logger } from './logging-Bl3HfcC8.js';
|
|
6
|
+
import { o as SlackTurnSource } from './options-B0xQCaez.js';
|
|
7
|
+
import { a as SlackChannelOptions } from './types-wLZzyI9r.js';
|
|
8
|
+
import { SlackFeedbackHandler } from './feedback/index.js';
|
|
9
|
+
import { h as SlackInteractiveRequestHandler } from './types-Cywfj8Mj.js';
|
|
10
|
+
import './activity-ByrD9Ftr.js';
|
|
11
|
+
import './interactive-CbKYkkc_.js';
|
|
12
|
+
import './formatting-C-kwQseI.js';
|
|
13
|
+
import './types-C8nkPuD4.js';
|
|
14
|
+
import '@slack/types';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Shared installer for the direct Slack app surfaces.
|
|
18
|
+
*
|
|
19
|
+
* HTTP Events API and Socket Mode differ only in how Bolt receives inbound
|
|
20
|
+
* events. The Assistant pane, app_mention, DM/channel routing, feedback, and
|
|
21
|
+
* interactive request wiring are mounted here so both transports behave the
|
|
22
|
+
* same.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
interface MountSlackAppTurnRequestContext extends SlackTurnRequestContext {
|
|
26
|
+
/** Present only for Assistant-pane turns. */
|
|
27
|
+
assistant?: SlackAssistantUtilities;
|
|
28
|
+
/** Present for Assistant-pane turns; use direct history helpers for Slack API context. */
|
|
29
|
+
client?: WebClient;
|
|
30
|
+
/** Raw Bolt assistant args for advanced hosts. */
|
|
31
|
+
rawArgs?: unknown;
|
|
32
|
+
}
|
|
33
|
+
interface SlackAppSurfaceInteractiveController {
|
|
34
|
+
handleInteractiveRequest: SlackInteractiveRequestHandler;
|
|
35
|
+
install(app: App): void;
|
|
36
|
+
}
|
|
37
|
+
interface SlackAppSurfaceViewWorkflowController {
|
|
38
|
+
install(app: App): void;
|
|
39
|
+
}
|
|
40
|
+
interface SlackAppSurfaceOptions extends Omit<CreateSlackAssistantBridgeOptions, "feedback" | "source" | "prepareTurn" | "resolveSession" | "handleInteractiveRequest"> {
|
|
41
|
+
/** Source of Slack turns. */
|
|
42
|
+
source: SlackTurnSource;
|
|
43
|
+
/**
|
|
44
|
+
* Prepare a Slack turn for every direct Slack surface registered by this
|
|
45
|
+
* mount: Assistant pane, @mentions, and DMs.
|
|
46
|
+
*/
|
|
47
|
+
prepareTurn?: (request: MountSlackAppTurnRequestContext) => SlackTurnPreparation | Promise<SlackTurnPreparation>;
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the runtime session for every direct Slack surface. Returning
|
|
50
|
+
* `undefined` falls back to the configured session strategy.
|
|
51
|
+
*/
|
|
52
|
+
resolveSession?: (request: MountSlackAppTurnRequestContext) => string | undefined | Promise<string | undefined>;
|
|
53
|
+
/** Register `app.event("app_mention", ...)`. @default true */
|
|
54
|
+
respondToMentions?: boolean;
|
|
55
|
+
/** Register `app.message(...)` for DMs. @default true */
|
|
56
|
+
respondToMessages?: boolean;
|
|
57
|
+
/** Forward plain channel/group messages too. @default false */
|
|
58
|
+
respondToChannelMessages?: boolean;
|
|
59
|
+
/** Resolve or skip classic Slack channel-adapter messages. Return undefined to skip. */
|
|
60
|
+
resolveMessage?: SlackChannelOptions["resolveMessage"];
|
|
61
|
+
/** Feedback config. Pass `false` to omit feedback blocks. */
|
|
62
|
+
feedback?: SlackAssistantFeedbackConfig | false;
|
|
63
|
+
/** Convenience feedback handler. Ignored when `feedback` is set. */
|
|
64
|
+
onFeedback?: SlackFeedbackHandler;
|
|
65
|
+
/** Maximum turn runtime in ms. Set `0` to disable. @default 120_000 */
|
|
66
|
+
timeoutMs?: number;
|
|
67
|
+
/** Optional logger for diagnostics. */
|
|
68
|
+
logger?: Logger;
|
|
69
|
+
/**
|
|
70
|
+
* Slack-native approval/human-input controller. Pair this with a runtime
|
|
71
|
+
* that can pause on interactive request events.
|
|
72
|
+
*/
|
|
73
|
+
interactive?: SlackAppSurfaceInteractiveController;
|
|
74
|
+
/**
|
|
75
|
+
* Product/runtime Slack modal workflow controller. Use this for workflows that
|
|
76
|
+
* are richer than approval/human-input, such as incident triage forms or
|
|
77
|
+
* report-generation setup modals.
|
|
78
|
+
*/
|
|
79
|
+
viewWorkflows?: SlackAppSurfaceViewWorkflowController;
|
|
80
|
+
}
|
|
81
|
+
interface SlackAppSurfaceResult {
|
|
82
|
+
bridge: SlackAssistantBridge;
|
|
83
|
+
}
|
|
84
|
+
declare function installSlackAppSurface(boltApp: App, options: SlackAppSurfaceOptions): SlackAppSurfaceResult;
|
|
85
|
+
|
|
86
|
+
export { type MountSlackAppTurnRequestContext, type SlackAppSurfaceInteractiveController, type SlackAppSurfaceOptions, type SlackAppSurfaceResult, type SlackAppSurfaceViewWorkflowController, installSlackAppSurface };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
installSlackAppSurface
|
|
3
|
+
} from "./chunk-LFQCINHI.js";
|
|
4
|
+
import "./chunk-Q6YX7HHK.js";
|
|
5
|
+
import "./chunk-RHOIVQLD.js";
|
|
6
|
+
import "./chunk-IRFKUPJN.js";
|
|
7
|
+
import "./chunk-RTDLIYEE.js";
|
|
8
|
+
import "./chunk-IAQXQESO.js";
|
|
9
|
+
import "./chunk-37RN2YUI.js";
|
|
10
|
+
import "./chunk-3KP3CBCC.js";
|
|
11
|
+
import "./chunk-FPCE5V5Y.js";
|
|
12
|
+
import "./chunk-6WHFQUYQ.js";
|
|
13
|
+
export {
|
|
14
|
+
installSlackAppSurface
|
|
15
|
+
};
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Server } from 'node:http';
|
|
2
|
+
import { Application } from 'express';
|
|
3
|
+
import { App, ExpressReceiver } from '@slack/bolt';
|
|
4
|
+
import { CreateSlackBoltAppOptions } from './transports/http/index.js';
|
|
5
|
+
import { e as SlackDirectAuthOptions, d as SlackDirectAuthMode } from './types-B9NfCVrk.js';
|
|
6
|
+
import { SlackAppSurfaceOptions } from './app-surface.js';
|
|
7
|
+
export { MountSlackAppTurnRequestContext } from './app-surface.js';
|
|
8
|
+
import { S as SlackAssistantBridge } from './options-DQacQDmD.js';
|
|
9
|
+
import '@slack/web-api';
|
|
10
|
+
import './turn-BGAXddH_.js';
|
|
11
|
+
import './activity-ByrD9Ftr.js';
|
|
12
|
+
import './logging-Bl3HfcC8.js';
|
|
13
|
+
import './options-B0xQCaez.js';
|
|
14
|
+
import './types-C8nkPuD4.js';
|
|
15
|
+
import './types-Cywfj8Mj.js';
|
|
16
|
+
import './interactive-CbKYkkc_.js';
|
|
17
|
+
import './types-wLZzyI9r.js';
|
|
18
|
+
import './feedback/index.js';
|
|
19
|
+
import '@slack/types';
|
|
20
|
+
import './formatting-C-kwQseI.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Unified Slack app over the HTTP Events API.
|
|
24
|
+
*
|
|
25
|
+
* This file owns only the HTTP/Bolt receiver lifecycle. The actual Slack
|
|
26
|
+
* surfaces (Assistant pane, app mentions, DMs/channel messages, feedback, and
|
|
27
|
+
* interactive requests) are mounted by `installSlackAppSurface` so Socket
|
|
28
|
+
* Mode gets the exact same behavior.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
interface MountSlackAppOptions extends SlackAppSurfaceOptions, Omit<CreateSlackBoltAppOptions, "app" | "path" | "botToken" | "signingSecret" | "auth"> {
|
|
32
|
+
/** Slack bot token (`xoxb-...`). @default process.env.SLACK_BOT_TOKEN */
|
|
33
|
+
botToken?: string;
|
|
34
|
+
/** Slack signing secret. @default process.env.SLACK_SIGNING_SECRET */
|
|
35
|
+
signingSecret?: string;
|
|
36
|
+
/** Direct-mode auth config (single-workspace, OAuth, custom). */
|
|
37
|
+
auth?: SlackDirectAuthOptions;
|
|
38
|
+
/** Slack Events API callback path. @default "/slack/events" */
|
|
39
|
+
path?: string;
|
|
40
|
+
/** Port to listen on. @default process.env.PORT || 3000 */
|
|
41
|
+
port?: number | null;
|
|
42
|
+
/** Optional host for `app.listen(port, host)`. */
|
|
43
|
+
host?: string;
|
|
44
|
+
/** Pre-existing Express app. */
|
|
45
|
+
app?: Application;
|
|
46
|
+
}
|
|
47
|
+
interface MountSlackAppResult {
|
|
48
|
+
app: Application;
|
|
49
|
+
boltApp: App;
|
|
50
|
+
receiver: ExpressReceiver;
|
|
51
|
+
authMode: SlackDirectAuthMode;
|
|
52
|
+
routePath: string;
|
|
53
|
+
bridge: SlackAssistantBridge;
|
|
54
|
+
server?: Server;
|
|
55
|
+
}
|
|
56
|
+
declare function mountSlackApp(options: MountSlackAppOptions): Promise<MountSlackAppResult>;
|
|
57
|
+
|
|
58
|
+
export { type MountSlackAppOptions, type MountSlackAppResult, mountSlackApp };
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSlackBoltApp
|
|
3
|
+
} from "./chunk-QJYCHWN6.js";
|
|
4
|
+
import "./chunk-S3SWPYXJ.js";
|
|
5
|
+
import {
|
|
6
|
+
installSlackAppSurface
|
|
7
|
+
} from "./chunk-LFQCINHI.js";
|
|
8
|
+
import "./chunk-Q6YX7HHK.js";
|
|
9
|
+
import "./chunk-RHOIVQLD.js";
|
|
10
|
+
import "./chunk-IRFKUPJN.js";
|
|
11
|
+
import "./chunk-RTDLIYEE.js";
|
|
12
|
+
import "./chunk-IAQXQESO.js";
|
|
13
|
+
import "./chunk-37RN2YUI.js";
|
|
14
|
+
import "./chunk-3KP3CBCC.js";
|
|
15
|
+
import "./chunk-FPCE5V5Y.js";
|
|
16
|
+
import "./chunk-6WHFQUYQ.js";
|
|
17
|
+
|
|
18
|
+
// src/app.ts
|
|
19
|
+
async function mountSlackApp(options) {
|
|
20
|
+
const {
|
|
21
|
+
botToken,
|
|
22
|
+
signingSecret,
|
|
23
|
+
auth,
|
|
24
|
+
path,
|
|
25
|
+
processBeforeResponse,
|
|
26
|
+
signatureVerification,
|
|
27
|
+
boltAppOptions,
|
|
28
|
+
receiverOptions,
|
|
29
|
+
port: portOption,
|
|
30
|
+
host,
|
|
31
|
+
app: providedApp,
|
|
32
|
+
...surfaceOptions
|
|
33
|
+
} = options;
|
|
34
|
+
const {
|
|
35
|
+
boltApp,
|
|
36
|
+
receiver,
|
|
37
|
+
app: expressApp,
|
|
38
|
+
authMode,
|
|
39
|
+
routePath
|
|
40
|
+
} = await createSlackBoltApp({
|
|
41
|
+
signingSecret,
|
|
42
|
+
path,
|
|
43
|
+
botToken,
|
|
44
|
+
auth,
|
|
45
|
+
app: providedApp,
|
|
46
|
+
processBeforeResponse,
|
|
47
|
+
signatureVerification,
|
|
48
|
+
boltAppOptions,
|
|
49
|
+
receiverOptions
|
|
50
|
+
});
|
|
51
|
+
const { bridge } = installSlackAppSurface(boltApp, surfaceOptions);
|
|
52
|
+
expressApp.use(
|
|
53
|
+
receiver.router
|
|
54
|
+
);
|
|
55
|
+
const port = portOption === void 0 ? resolvePort(process.env.PORT) : portOption;
|
|
56
|
+
let server;
|
|
57
|
+
if (!providedApp && port !== null) {
|
|
58
|
+
const onListen = () => {
|
|
59
|
+
process.stdout.write(
|
|
60
|
+
`Slack app listening on port ${port} at ${routePath}
|
|
61
|
+
`
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
server = host ? expressApp.listen(port, host, onListen) : expressApp.listen(port, onListen);
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
app: expressApp,
|
|
68
|
+
boltApp,
|
|
69
|
+
receiver,
|
|
70
|
+
authMode,
|
|
71
|
+
routePath,
|
|
72
|
+
bridge,
|
|
73
|
+
...server ? { server } : {}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function resolvePort(port) {
|
|
77
|
+
if (!port) return 3e3;
|
|
78
|
+
const parsed = Number(port);
|
|
79
|
+
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
80
|
+
throw new Error(`Invalid PORT value: ${port}`);
|
|
81
|
+
}
|
|
82
|
+
return parsed;
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
mountSlackApp
|
|
86
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SlackArtifact, l as SlackLinkArtifact, P as PublishSlackArtifactOptions, g as SlackArtifactPublication, i as SlackCanvasArtifact, j as SlackFileArtifact, k as SlackImageArtifact, m as SlackTextArtifact } from '../types-C8nkPuD4.js';
|
|
2
|
-
export { a as SlackArtifactBase, b as SlackArtifactBinaryData, c as SlackArtifactCanvasResponse,
|
|
1
|
+
import { S as SlackArtifact, l as SlackLinkArtifact, P as PublishSlackArtifactOptions, g as SlackArtifactPublication, i as SlackCanvasArtifact, j as SlackFileArtifact, k as SlackImageArtifact, m as SlackTextArtifact, d as SlackArtifactClient } from '../types-C8nkPuD4.js';
|
|
2
|
+
export { a as SlackArtifactBase, b as SlackArtifactBinaryData, c as SlackArtifactCanvasResponse, e as SlackArtifactFileUploadResponse, f as SlackArtifactPostMessageResponse, h as SlackArtifactPublishMethod } from '../types-C8nkPuD4.js';
|
|
3
3
|
|
|
4
4
|
interface SlackArtifactBlockKitMessage {
|
|
5
5
|
text: string;
|
|
@@ -25,4 +25,58 @@ declare function publishSlackCanvasArtifact(options: PublishSlackArtifactOptions
|
|
|
25
25
|
artifact: SlackCanvasArtifact;
|
|
26
26
|
}): Promise<SlackArtifactPublication>;
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
interface SlackFinalResponseArtifactContext {
|
|
29
|
+
text: string;
|
|
30
|
+
formattedText: string;
|
|
31
|
+
client: SlackArtifactClient;
|
|
32
|
+
channelId: string;
|
|
33
|
+
threadTs?: string;
|
|
34
|
+
}
|
|
35
|
+
interface SlackFinalResponseArtifactResult {
|
|
36
|
+
publication: SlackArtifactPublication;
|
|
37
|
+
}
|
|
38
|
+
type SlackFinalResponseArtifactDeliveryMode = "supplemental" | "replace";
|
|
39
|
+
type SlackFinalResponseArtifactPublisher = (context: SlackFinalResponseArtifactContext) => Promise<SlackFinalResponseArtifactResult | undefined>;
|
|
40
|
+
type SlackFinalResponseArtifactValueResolver<T> = T | ((context: SlackFinalResponseArtifactContext) => T | Promise<T>);
|
|
41
|
+
interface CreateSlackFinalResponseArtifactPublisherOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Minimum raw-response characters required before publishing an artifact.
|
|
44
|
+
*
|
|
45
|
+
* @default 4000
|
|
46
|
+
*/
|
|
47
|
+
minCharacters?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Canvas/file title.
|
|
50
|
+
*
|
|
51
|
+
* @default "Agent response"
|
|
52
|
+
*/
|
|
53
|
+
title?: SlackFinalResponseArtifactValueResolver<string | undefined>;
|
|
54
|
+
/**
|
|
55
|
+
* Optional Slack artifact summary.
|
|
56
|
+
*/
|
|
57
|
+
summary?: SlackFinalResponseArtifactValueResolver<string | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* Prefer creating a channel canvas when the Slack client exposes
|
|
60
|
+
* `conversations.canvases.create`.
|
|
61
|
+
*
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
channelCanvas?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Fallback when Canvas publication fails.
|
|
67
|
+
*
|
|
68
|
+
* @default "file"
|
|
69
|
+
*/
|
|
70
|
+
fallback?: "file" | "none";
|
|
71
|
+
/**
|
|
72
|
+
* Called after a Canvas or fallback file is published.
|
|
73
|
+
*/
|
|
74
|
+
onPublished?: (result: SlackFinalResponseArtifactResult, context: SlackFinalResponseArtifactContext) => void | Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Called when Canvas publication fails and no fallback publication succeeds.
|
|
77
|
+
*/
|
|
78
|
+
onError?: (error: unknown, context: SlackFinalResponseArtifactContext) => void | Promise<void>;
|
|
79
|
+
}
|
|
80
|
+
declare function createSlackFinalResponseArtifactPublisher({ minCharacters, title, summary, channelCanvas, fallback, onPublished, onError, }?: CreateSlackFinalResponseArtifactPublisherOptions): SlackFinalResponseArtifactPublisher;
|
|
81
|
+
|
|
82
|
+
export { type CreateSlackFinalResponseArtifactPublisherOptions, PublishSlackArtifactOptions, SlackArtifact, type SlackArtifactBlockKitMessage, SlackArtifactClient, SlackArtifactPublication, SlackCanvasArtifact, SlackFileArtifact, type SlackFinalResponseArtifactContext, type SlackFinalResponseArtifactDeliveryMode, type SlackFinalResponseArtifactPublisher, type SlackFinalResponseArtifactResult, type SlackFinalResponseArtifactValueResolver, SlackImageArtifact, SlackLinkArtifact, SlackTextArtifact, createSlackArtifactBlocks, createSlackFinalResponseArtifactPublisher, createSlackLinkArtifactBlocks, publishSlackArtifact, publishSlackCanvasArtifact, publishSlackFileArtifact, publishSlackImageArtifact, publishSlackLinkArtifact, publishSlackTextArtifact };
|
package/dist/artifacts/index.js
CHANGED
|
@@ -287,8 +287,96 @@ function readUploadedFileId(response) {
|
|
|
287
287
|
function readString(value) {
|
|
288
288
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
289
289
|
}
|
|
290
|
+
|
|
291
|
+
// src/artifacts/final-response.ts
|
|
292
|
+
var DEFAULT_MIN_CHARACTERS = 4e3;
|
|
293
|
+
var DEFAULT_TITLE = "Agent response";
|
|
294
|
+
function createSlackFinalResponseArtifactPublisher({
|
|
295
|
+
minCharacters = DEFAULT_MIN_CHARACTERS,
|
|
296
|
+
title = DEFAULT_TITLE,
|
|
297
|
+
summary,
|
|
298
|
+
channelCanvas = true,
|
|
299
|
+
fallback = "file",
|
|
300
|
+
onPublished,
|
|
301
|
+
onError
|
|
302
|
+
} = {}) {
|
|
303
|
+
const configuredThreshold = Math.floor(minCharacters);
|
|
304
|
+
const threshold = Number.isFinite(configuredThreshold) && configuredThreshold > 0 ? configuredThreshold : DEFAULT_MIN_CHARACTERS;
|
|
305
|
+
return async (context) => {
|
|
306
|
+
const text = context.text.trim();
|
|
307
|
+
if (text.length < threshold) {
|
|
308
|
+
return void 0;
|
|
309
|
+
}
|
|
310
|
+
const resolvedTitle = normalizeText2(await resolveValue(title, context)) ?? DEFAULT_TITLE;
|
|
311
|
+
const resolvedSummary = normalizeText2(await resolveValue(summary, context));
|
|
312
|
+
let lastError;
|
|
313
|
+
try {
|
|
314
|
+
const publication = await publishSlackCanvasArtifact({
|
|
315
|
+
client: context.client,
|
|
316
|
+
channelId: context.channelId,
|
|
317
|
+
...context.threadTs ? { threadTs: context.threadTs } : {},
|
|
318
|
+
artifact: {
|
|
319
|
+
kind: "canvas",
|
|
320
|
+
title: resolvedTitle,
|
|
321
|
+
markdown: text,
|
|
322
|
+
channelCanvas,
|
|
323
|
+
...resolvedSummary ? { summary: resolvedSummary } : {},
|
|
324
|
+
metadata: {
|
|
325
|
+
source: "slack-final-response",
|
|
326
|
+
characterCount: text.length
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
const result = { publication };
|
|
331
|
+
await onPublished?.(result, context);
|
|
332
|
+
return result;
|
|
333
|
+
} catch (error) {
|
|
334
|
+
lastError = error;
|
|
335
|
+
}
|
|
336
|
+
if (fallback === "file") {
|
|
337
|
+
try {
|
|
338
|
+
const publication = await publishSlackTextArtifact({
|
|
339
|
+
client: context.client,
|
|
340
|
+
channelId: context.channelId,
|
|
341
|
+
...context.threadTs ? { threadTs: context.threadTs } : {},
|
|
342
|
+
artifact: {
|
|
343
|
+
kind: "text",
|
|
344
|
+
title: resolvedTitle,
|
|
345
|
+
text,
|
|
346
|
+
filename: filenameFromTitle2(resolvedTitle),
|
|
347
|
+
...resolvedSummary ? { summary: resolvedSummary } : {},
|
|
348
|
+
metadata: {
|
|
349
|
+
source: "slack-final-response",
|
|
350
|
+
characterCount: text.length,
|
|
351
|
+
canvasFallback: true
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
const result = { publication };
|
|
356
|
+
await onPublished?.(result, context);
|
|
357
|
+
return result;
|
|
358
|
+
} catch (error) {
|
|
359
|
+
lastError = error;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
await onError?.(lastError, context);
|
|
363
|
+
return void 0;
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
async function resolveValue(value, context) {
|
|
367
|
+
return typeof value === "function" ? await value(context) : value;
|
|
368
|
+
}
|
|
369
|
+
function normalizeText2(value) {
|
|
370
|
+
const trimmed = value?.trim();
|
|
371
|
+
return trimmed ? trimmed : void 0;
|
|
372
|
+
}
|
|
373
|
+
function filenameFromTitle2(title) {
|
|
374
|
+
const slug = title.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
375
|
+
return `${slug || "agent-response"}.txt`;
|
|
376
|
+
}
|
|
290
377
|
export {
|
|
291
378
|
createSlackArtifactBlocks,
|
|
379
|
+
createSlackFinalResponseArtifactPublisher,
|
|
292
380
|
createSlackLinkArtifactBlocks,
|
|
293
381
|
publishSlackArtifact,
|
|
294
382
|
publishSlackCanvasArtifact,
|
|
@@ -1,58 +1,23 @@
|
|
|
1
|
-
import { S as
|
|
1
|
+
import { C as CreateSlackAssistantBridgeOptions, S as SlackAssistantBridge } from '../options-DQacQDmD.js';
|
|
2
|
+
export { A as AssistantLifecycleArgs, a as AssistantThreadStartedArgs, M as MaybePromise, P as ParsedAssistantUserMessage, b as SlackAssistantCancelControlOptions, c as SlackAssistantCancelControlVisibleWhen, d as SlackAssistantFeedbackConfig, e as SlackAssistantSessionStrategy, f as SlackAssistantStatusContext, g as SlackAssistantThreadContextStoreLike, h as SlackAssistantThreadStartedContext, i as SlackAssistantTurnCancelContext, j as SlackAssistantTurnControlsOptions, k as SlackAssistantTurnPreparation, l as SlackAssistantUserMessageContext, m as createSlackAssistantThreadContextStore, p as parseSlackMessageActivityFromMessageEvent, r as resolveAssistantSessionId } from '../options-DQacQDmD.js';
|
|
3
|
+
import '@slack/bolt';
|
|
4
|
+
import '@slack/web-api';
|
|
5
|
+
import '../turn-BGAXddH_.js';
|
|
6
|
+
import '../activity-ByrD9Ftr.js';
|
|
7
|
+
import '../interactive-CbKYkkc_.js';
|
|
8
|
+
import '../formatting-C-kwQseI.js';
|
|
9
|
+
import '../options-B0xQCaez.js';
|
|
10
|
+
import '../types-C8nkPuD4.js';
|
|
11
|
+
import '../types-Cywfj8Mj.js';
|
|
12
|
+
import '../feedback/index.js';
|
|
13
|
+
import '@slack/types';
|
|
14
|
+
import '../logging-Bl3HfcC8.js';
|
|
2
15
|
|
|
3
16
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Bolt's default store persists context in message metadata, but also keeps a
|
|
7
|
-
* single process-local cached context. That cache is not keyed by thread, so a
|
|
8
|
-
* multi-user app can read the wrong channel-of-origin context after another
|
|
9
|
-
* assistant thread changes it. This store keeps the same metadata persistence
|
|
10
|
-
* model while caching by Slack channel/thread.
|
|
17
|
+
* `createSlackAssistantBridge` factory — assembles the three lifecycle
|
|
18
|
+
* middlewares into a Bolt `Assistant` and wires the feedback action handler.
|
|
11
19
|
*/
|
|
12
|
-
type ThreadStoreArgs = {
|
|
13
|
-
context?: {
|
|
14
|
-
botUserId?: string;
|
|
15
|
-
};
|
|
16
|
-
client?: {
|
|
17
|
-
conversations?: {
|
|
18
|
-
replies?: (args: Record<string, unknown>) => Promise<{
|
|
19
|
-
messages?: unknown[];
|
|
20
|
-
}>;
|
|
21
|
-
};
|
|
22
|
-
chat?: {
|
|
23
|
-
update?: (args: Record<string, unknown>) => Promise<unknown>;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
logger?: {
|
|
27
|
-
debug?: (...args: unknown[]) => void;
|
|
28
|
-
};
|
|
29
|
-
payload?: unknown;
|
|
30
|
-
};
|
|
31
|
-
interface SlackAssistantThreadContextStoreLike {
|
|
32
|
-
get: (args: ThreadStoreArgs) => Promise<unknown>;
|
|
33
|
-
save: (args: ThreadStoreArgs) => Promise<void>;
|
|
34
|
-
}
|
|
35
|
-
declare function createSlackAssistantThreadContextStore(): SlackAssistantThreadContextStoreLike;
|
|
36
20
|
|
|
37
|
-
|
|
38
|
-
* Parse the `message` payload delivered to a Bolt assistant `userMessage`
|
|
39
|
-
* handler into the same shape as `parseSlackMessageActivity`.
|
|
40
|
-
*
|
|
41
|
-
* Bolt routes a fairly wide message event to assistant handlers, so we keep
|
|
42
|
-
* the input typed loosely and inspect only the fields we need.
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
interface ParsedAssistantUserMessage extends SlackActivityInfo {
|
|
46
|
-
/** Slack `channel` identifier, always present after parsing. */
|
|
47
|
-
channel: string;
|
|
48
|
-
/** Slack `thread_ts` identifier — the assistant API requires a thread. */
|
|
49
|
-
threadTs: string;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Returns `undefined` when the event is not a parseable user message — bolt
|
|
53
|
-
* delivers join/leave/edit/delete subtypes through the same handler, and the
|
|
54
|
-
* caller should ignore them.
|
|
55
|
-
*/
|
|
56
|
-
declare function parseSlackMessageActivityFromMessageEvent(message: unknown): ParsedAssistantUserMessage | undefined;
|
|
21
|
+
declare function createSlackAssistantBridge(options: CreateSlackAssistantBridgeOptions): SlackAssistantBridge;
|
|
57
22
|
|
|
58
|
-
export {
|
|
23
|
+
export { CreateSlackAssistantBridgeOptions, SlackAssistantBridge, createSlackAssistantBridge };
|