@cuylabs/channel-slack 0.8.0 → 0.10.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 +3 -2
- package/dist/artifacts/index.d.ts +3 -110
- package/dist/chunk-IAQXQESO.js +1008 -0
- package/dist/core.d.ts +2 -40
- package/dist/index.d.ts +6 -1
- package/dist/index.js +8 -0
- package/dist/interactive/index.d.ts +67 -0
- package/dist/interactive/index.js +650 -0
- package/dist/interactive-CbKYkkc_.d.ts +46 -0
- package/dist/responses/index.d.ts +74 -0
- package/dist/responses/index.js +0 -0
- package/dist/runtime/index.d.ts +260 -0
- package/dist/runtime/index.js +10 -0
- package/dist/types-C8nkPuD4.d.ts +111 -0
- package/dist/types-Cywfj8Mj.d.ts +91 -0
- package/docs/reference/channel-slack-boundary.md +5 -2
- package/docs/reference/exports.md +2 -0
- package/package.json +18 -3
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { d as SlackArtifactClient } from '../types-C8nkPuD4.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Slack response-sink contracts consumed by the event bridge.
|
|
5
|
+
*
|
|
6
|
+
* The adapter constructs a `SlackResponseSink` from the Bolt `say` function
|
|
7
|
+
* and `WebClient` instance available in each handler. Keeping the sink
|
|
8
|
+
* interface separate makes the bridge testable without a live Slack
|
|
9
|
+
* connection.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
type SlackStreamTaskStatus = "pending" | "in_progress" | "complete" | "error";
|
|
13
|
+
type SlackStreamChunk = {
|
|
14
|
+
type: "markdown_text";
|
|
15
|
+
text: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: "plan_update";
|
|
18
|
+
title: string;
|
|
19
|
+
} | {
|
|
20
|
+
type: "task_update";
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
status: SlackStreamTaskStatus;
|
|
24
|
+
details?: string;
|
|
25
|
+
output?: string;
|
|
26
|
+
};
|
|
27
|
+
interface SlackChatStream {
|
|
28
|
+
append(args: {
|
|
29
|
+
markdown_text?: string;
|
|
30
|
+
chunks?: SlackStreamChunk[];
|
|
31
|
+
}): Promise<unknown>;
|
|
32
|
+
stop(args?: {
|
|
33
|
+
markdown_text?: string;
|
|
34
|
+
chunks?: SlackStreamChunk[];
|
|
35
|
+
}): Promise<unknown>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Minimal Slack posting interface consumed by the event bridge.
|
|
39
|
+
*/
|
|
40
|
+
interface SlackArtifactPublicationTarget {
|
|
41
|
+
channelId: string;
|
|
42
|
+
threadTs?: string;
|
|
43
|
+
}
|
|
44
|
+
interface SlackResponseSink {
|
|
45
|
+
/**
|
|
46
|
+
* Slack Web API surface used by optional artifact publishers.
|
|
47
|
+
*/
|
|
48
|
+
artifactClient?: SlackArtifactClient;
|
|
49
|
+
/**
|
|
50
|
+
* Channel/thread target used by optional artifact publishers.
|
|
51
|
+
*/
|
|
52
|
+
artifactTarget?: SlackArtifactPublicationTarget;
|
|
53
|
+
/**
|
|
54
|
+
* Post a new message to the channel / thread.
|
|
55
|
+
* Returns the channel ID and message timestamp needed for updates.
|
|
56
|
+
*/
|
|
57
|
+
postMessage(text: string): Promise<{
|
|
58
|
+
channel: string;
|
|
59
|
+
ts: string;
|
|
60
|
+
}>;
|
|
61
|
+
/**
|
|
62
|
+
* Update an existing message by channel + ts.
|
|
63
|
+
*/
|
|
64
|
+
updateMessage(channel: string, ts: string, text: string): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Create a native Slack chat stream. Required when `streamingMode` is
|
|
67
|
+
* `"chat-stream"`.
|
|
68
|
+
*/
|
|
69
|
+
createChatStream?(options: {
|
|
70
|
+
bufferSize: number;
|
|
71
|
+
}): SlackChatStream;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export type { SlackArtifactPublicationTarget, SlackChatStream, SlackResponseSink, SlackStreamChunk, SlackStreamTaskStatus };
|
|
File without changes
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { d as SlackArtifactClient, g as SlackArtifactPublication } from '../types-C8nkPuD4.js';
|
|
2
|
+
import { c as SlackInteractiveApprovalRequest, e as SlackInteractiveHumanInputRequest } from '../types-Cywfj8Mj.js';
|
|
3
|
+
import { a as SlackEventInteractiveRequestHandler } from '../interactive-CbKYkkc_.js';
|
|
4
|
+
import { SlackResponseSink } from '../responses/index.js';
|
|
5
|
+
import '../activity-ByrD9Ftr.js';
|
|
6
|
+
|
|
7
|
+
interface SlackTurnSourceChatOptions {
|
|
8
|
+
abort?: AbortSignal;
|
|
9
|
+
system?: string;
|
|
10
|
+
}
|
|
11
|
+
interface SlackTurnSource {
|
|
12
|
+
chat(sessionId: string, message: string, options?: SlackTurnSourceChatOptions): AsyncGenerator<SlackTurnEvent>;
|
|
13
|
+
}
|
|
14
|
+
interface SlackFinalResponseArtifactContext {
|
|
15
|
+
text: string;
|
|
16
|
+
formattedText: string;
|
|
17
|
+
client: SlackArtifactClient;
|
|
18
|
+
channelId: string;
|
|
19
|
+
threadTs?: string;
|
|
20
|
+
}
|
|
21
|
+
interface SlackFinalResponseArtifactResult {
|
|
22
|
+
publication: SlackArtifactPublication;
|
|
23
|
+
}
|
|
24
|
+
type SlackFinalResponseArtifactDeliveryMode = "supplemental" | "replace";
|
|
25
|
+
type SlackFinalResponseArtifactPublisher = (context: SlackFinalResponseArtifactContext) => Promise<SlackFinalResponseArtifactResult | undefined>;
|
|
26
|
+
type SlackTurnStatus = "thinking" | "reasoning" | "calling-tool" | "waiting-approval" | "waiting-input" | "processing" | "error" | string;
|
|
27
|
+
interface SlackTurnEventBase {
|
|
28
|
+
type: string;
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
interface SlackTurnTextStartEvent extends SlackTurnEventBase {
|
|
32
|
+
type: "text-start";
|
|
33
|
+
}
|
|
34
|
+
interface SlackTurnTextDeltaEvent extends SlackTurnEventBase {
|
|
35
|
+
type: "text-delta";
|
|
36
|
+
text: string;
|
|
37
|
+
}
|
|
38
|
+
interface SlackTurnTextEndEvent extends SlackTurnEventBase {
|
|
39
|
+
type: "text-end";
|
|
40
|
+
}
|
|
41
|
+
interface SlackTurnReasoningStartEvent extends SlackTurnEventBase {
|
|
42
|
+
type: "reasoning-start";
|
|
43
|
+
}
|
|
44
|
+
interface SlackTurnReasoningEndEvent extends SlackTurnEventBase {
|
|
45
|
+
type: "reasoning-end";
|
|
46
|
+
}
|
|
47
|
+
interface SlackTurnToolStartEvent extends SlackTurnEventBase {
|
|
48
|
+
type: "tool-start";
|
|
49
|
+
toolCallId: string;
|
|
50
|
+
toolName: string;
|
|
51
|
+
input?: unknown;
|
|
52
|
+
}
|
|
53
|
+
interface SlackTurnToolResultEvent extends SlackTurnEventBase {
|
|
54
|
+
type: "tool-result";
|
|
55
|
+
toolCallId: string;
|
|
56
|
+
toolName: string;
|
|
57
|
+
result?: unknown;
|
|
58
|
+
}
|
|
59
|
+
interface SlackTurnToolErrorEvent extends SlackTurnEventBase {
|
|
60
|
+
type: "tool-error";
|
|
61
|
+
toolCallId: string;
|
|
62
|
+
toolName: string;
|
|
63
|
+
error: string;
|
|
64
|
+
}
|
|
65
|
+
interface SlackTurnSubagentEventBase extends SlackTurnEventBase {
|
|
66
|
+
dispatchId: string;
|
|
67
|
+
role: string;
|
|
68
|
+
title?: string;
|
|
69
|
+
parentDispatchId?: string;
|
|
70
|
+
agentPath?: string;
|
|
71
|
+
depth?: number;
|
|
72
|
+
}
|
|
73
|
+
interface SlackTurnSubagentStartEvent extends SlackTurnSubagentEventBase {
|
|
74
|
+
type: "subagent-start";
|
|
75
|
+
}
|
|
76
|
+
interface SlackTurnSubagentEventEvent extends SlackTurnSubagentEventBase {
|
|
77
|
+
type: "subagent-event";
|
|
78
|
+
event: SlackTurnEvent;
|
|
79
|
+
}
|
|
80
|
+
interface SlackTurnSubagentCompleteEvent extends SlackTurnSubagentEventBase {
|
|
81
|
+
type: "subagent-complete";
|
|
82
|
+
output?: unknown;
|
|
83
|
+
}
|
|
84
|
+
interface SlackTurnSubagentErrorEvent extends SlackTurnSubagentEventBase {
|
|
85
|
+
type: "subagent-error";
|
|
86
|
+
error: string;
|
|
87
|
+
}
|
|
88
|
+
interface SlackTurnStatusEvent extends SlackTurnEventBase {
|
|
89
|
+
type: "status";
|
|
90
|
+
status: SlackTurnStatus;
|
|
91
|
+
}
|
|
92
|
+
interface SlackTurnCompleteEvent extends SlackTurnEventBase {
|
|
93
|
+
type: "complete";
|
|
94
|
+
output?: string;
|
|
95
|
+
}
|
|
96
|
+
interface SlackTurnErrorEvent extends SlackTurnEventBase {
|
|
97
|
+
type: "error";
|
|
98
|
+
error: unknown;
|
|
99
|
+
}
|
|
100
|
+
interface SlackTurnApprovalRequestEvent extends SlackTurnEventBase {
|
|
101
|
+
type: "approval-request";
|
|
102
|
+
request: SlackInteractiveApprovalRequest;
|
|
103
|
+
}
|
|
104
|
+
interface SlackTurnApprovalResolvedEvent extends SlackTurnEventBase {
|
|
105
|
+
type: "approval-resolved";
|
|
106
|
+
}
|
|
107
|
+
interface SlackTurnHumanInputRequestEvent extends SlackTurnEventBase {
|
|
108
|
+
type: "human-input-request";
|
|
109
|
+
request: SlackInteractiveHumanInputRequest;
|
|
110
|
+
}
|
|
111
|
+
interface SlackTurnHumanInputResolvedEvent extends SlackTurnEventBase {
|
|
112
|
+
type: "human-input-resolved";
|
|
113
|
+
}
|
|
114
|
+
type SlackTurnEvent = SlackTurnTextStartEvent | SlackTurnTextDeltaEvent | SlackTurnTextEndEvent | SlackTurnReasoningStartEvent | SlackTurnReasoningEndEvent | SlackTurnToolStartEvent | SlackTurnToolResultEvent | SlackTurnToolErrorEvent | SlackTurnSubagentStartEvent | SlackTurnSubagentEventEvent | SlackTurnSubagentCompleteEvent | SlackTurnSubagentErrorEvent | SlackTurnStatusEvent | SlackTurnCompleteEvent | SlackTurnErrorEvent | SlackTurnApprovalRequestEvent | SlackTurnApprovalResolvedEvent | SlackTurnHumanInputRequestEvent | SlackTurnHumanInputResolvedEvent;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Event-bridge configuration. The bridge is mode-aware (progressive,
|
|
118
|
+
* accumulate, chat-stream) and these options control formatting, status
|
|
119
|
+
* propagation, interactive-request handling, and chat-stream finalization.
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
type ApprovalRequest = SlackTurnApprovalRequestEvent["request"];
|
|
123
|
+
type HumanInputRequest = SlackTurnHumanInputRequestEvent["request"];
|
|
124
|
+
interface SlackEventBridgeOptions {
|
|
125
|
+
showReasoning: boolean;
|
|
126
|
+
/** Render root-agent tool rows/status updates. */
|
|
127
|
+
showToolUsage: boolean;
|
|
128
|
+
/** Render subagent child tool rows in the parent Slack task timeline. */
|
|
129
|
+
showSubagentToolUsage: boolean;
|
|
130
|
+
/** Include full subagent completion output in the subagent task row. */
|
|
131
|
+
showSubagentResultInTask: boolean;
|
|
132
|
+
formatToolTitle?: (toolName: string) => string;
|
|
133
|
+
formatToolUpdate: (toolName: string) => string;
|
|
134
|
+
formatToolDetails?: (event: SlackTurnToolStartEvent) => string | undefined;
|
|
135
|
+
/**
|
|
136
|
+
* Format the completed tool output shown in Slack task rows.
|
|
137
|
+
*
|
|
138
|
+
* Return `undefined` to use the default generic formatter. Return `null` to
|
|
139
|
+
* intentionally omit task-row output for this tool result.
|
|
140
|
+
*/
|
|
141
|
+
formatToolResultOutput?: (event: SlackTurnToolResultEvent) => string | null | undefined;
|
|
142
|
+
formatToolError: (toolName: string, error: string) => string;
|
|
143
|
+
formatReasoningUpdate: () => string;
|
|
144
|
+
formatMessageText: (text: string) => string;
|
|
145
|
+
streamingMode: "progressive" | "accumulate" | "chat-stream";
|
|
146
|
+
progressiveUpdateThreshold: number;
|
|
147
|
+
progressiveUpdateIntervalMs: number;
|
|
148
|
+
chatStreamBufferSize: number;
|
|
149
|
+
/**
|
|
150
|
+
* Maximum number of Slack task-update chunks the bridge will append to a
|
|
151
|
+
* single chat stream. Task rows are a bounded UI projection, not a durable
|
|
152
|
+
* event log.
|
|
153
|
+
*/
|
|
154
|
+
maxTaskUpdates: number;
|
|
155
|
+
/**
|
|
156
|
+
* Maximum cumulative characters from task titles/details/output that the
|
|
157
|
+
* bridge will append to one chat stream.
|
|
158
|
+
*/
|
|
159
|
+
maxTaskUpdateTextChars: number;
|
|
160
|
+
/**
|
|
161
|
+
* Maximum characters for a single task details/output field.
|
|
162
|
+
*/
|
|
163
|
+
maxTaskUpdateFieldChars: number;
|
|
164
|
+
interactiveMode: "message-and-error" | "ignore";
|
|
165
|
+
handleInteractiveRequest?: SlackEventInteractiveRequestHandler;
|
|
166
|
+
formatApprovalRequired: (request: ApprovalRequest) => string;
|
|
167
|
+
formatHumanInputRequired: (request: HumanInputRequest) => string;
|
|
168
|
+
/**
|
|
169
|
+
* Optional hook called whenever the bridge's status label changes — used by
|
|
170
|
+
* the assistant bridge to update the assistant pane's status line via
|
|
171
|
+
* `assistant.threads.setStatus`. Errors are swallowed by the caller.
|
|
172
|
+
*/
|
|
173
|
+
onStatusChange?: (label: string, event: SlackTurnEvent | undefined) => void | Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* Optional final-args passthrough for `chatStream.stop(...)`. When the
|
|
176
|
+
* bridge stops the chat stream on `complete`, these args (e.g. final
|
|
177
|
+
* `blocks` for a feedback widget) are merged into the `stop` call. The
|
|
178
|
+
* existing `markdown_text` final-text fallback always wins on text fields.
|
|
179
|
+
*/
|
|
180
|
+
chatStreamFinalArgs?: {
|
|
181
|
+
blocks?: unknown[];
|
|
182
|
+
} & Record<string, unknown>;
|
|
183
|
+
/**
|
|
184
|
+
* Optional post-processing hook for publishing a rich artifact from the final
|
|
185
|
+
* accumulated response, such as a Slack Canvas for long answers.
|
|
186
|
+
*/
|
|
187
|
+
publishFinalResponseArtifact?: SlackFinalResponseArtifactPublisher;
|
|
188
|
+
/**
|
|
189
|
+
* Controls whether artifact publication is additive or becomes the primary
|
|
190
|
+
* final-answer surface.
|
|
191
|
+
*
|
|
192
|
+
* - `supplemental`: finalize the Slack text normally, then publish artifact.
|
|
193
|
+
* - `replace`: publish artifact first and use a compact Slack final message.
|
|
194
|
+
*
|
|
195
|
+
* @default "supplemental"
|
|
196
|
+
*/
|
|
197
|
+
finalResponseArtifactMode?: SlackFinalResponseArtifactDeliveryMode;
|
|
198
|
+
/**
|
|
199
|
+
* When replacement mode is active, continue streaming text up to this many
|
|
200
|
+
* raw characters, then suppress further text deltas and publish the full
|
|
201
|
+
* answer as an artifact at completion. This preserves normal short-answer
|
|
202
|
+
* streaming without flooding Slack for long answers.
|
|
203
|
+
*
|
|
204
|
+
* @default 4000
|
|
205
|
+
*/
|
|
206
|
+
finalResponseArtifactStreamThreshold?: number;
|
|
207
|
+
/**
|
|
208
|
+
* Notice appended when replacement mode suppresses the remaining text stream.
|
|
209
|
+
*/
|
|
210
|
+
formatFinalResponseArtifactContinuationNotice?: (context: Pick<SlackFinalResponseArtifactContext, "text" | "formattedText">) => string;
|
|
211
|
+
/**
|
|
212
|
+
* Final compact message used when an artifact replaces the full Slack text.
|
|
213
|
+
*/
|
|
214
|
+
formatFinalResponseArtifactMessage?: (result: SlackFinalResponseArtifactResult, context: SlackFinalResponseArtifactContext) => string;
|
|
215
|
+
/**
|
|
216
|
+
* Called when `publishFinalResponseArtifact` throws. Errors from this hook
|
|
217
|
+
* are swallowed so artifact publication cannot break a completed turn.
|
|
218
|
+
*/
|
|
219
|
+
onFinalResponseArtifactError?: (error: unknown, context: SlackFinalResponseArtifactContext) => void | Promise<void>;
|
|
220
|
+
}
|
|
221
|
+
declare function resolveSlackEventBridgeOptions(partial: Partial<SlackEventBridgeOptions>): SlackEventBridgeOptions;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Event bridge — maps a runtime-neutral `SlackTurnEvent` stream to a Slack
|
|
225
|
+
* conversation via a `SlackResponseSink`.
|
|
226
|
+
*
|
|
227
|
+
* | Mode | Behaviour |
|
|
228
|
+
* |----------------|--------------------------------------------------------|
|
|
229
|
+
* | `progressive` | Posts a placeholder, updates it as text accumulates. |
|
|
230
|
+
* | `accumulate` | Collects the full response then posts it in one shot. |
|
|
231
|
+
* | `chat-stream` | Uses Slack's native `chat.startStream` + append + stop |
|
|
232
|
+
*
|
|
233
|
+
* The three modes share enough state (full-response accumulator, status
|
|
234
|
+
* label, last-update offset) that they live in one function. Per-mode
|
|
235
|
+
* branches are clearly labelled inside the event loop.
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Stream runtime-neutral turn events to a Slack conversation via
|
|
240
|
+
* `SlackResponseSink`.
|
|
241
|
+
*
|
|
242
|
+
* @returns The full accumulated response text.
|
|
243
|
+
*/
|
|
244
|
+
declare function bridgeSlackTurnEventsToSlack(events: AsyncGenerator<SlackTurnEvent>, sink: SlackResponseSink, options: SlackEventBridgeOptions): Promise<string>;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Interactive-request error type raised when an `approval-request` or
|
|
248
|
+
* `human-input-request` event reaches the Slack transport in a mode that
|
|
249
|
+
* does not support in-channel resolution.
|
|
250
|
+
*
|
|
251
|
+
* Hosts can catch this error to fall back to message-and-error mode, or install
|
|
252
|
+
* `createSlackInteractiveController` to render and resolve requests in Slack.
|
|
253
|
+
*/
|
|
254
|
+
declare class UnsupportedSlackInteractiveRequestError extends Error {
|
|
255
|
+
readonly kind: "approval" | "human-input";
|
|
256
|
+
readonly requestId: string;
|
|
257
|
+
constructor(kind: "approval" | "human-input", requestId: string, message: string);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { type SlackEventBridgeOptions, type SlackFinalResponseArtifactContext, type SlackFinalResponseArtifactDeliveryMode, type SlackFinalResponseArtifactPublisher, type SlackFinalResponseArtifactResult, type SlackTurnApprovalRequestEvent, type SlackTurnApprovalResolvedEvent, type SlackTurnCompleteEvent, type SlackTurnErrorEvent, type SlackTurnEvent, type SlackTurnEventBase, type SlackTurnHumanInputRequestEvent, type SlackTurnHumanInputResolvedEvent, type SlackTurnReasoningEndEvent, type SlackTurnReasoningStartEvent, type SlackTurnSource, type SlackTurnSourceChatOptions, type SlackTurnStatus, type SlackTurnStatusEvent, type SlackTurnSubagentCompleteEvent, type SlackTurnSubagentErrorEvent, type SlackTurnSubagentEventBase, type SlackTurnSubagentEventEvent, type SlackTurnSubagentStartEvent, type SlackTurnTextDeltaEvent, type SlackTurnTextEndEvent, type SlackTurnTextStartEvent, type SlackTurnToolErrorEvent, type SlackTurnToolResultEvent, type SlackTurnToolStartEvent, UnsupportedSlackInteractiveRequestError, bridgeSlackTurnEventsToSlack, resolveSlackEventBridgeOptions };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UnsupportedSlackInteractiveRequestError,
|
|
3
|
+
bridgeSlackTurnEventsToSlack,
|
|
4
|
+
resolveSlackEventBridgeOptions
|
|
5
|
+
} from "../chunk-IAQXQESO.js";
|
|
6
|
+
export {
|
|
7
|
+
UnsupportedSlackInteractiveRequestError,
|
|
8
|
+
bridgeSlackTurnEventsToSlack,
|
|
9
|
+
resolveSlackEventBridgeOptions
|
|
10
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
type SlackArtifactPublishMethod = "message" | "file" | "canvas";
|
|
2
|
+
type SlackArtifactBinaryData = string | Uint8Array | ArrayBuffer;
|
|
3
|
+
interface SlackArtifactBase {
|
|
4
|
+
kind: string;
|
|
5
|
+
title: string;
|
|
6
|
+
summary?: string;
|
|
7
|
+
metadata?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
interface SlackTextArtifact extends SlackArtifactBase {
|
|
10
|
+
kind: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
filename?: string;
|
|
13
|
+
mimeType?: string;
|
|
14
|
+
publishAs?: "message" | "file";
|
|
15
|
+
}
|
|
16
|
+
interface SlackFileArtifact extends SlackArtifactBase {
|
|
17
|
+
kind: "file";
|
|
18
|
+
filename: string;
|
|
19
|
+
data?: SlackArtifactBinaryData;
|
|
20
|
+
filePath?: string;
|
|
21
|
+
mimeType?: string;
|
|
22
|
+
initialComment?: string;
|
|
23
|
+
}
|
|
24
|
+
interface SlackImageArtifact extends SlackArtifactBase {
|
|
25
|
+
kind: "image";
|
|
26
|
+
filename: string;
|
|
27
|
+
altText: string;
|
|
28
|
+
data?: SlackArtifactBinaryData;
|
|
29
|
+
filePath?: string;
|
|
30
|
+
initialComment?: string;
|
|
31
|
+
}
|
|
32
|
+
interface SlackLinkArtifact extends SlackArtifactBase {
|
|
33
|
+
kind: "link";
|
|
34
|
+
url: string;
|
|
35
|
+
}
|
|
36
|
+
interface SlackCanvasArtifact extends SlackArtifactBase {
|
|
37
|
+
kind: "canvas";
|
|
38
|
+
markdown: string;
|
|
39
|
+
/**
|
|
40
|
+
* When set, updates an existing canvas instead of creating one.
|
|
41
|
+
*/
|
|
42
|
+
canvasId?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Create a channel canvas when a channel is available.
|
|
45
|
+
*
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
channelCanvas?: boolean;
|
|
49
|
+
}
|
|
50
|
+
type SlackArtifact = SlackTextArtifact | SlackFileArtifact | SlackImageArtifact | SlackLinkArtifact | SlackCanvasArtifact;
|
|
51
|
+
interface SlackArtifactPostMessageResponse {
|
|
52
|
+
ok?: boolean;
|
|
53
|
+
channel?: string;
|
|
54
|
+
ts?: string;
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
interface SlackArtifactFileUploadResponse {
|
|
58
|
+
ok?: boolean;
|
|
59
|
+
file?: {
|
|
60
|
+
id?: string;
|
|
61
|
+
[key: string]: unknown;
|
|
62
|
+
};
|
|
63
|
+
files?: Array<{
|
|
64
|
+
id?: string;
|
|
65
|
+
[key: string]: unknown;
|
|
66
|
+
}>;
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
}
|
|
69
|
+
interface SlackArtifactCanvasResponse {
|
|
70
|
+
ok?: boolean;
|
|
71
|
+
canvas_id?: string;
|
|
72
|
+
[key: string]: unknown;
|
|
73
|
+
}
|
|
74
|
+
interface SlackArtifactClient {
|
|
75
|
+
chat?: {
|
|
76
|
+
postMessage(args: Record<string, unknown>): Promise<SlackArtifactPostMessageResponse>;
|
|
77
|
+
};
|
|
78
|
+
files?: {
|
|
79
|
+
uploadV2(args: Record<string, unknown>): Promise<SlackArtifactFileUploadResponse>;
|
|
80
|
+
};
|
|
81
|
+
canvases?: {
|
|
82
|
+
create(args?: Record<string, unknown>): Promise<SlackArtifactCanvasResponse>;
|
|
83
|
+
edit?(args: Record<string, unknown>): Promise<SlackArtifactCanvasResponse>;
|
|
84
|
+
};
|
|
85
|
+
conversations?: {
|
|
86
|
+
canvases?: {
|
|
87
|
+
create(args: Record<string, unknown>): Promise<SlackArtifactCanvasResponse>;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
interface PublishSlackArtifactOptions {
|
|
92
|
+
client: SlackArtifactClient;
|
|
93
|
+
artifact: SlackArtifact;
|
|
94
|
+
channelId?: string;
|
|
95
|
+
threadTs?: string;
|
|
96
|
+
token?: string;
|
|
97
|
+
unfurlLinks?: boolean;
|
|
98
|
+
unfurlMedia?: boolean;
|
|
99
|
+
}
|
|
100
|
+
interface SlackArtifactPublication {
|
|
101
|
+
artifact: SlackArtifact;
|
|
102
|
+
method: SlackArtifactPublishMethod;
|
|
103
|
+
response: unknown;
|
|
104
|
+
channelId?: string;
|
|
105
|
+
threadTs?: string;
|
|
106
|
+
messageTs?: string;
|
|
107
|
+
fileId?: string;
|
|
108
|
+
canvasId?: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type { PublishSlackArtifactOptions as P, SlackArtifact as S, SlackArtifactBase as a, SlackArtifactBinaryData as b, SlackArtifactCanvasResponse as c, SlackArtifactClient as d, SlackArtifactFileUploadResponse as e, SlackArtifactPostMessageResponse as f, SlackArtifactPublication as g, SlackArtifactPublishMethod as h, SlackCanvasArtifact as i, SlackFileArtifact as j, SlackImageArtifact as k, SlackLinkArtifact as l, SlackTextArtifact as m };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { g as SlackInteractiveRequestContext } from './interactive-CbKYkkc_.js';
|
|
2
|
+
|
|
3
|
+
type SlackInteractiveRequestStatus = "pending" | "resolved";
|
|
4
|
+
type SlackInteractiveApprovalAction = "allow" | "deny" | "remember";
|
|
5
|
+
type SlackInteractiveHumanInputResponse = {
|
|
6
|
+
kind: "text";
|
|
7
|
+
text: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: "confirm";
|
|
10
|
+
confirmed: boolean;
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "choice";
|
|
14
|
+
selected: string[];
|
|
15
|
+
text: string;
|
|
16
|
+
};
|
|
17
|
+
interface SlackInteractiveApprovalRequest {
|
|
18
|
+
id: string;
|
|
19
|
+
tool: string;
|
|
20
|
+
args: unknown;
|
|
21
|
+
description: string;
|
|
22
|
+
risk: string;
|
|
23
|
+
rememberScopes?: string[];
|
|
24
|
+
defaultRememberScope?: string;
|
|
25
|
+
}
|
|
26
|
+
interface SlackInteractiveHumanInputOption {
|
|
27
|
+
label: string;
|
|
28
|
+
value?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
}
|
|
31
|
+
interface SlackInteractiveHumanInputRequest {
|
|
32
|
+
id: string;
|
|
33
|
+
kind: "text" | "confirm" | "choice";
|
|
34
|
+
title: string;
|
|
35
|
+
question: string;
|
|
36
|
+
options?: SlackInteractiveHumanInputOption[];
|
|
37
|
+
allowMultiple?: boolean;
|
|
38
|
+
placeholder?: string;
|
|
39
|
+
confirmLabel?: string;
|
|
40
|
+
denyLabel?: string;
|
|
41
|
+
}
|
|
42
|
+
type SlackInteractiveStoredRequest = SlackInteractiveApprovalRequest | SlackInteractiveHumanInputRequest;
|
|
43
|
+
type SlackInteractiveResolution = {
|
|
44
|
+
kind: "approval";
|
|
45
|
+
action: SlackInteractiveApprovalAction;
|
|
46
|
+
feedback?: string;
|
|
47
|
+
rememberScope?: string;
|
|
48
|
+
} | {
|
|
49
|
+
kind: "human-input";
|
|
50
|
+
response: SlackInteractiveHumanInputResponse;
|
|
51
|
+
};
|
|
52
|
+
interface SlackInteractiveMessageTarget {
|
|
53
|
+
channel: string;
|
|
54
|
+
ts: string;
|
|
55
|
+
threadTs?: string;
|
|
56
|
+
userId: string;
|
|
57
|
+
teamId?: string;
|
|
58
|
+
}
|
|
59
|
+
interface SlackInteractiveRequestRecord {
|
|
60
|
+
id: string;
|
|
61
|
+
kind: SlackInteractiveResolution["kind"];
|
|
62
|
+
request: SlackInteractiveStoredRequest;
|
|
63
|
+
status: SlackInteractiveRequestStatus;
|
|
64
|
+
createdAt: string;
|
|
65
|
+
updatedAt: string;
|
|
66
|
+
target?: SlackInteractiveMessageTarget;
|
|
67
|
+
resolution?: SlackInteractiveResolution;
|
|
68
|
+
}
|
|
69
|
+
interface SlackInteractiveRequestStore {
|
|
70
|
+
get(requestId: string): Promise<SlackInteractiveRequestRecord | undefined>;
|
|
71
|
+
upsert(record: SlackInteractiveRequestRecord): Promise<SlackInteractiveRequestRecord>;
|
|
72
|
+
attachTarget(requestId: string, target: SlackInteractiveMessageTarget): Promise<SlackInteractiveRequestRecord | undefined>;
|
|
73
|
+
resolve(requestId: string, resolution: SlackInteractiveResolution): Promise<SlackInteractiveRequestRecord | undefined>;
|
|
74
|
+
delete(requestId: string): Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
interface SlackInteractiveActionIds {
|
|
77
|
+
approvalAllow: string;
|
|
78
|
+
approvalDeny: string;
|
|
79
|
+
approvalRemember: string;
|
|
80
|
+
humanConfirm: string;
|
|
81
|
+
humanDeny: string;
|
|
82
|
+
humanOpen: string;
|
|
83
|
+
humanSubmit: string;
|
|
84
|
+
}
|
|
85
|
+
interface SlackInteractiveActor {
|
|
86
|
+
userId: string;
|
|
87
|
+
teamId?: string;
|
|
88
|
+
}
|
|
89
|
+
type SlackInteractiveRequestHandler = (context: SlackInteractiveRequestContext) => boolean | void | Promise<boolean | void>;
|
|
90
|
+
|
|
91
|
+
export type { SlackInteractiveActionIds as S, SlackInteractiveActor as a, SlackInteractiveApprovalAction as b, SlackInteractiveApprovalRequest as c, SlackInteractiveHumanInputOption as d, SlackInteractiveHumanInputRequest as e, SlackInteractiveHumanInputResponse as f, SlackInteractiveMessageTarget as g, SlackInteractiveRequestHandler as h, SlackInteractiveRequestRecord as i, SlackInteractiveRequestStatus as j, SlackInteractiveRequestStore as k, SlackInteractiveResolution as l, SlackInteractiveStoredRequest as m };
|
|
@@ -24,6 +24,9 @@ contracts.
|
|
|
24
24
|
- User profile and mention helpers.
|
|
25
25
|
- Target parsing and resolution.
|
|
26
26
|
- Feedback blocks and action handler.
|
|
27
|
+
- Slack response sink and chat stream contracts for runtime adapters.
|
|
28
|
+
- Slack interactive request Block Kit/modal builders and in-memory/Postgres
|
|
29
|
+
stores.
|
|
27
30
|
- Slack message policy resolver and in-memory/Postgres state stores.
|
|
28
31
|
- Supplemental history reader, context loader, and visibility policy.
|
|
29
32
|
- Assistant message parser and thread-context store.
|
|
@@ -33,8 +36,8 @@ contracts.
|
|
|
33
36
|
- Agent runtime execution.
|
|
34
37
|
- Agent-runtime scopes and context-fragment middleware.
|
|
35
38
|
- Runtime-specific mapping from Slack entrypoints into an agent turn.
|
|
36
|
-
- Agent event stream rendering.
|
|
37
|
-
- Agent-specific approval and human-input
|
|
39
|
+
- Agent event stream rendering and runtime-specific response orchestration.
|
|
40
|
+
- Agent-specific approval and human-input controllers.
|
|
38
41
|
- Product prompts, tools, audit policy, and deployment policy.
|
|
39
42
|
|
|
40
43
|
Those pieces belong in runtime-specific adapters or product applications.
|
|
@@ -8,9 +8,11 @@ keep application code close to the package boundary it uses.
|
|
|
8
8
|
| `@cuylabs/channel-slack/core` | no Slack SDK runtime imports | Transport-neutral parsing, formatting, types, sessions, turn context |
|
|
9
9
|
| `@cuylabs/channel-slack/policy` | `pg` only when using connection-string Postgres state | Message admission and in-memory/Postgres policy state |
|
|
10
10
|
| `@cuylabs/channel-slack/history` | `@slack/web-api` types | History reader accepts a Slack WebClient or minimal conversations client |
|
|
11
|
+
| `@cuylabs/channel-slack/interactive` | `@slack/types`; `pg` only when using connection-string Postgres storage | Slack interactive Block Kit/modal builders and request stores |
|
|
11
12
|
| `@cuylabs/channel-slack/app-home` | `@slack/bolt`, `@slack/types` | Slack App Home registration helper |
|
|
12
13
|
| `@cuylabs/channel-slack/artifacts` | no Slack SDK runtime imports; requires a Web API-like client at call time | Text, file, image, link, and Canvas artifact publishing |
|
|
13
14
|
| `@cuylabs/channel-slack/auth` | no Slack SDK runtime imports; `pg` is not required | Auth option types, auth resolution, OAuth installation stores |
|
|
15
|
+
| `@cuylabs/channel-slack/responses` | no Slack SDK runtime imports | Slack response sink and chat stream contracts for runtime adapters |
|
|
14
16
|
| `@cuylabs/channel-slack/transports` | `@slack/bolt`, `express`; `pg` only when using connection-string Postgres locks | HTTP and Socket Mode transport helpers |
|
|
15
17
|
| `@cuylabs/channel-slack/transports/http` | `@slack/bolt`, `express` | HTTP Events API Bolt app factory |
|
|
16
18
|
| `@cuylabs/channel-slack/transports/socket` | `@slack/bolt`; `pg` only when using connection-string Postgres locks | Socket Mode app factory, runtime guard, process/Postgres locks |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cuylabs/channel-slack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Agent-runtime-agnostic Slack channel primitives for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -56,11 +56,26 @@
|
|
|
56
56
|
"import": "./dist/history/index.js",
|
|
57
57
|
"default": "./dist/history/index.js"
|
|
58
58
|
},
|
|
59
|
+
"./interactive": {
|
|
60
|
+
"types": "./dist/interactive/index.d.ts",
|
|
61
|
+
"import": "./dist/interactive/index.js",
|
|
62
|
+
"default": "./dist/interactive/index.js"
|
|
63
|
+
},
|
|
59
64
|
"./policy": {
|
|
60
65
|
"types": "./dist/policy/index.d.ts",
|
|
61
66
|
"import": "./dist/policy/index.js",
|
|
62
67
|
"default": "./dist/policy/index.js"
|
|
63
68
|
},
|
|
69
|
+
"./responses": {
|
|
70
|
+
"types": "./dist/responses/index.d.ts",
|
|
71
|
+
"import": "./dist/responses/index.js",
|
|
72
|
+
"default": "./dist/responses/index.js"
|
|
73
|
+
},
|
|
74
|
+
"./runtime": {
|
|
75
|
+
"types": "./dist/runtime/index.d.ts",
|
|
76
|
+
"import": "./dist/runtime/index.js",
|
|
77
|
+
"default": "./dist/runtime/index.js"
|
|
78
|
+
},
|
|
64
79
|
"./setup": {
|
|
65
80
|
"types": "./dist/setup/index.d.ts",
|
|
66
81
|
"import": "./dist/setup/index.js",
|
|
@@ -153,9 +168,9 @@
|
|
|
153
168
|
"node": ">=20"
|
|
154
169
|
},
|
|
155
170
|
"scripts": {
|
|
156
|
-
"build": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/policy/index.ts src/setup/index.ts src/targets/index.ts src/turn-controls/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts src/views/index.ts --format esm --dts --clean",
|
|
171
|
+
"build": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/interactive/index.ts src/policy/index.ts src/responses/index.ts src/runtime/index.ts src/setup/index.ts src/targets/index.ts src/turn-controls/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts src/views/index.ts --format esm --dts --clean",
|
|
157
172
|
"clean": "rm -rf dist",
|
|
158
|
-
"dev": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/policy/index.ts src/setup/index.ts src/targets/index.ts src/turn-controls/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts src/views/index.ts --format esm --dts --watch",
|
|
173
|
+
"dev": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/interactive/index.ts src/policy/index.ts src/responses/index.ts src/runtime/index.ts src/setup/index.ts src/targets/index.ts src/turn-controls/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts src/views/index.ts --format esm --dts --watch",
|
|
159
174
|
"lint": "eslint \"src/**/*.{ts,tsx}\" \"tests/**/*.{ts,tsx}\" --max-warnings=0",
|
|
160
175
|
"test": "vitest run",
|
|
161
176
|
"test:watch": "vitest",
|