@cuylabs/channel-slack-agent-core 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 +13 -10
- package/dist/chunk-U6RC4SXN.js +331 -0
- package/dist/history/index.d.ts +7 -17
- package/dist/index.d.ts +5 -28
- package/dist/index.js +14 -58
- package/dist/interactive/index.d.ts +86 -7
- package/dist/shared/index.d.ts +144 -19
- package/dist/shared/index.js +8 -4
- package/docs/README.md +0 -1
- package/docs/concepts/final-response-artifacts.md +9 -7
- package/docs/concepts/tool-task-rendering.md +2 -0
- package/docs/reference/exports.md +10 -20
- package/package.json +4 -54
- package/dist/adapter/index.d.ts +0 -26
- package/dist/adapter/index.js +0 -9
- package/dist/adapter-vbqtraAr.d.ts +0 -31
- package/dist/app-surface.d.ts +0 -82
- package/dist/app-surface.js +0 -10
- package/dist/app.d.ts +0 -60
- package/dist/app.js +0 -11
- package/dist/artifacts/index.d.ts +0 -57
- package/dist/artifacts/index.js +0 -6
- package/dist/assistant/index.d.ts +0 -22
- package/dist/assistant/index.js +0 -14
- package/dist/chunk-A2PLAVW6.js +0 -75
- package/dist/chunk-C7CHMYV6.js +0 -226
- package/dist/chunk-D4CSEAIF.js +0 -82
- package/dist/chunk-ELR6MQD7.js +0 -12
- package/dist/chunk-FJP6ZFUB.js +0 -921
- package/dist/chunk-GKZRDNEB.js +0 -187
- package/dist/chunk-HHXAXSG6.js +0 -67
- package/dist/chunk-JU5R6JZG.js +0 -85
- package/dist/chunk-KAEZPS3U.js +0 -77
- package/dist/chunk-NNCVHQC4.js +0 -94
- package/dist/chunk-VBGQD6JT.js +0 -1008
- package/dist/chunk-XA7U3GRN.js +0 -482
- package/dist/express-assistant.d.ts +0 -106
- package/dist/express-assistant.js +0 -9
- package/dist/express.d.ts +0 -103
- package/dist/express.js +0 -8
- package/dist/feedback/index.d.ts +0 -1
- package/dist/feedback/index.js +0 -10
- package/dist/options-ByNm2o89.d.ts +0 -323
- package/dist/options-CGUfVStV.d.ts +0 -119
- package/dist/socket.d.ts +0 -143
- package/dist/socket.js +0 -13
- package/dist/types-BeGPexio.d.ts +0 -381
- package/dist/types-Bz4OYEAV.d.ts +0 -87
- package/dist/types-CiwGU6zC.d.ts +0 -56
- package/dist/views/index.d.ts +0 -8
- package/dist/views/index.js +0 -10
- package/docs/concepts/view-workflows.md +0 -52
package/dist/chunk-XA7U3GRN.js
DELETED
|
@@ -1,482 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
UnsupportedSlackInteractiveRequestError,
|
|
3
|
-
bridgeAgentEventsToSlack,
|
|
4
|
-
resolveSlackEventBridgeOptions
|
|
5
|
-
} from "./chunk-VBGQD6JT.js";
|
|
6
|
-
|
|
7
|
-
// src/adapter/adapter.ts
|
|
8
|
-
import { withinScope } from "@cuylabs/agent-core";
|
|
9
|
-
import {
|
|
10
|
-
extractSlackAuthContext,
|
|
11
|
-
extractSlackUserIdentity,
|
|
12
|
-
isProcessableMessage,
|
|
13
|
-
parseSlackMentionActivity,
|
|
14
|
-
parseSlackMessageActivity,
|
|
15
|
-
resolveSlackMessageFormatter,
|
|
16
|
-
runWithSlackTurnContext
|
|
17
|
-
} from "@cuylabs/channel-slack/core";
|
|
18
|
-
|
|
19
|
-
// src/adapter/session-map.ts
|
|
20
|
-
import {
|
|
21
|
-
resolveThreadAwareSlackSessionId
|
|
22
|
-
} from "@cuylabs/channel-slack/core";
|
|
23
|
-
function createSlackSessionMap(options) {
|
|
24
|
-
const strategy = options.sessionStrategy ?? "thread-aware";
|
|
25
|
-
if (strategy === "custom") {
|
|
26
|
-
if (!options.resolveSessionId) {
|
|
27
|
-
throw new Error(
|
|
28
|
-
"SlackChannelOptions.resolveSessionId is required when sessionStrategy is 'custom'"
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
const customResolve = options.resolveSessionId;
|
|
32
|
-
return {
|
|
33
|
-
resolve(info) {
|
|
34
|
-
return customResolve(info);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
if (strategy === "channel-id") {
|
|
39
|
-
return {
|
|
40
|
-
resolve(info) {
|
|
41
|
-
return info.channelId;
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
if (strategy === "user-per-channel") {
|
|
46
|
-
return {
|
|
47
|
-
resolve(info) {
|
|
48
|
-
return `${info.channelId}:${info.userId}`;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
if (strategy === "user-per-thread") {
|
|
53
|
-
return {
|
|
54
|
-
resolve(info) {
|
|
55
|
-
if (info.channelType === "dm") {
|
|
56
|
-
return `${info.channelId}:${info.userId}`;
|
|
57
|
-
}
|
|
58
|
-
return `${info.channelId}:${info.threadTs ?? info.messageTs ?? info.channelId}:${info.userId}`;
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
return {
|
|
63
|
-
resolve: resolveThreadAwareSlackSessionId
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// src/adapter/sink.ts
|
|
68
|
-
function buildThreadPayload(info, respondInThread) {
|
|
69
|
-
if (!respondInThread || info.channelType === "dm") return {};
|
|
70
|
-
const threadTs = info.threadTs ?? info.messageTs;
|
|
71
|
-
return threadTs ? { thread_ts: threadTs } : {};
|
|
72
|
-
}
|
|
73
|
-
function buildResponseSink(say, client, info, respondInThread, chatStreamStartArgs, sayStream) {
|
|
74
|
-
const threadPayload = buildThreadPayload(info, respondInThread);
|
|
75
|
-
return {
|
|
76
|
-
artifactClient: client,
|
|
77
|
-
artifactTarget: {
|
|
78
|
-
channelId: info.channelId,
|
|
79
|
-
...threadPayload.thread_ts ? { threadTs: threadPayload.thread_ts } : {}
|
|
80
|
-
},
|
|
81
|
-
async postMessage(text) {
|
|
82
|
-
const result = await say({ text, ...threadPayload });
|
|
83
|
-
const response = result;
|
|
84
|
-
const { channel, ts } = response;
|
|
85
|
-
if (!channel || !ts) {
|
|
86
|
-
throw new Error("Slack say() response did not include channel and ts.");
|
|
87
|
-
}
|
|
88
|
-
return { channel, ts };
|
|
89
|
-
},
|
|
90
|
-
async updateMessage(channel, ts, text) {
|
|
91
|
-
await client.chat.update({ channel, ts, text });
|
|
92
|
-
},
|
|
93
|
-
createChatStream({ bufferSize }) {
|
|
94
|
-
const threadTs = threadPayload.thread_ts ?? info.messageTs;
|
|
95
|
-
if (!threadTs) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
"Slack chat-stream mode requires a source message timestamp."
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
const streamArgs = {
|
|
101
|
-
...chatStreamStartArgs ?? {},
|
|
102
|
-
buffer_size: bufferSize
|
|
103
|
-
};
|
|
104
|
-
if (typeof sayStream === "function") {
|
|
105
|
-
return sayStream(streamArgs);
|
|
106
|
-
}
|
|
107
|
-
const streamer = client.chatStream({
|
|
108
|
-
channel: info.channelId,
|
|
109
|
-
thread_ts: threadTs,
|
|
110
|
-
...info.teamId ? { recipient_team_id: info.teamId } : {},
|
|
111
|
-
recipient_user_id: info.userId,
|
|
112
|
-
...streamArgs
|
|
113
|
-
});
|
|
114
|
-
return streamer;
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
function buildInteractiveResponder(say, client, info, respondInThread) {
|
|
119
|
-
const threadPayload = buildThreadPayload(info, respondInThread);
|
|
120
|
-
return {
|
|
121
|
-
async postMessage(message) {
|
|
122
|
-
const result = await say({
|
|
123
|
-
text: message.text,
|
|
124
|
-
...message.blocks ? { blocks: message.blocks } : {},
|
|
125
|
-
...threadPayload
|
|
126
|
-
});
|
|
127
|
-
const response = result;
|
|
128
|
-
const channel = response.channel ?? info.channelId;
|
|
129
|
-
const ts = response.ts;
|
|
130
|
-
if (!channel || !ts) {
|
|
131
|
-
throw new Error("Slack say() response did not include channel and ts.");
|
|
132
|
-
}
|
|
133
|
-
return { channel, ts };
|
|
134
|
-
},
|
|
135
|
-
async updateMessage(ref, message) {
|
|
136
|
-
await client.chat.update({
|
|
137
|
-
channel: ref.channel,
|
|
138
|
-
ts: ref.ts,
|
|
139
|
-
text: message.text,
|
|
140
|
-
...message.blocks ? { blocks: message.blocks } : {}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// src/adapter/scope-attributes.ts
|
|
147
|
-
function buildScopeAttributes(info, user, prep) {
|
|
148
|
-
return {
|
|
149
|
-
slackChannelId: info.channelId,
|
|
150
|
-
slackChannelType: info.channelType,
|
|
151
|
-
slackUserId: user.userId,
|
|
152
|
-
slackTeamId: user.teamId,
|
|
153
|
-
slackThreadTs: info.threadTs,
|
|
154
|
-
slackIsMention: info.isMention,
|
|
155
|
-
...prep.scopeAttributes ?? {}
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// src/adapter/adapter.ts
|
|
160
|
-
var DEFAULT_CLASSIC_INITIAL_STATUS = {
|
|
161
|
-
status: "Thinking..."
|
|
162
|
-
};
|
|
163
|
-
function createSlackChannelAdapter(options) {
|
|
164
|
-
const source = resolveTurnSource(options);
|
|
165
|
-
const sessionMap = createSlackSessionMap(options);
|
|
166
|
-
const bridgeOptions = resolveSlackEventBridgeOptions(
|
|
167
|
-
{
|
|
168
|
-
showReasoning: options.showReasoning,
|
|
169
|
-
showToolUsage: options.showToolUsage,
|
|
170
|
-
showSubagentToolUsage: options.showSubagentToolUsage,
|
|
171
|
-
showSubagentResultInTask: options.showSubagentResultInTask,
|
|
172
|
-
formatToolTitle: options.formatToolTitle,
|
|
173
|
-
formatToolUpdate: options.formatToolUpdate,
|
|
174
|
-
formatToolDetails: options.formatToolDetails,
|
|
175
|
-
formatToolResultOutput: options.formatToolResultOutput,
|
|
176
|
-
formatToolError: options.formatToolError,
|
|
177
|
-
formatReasoningUpdate: options.formatReasoningUpdate,
|
|
178
|
-
interactiveMode: options.interactiveMode,
|
|
179
|
-
formatApprovalRequired: options.formatApprovalRequired,
|
|
180
|
-
formatHumanInputRequired: options.formatHumanInputRequired,
|
|
181
|
-
formatMessageText: resolveSlackMessageFormatter(options),
|
|
182
|
-
streamingMode: options.streamingMode,
|
|
183
|
-
progressiveUpdateThreshold: options.progressiveUpdateThreshold,
|
|
184
|
-
progressiveUpdateIntervalMs: options.progressiveUpdateIntervalMs,
|
|
185
|
-
chatStreamBufferSize: options.chatStreamBufferSize,
|
|
186
|
-
maxTaskUpdates: options.maxTaskUpdates,
|
|
187
|
-
maxTaskUpdateTextChars: options.maxTaskUpdateTextChars,
|
|
188
|
-
maxTaskUpdateFieldChars: options.maxTaskUpdateFieldChars,
|
|
189
|
-
chatStreamFinalArgs: options.chatStreamFinalArgs,
|
|
190
|
-
publishFinalResponseArtifact: options.publishFinalResponseArtifact,
|
|
191
|
-
finalResponseArtifactMode: options.finalResponseArtifactMode,
|
|
192
|
-
finalResponseArtifactStreamThreshold: options.finalResponseArtifactStreamThreshold,
|
|
193
|
-
formatFinalResponseArtifactContinuationNotice: options.formatFinalResponseArtifactContinuationNotice,
|
|
194
|
-
formatFinalResponseArtifactMessage: options.formatFinalResponseArtifactMessage,
|
|
195
|
-
onFinalResponseArtifactError: options.onFinalResponseArtifactError
|
|
196
|
-
}
|
|
197
|
-
);
|
|
198
|
-
const timeout = options.timeout ?? 12e4;
|
|
199
|
-
const respondInThread = options.respondInThread ?? true;
|
|
200
|
-
const respondToMentions = options.respondToMentions ?? true;
|
|
201
|
-
const respondToMessages = options.respondToMessages ?? true;
|
|
202
|
-
const respondToChannelMessages = options.respondToChannelMessages ?? false;
|
|
203
|
-
async function processTurn(slackActivity, say, client, context, utilities = {}) {
|
|
204
|
-
const rawText = slackActivity.text.trim();
|
|
205
|
-
const userText = options.resolveMessage ? await options.resolveMessage(slackActivity) : rawText;
|
|
206
|
-
if (!userText) return;
|
|
207
|
-
const initialSessionId = await sessionMap.resolve(slackActivity);
|
|
208
|
-
const userIdentity = extractSlackUserIdentity(slackActivity);
|
|
209
|
-
const auth = extractSlackAuthContext(context, slackActivity.userId);
|
|
210
|
-
const hasSayStream = typeof utilities.sayStream === "function";
|
|
211
|
-
const hasSetStatus = typeof utilities.setStatus === "function";
|
|
212
|
-
options.logger?.debug?.("slack classic turn utilities", {
|
|
213
|
-
channelId: slackActivity.channelId,
|
|
214
|
-
channelType: slackActivity.channelType,
|
|
215
|
-
isMention: slackActivity.isMention,
|
|
216
|
-
threadTs: slackActivity.threadTs,
|
|
217
|
-
messageTs: slackActivity.messageTs,
|
|
218
|
-
hasSayStream,
|
|
219
|
-
hasSetStatus
|
|
220
|
-
});
|
|
221
|
-
const baseTurnRequest = {
|
|
222
|
-
slackActivity,
|
|
223
|
-
user: userIdentity,
|
|
224
|
-
sessionId: initialSessionId,
|
|
225
|
-
message: userText,
|
|
226
|
-
auth,
|
|
227
|
-
...utilities.setStatus ? { setStatus: utilities.setStatus } : {}
|
|
228
|
-
};
|
|
229
|
-
if (utilities.setStatus) {
|
|
230
|
-
const initialStatus = await resolveClassicInitialStatus(
|
|
231
|
-
options,
|
|
232
|
-
baseTurnRequest
|
|
233
|
-
);
|
|
234
|
-
if (initialStatus) {
|
|
235
|
-
try {
|
|
236
|
-
await utilities.setStatus(initialStatus);
|
|
237
|
-
} catch (error) {
|
|
238
|
-
options.logger?.warn?.("slack classic setStatus failed", {
|
|
239
|
-
error: formatErrorForLog(error)
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
const resolvedSessionId = await options.resolveSession?.(baseTurnRequest);
|
|
245
|
-
const sessionId = resolvedSessionId && resolvedSessionId.length > 0 ? resolvedSessionId : initialSessionId;
|
|
246
|
-
const turnRequest = {
|
|
247
|
-
...baseTurnRequest,
|
|
248
|
-
sessionId
|
|
249
|
-
};
|
|
250
|
-
const preparedTurn = await resolveTurnPreparation(
|
|
251
|
-
options,
|
|
252
|
-
turnRequest,
|
|
253
|
-
userIdentity
|
|
254
|
-
);
|
|
255
|
-
const finalSessionId = preparedTurn.sessionId && preparedTurn.sessionId.length > 0 ? preparedTurn.sessionId : sessionId;
|
|
256
|
-
const finalUserText = preparedTurn.message ?? userText;
|
|
257
|
-
const sink = buildResponseSink(
|
|
258
|
-
say,
|
|
259
|
-
client,
|
|
260
|
-
slackActivity,
|
|
261
|
-
respondInThread,
|
|
262
|
-
options.chatStreamStartArgs,
|
|
263
|
-
utilities.sayStream
|
|
264
|
-
);
|
|
265
|
-
const abortController = new AbortController();
|
|
266
|
-
const chatOptions = {
|
|
267
|
-
abort: abortController.signal
|
|
268
|
-
};
|
|
269
|
-
if (preparedTurn.system) {
|
|
270
|
-
chatOptions.system = preparedTurn.system;
|
|
271
|
-
}
|
|
272
|
-
const timeoutId = timeout > 0 ? setTimeout(() => abortController.abort(), timeout) : void 0;
|
|
273
|
-
try {
|
|
274
|
-
const scopeAttributes = buildScopeAttributes(
|
|
275
|
-
slackActivity,
|
|
276
|
-
userIdentity,
|
|
277
|
-
preparedTurn
|
|
278
|
-
);
|
|
279
|
-
await runWithSlackTurnContext(
|
|
280
|
-
{
|
|
281
|
-
...turnRequest,
|
|
282
|
-
sessionId: finalSessionId,
|
|
283
|
-
message: finalUserText,
|
|
284
|
-
...utilities.setStatus ? { setStatus: utilities.setStatus } : {},
|
|
285
|
-
...preparedTurn.context ? { context: preparedTurn.context } : {}
|
|
286
|
-
},
|
|
287
|
-
() => withinScope(
|
|
288
|
-
{
|
|
289
|
-
kind: "activity",
|
|
290
|
-
name: preparedTurn.scopeName?.trim() || "slack-activity",
|
|
291
|
-
sessionId: finalSessionId,
|
|
292
|
-
attributes: scopeAttributes
|
|
293
|
-
},
|
|
294
|
-
async () => {
|
|
295
|
-
const events = source.chat(
|
|
296
|
-
finalSessionId,
|
|
297
|
-
finalUserText,
|
|
298
|
-
chatOptions
|
|
299
|
-
);
|
|
300
|
-
const baseTurnBridgeOptions = options.handleInteractiveRequest ? {
|
|
301
|
-
...bridgeOptions,
|
|
302
|
-
handleInteractiveRequest: (interactive) => options.handleInteractiveRequest({
|
|
303
|
-
...interactive,
|
|
304
|
-
slackActivity,
|
|
305
|
-
user: userIdentity,
|
|
306
|
-
sessionId: finalSessionId,
|
|
307
|
-
message: finalUserText,
|
|
308
|
-
responder: buildInteractiveResponder(
|
|
309
|
-
say,
|
|
310
|
-
client,
|
|
311
|
-
slackActivity,
|
|
312
|
-
respondInThread
|
|
313
|
-
)
|
|
314
|
-
})
|
|
315
|
-
} : bridgeOptions;
|
|
316
|
-
const turnBridgeOptions = withClassicStatusUpdates(
|
|
317
|
-
baseTurnBridgeOptions,
|
|
318
|
-
utilities.setStatus
|
|
319
|
-
);
|
|
320
|
-
await bridgeAgentEventsToSlack(events, sink, turnBridgeOptions);
|
|
321
|
-
}
|
|
322
|
-
)
|
|
323
|
-
);
|
|
324
|
-
} catch (error) {
|
|
325
|
-
const errorInstance = error instanceof Error ? error : new Error(String(error));
|
|
326
|
-
if (!(errorInstance instanceof UnsupportedSlackInteractiveRequestError)) {
|
|
327
|
-
await say({
|
|
328
|
-
text: `I encountered an error while processing your request: ${errorInstance.message}`,
|
|
329
|
-
...buildThreadPayload(slackActivity, respondInThread)
|
|
330
|
-
}).catch(() => void 0);
|
|
331
|
-
}
|
|
332
|
-
if (options.onError) {
|
|
333
|
-
await options.onError(errorInstance, slackActivity);
|
|
334
|
-
}
|
|
335
|
-
} finally {
|
|
336
|
-
if (timeoutId) {
|
|
337
|
-
clearTimeout(timeoutId);
|
|
338
|
-
}
|
|
339
|
-
if (utilities.setStatus) {
|
|
340
|
-
await utilities.setStatus({ status: "" }).catch(
|
|
341
|
-
(error) => options.logger?.warn?.("slack classic clear status failed", {
|
|
342
|
-
error: formatErrorForLog(error)
|
|
343
|
-
})
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
function mount(app) {
|
|
349
|
-
if (respondToMessages) {
|
|
350
|
-
app.message(
|
|
351
|
-
async ({
|
|
352
|
-
message,
|
|
353
|
-
say,
|
|
354
|
-
client,
|
|
355
|
-
context,
|
|
356
|
-
sayStream,
|
|
357
|
-
setStatus
|
|
358
|
-
}) => {
|
|
359
|
-
const raw = message;
|
|
360
|
-
if (!isProcessableMessage(
|
|
361
|
-
raw
|
|
362
|
-
)) {
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
const info = parseSlackMessageActivity(
|
|
366
|
-
raw
|
|
367
|
-
);
|
|
368
|
-
if (info.channelType !== "dm" && !respondToChannelMessages) {
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
if (!info.text) return;
|
|
372
|
-
await processTurn(info, say, client, context, {
|
|
373
|
-
...typeof sayStream === "function" ? { sayStream } : {},
|
|
374
|
-
...typeof setStatus === "function" ? { setStatus } : {}
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
);
|
|
378
|
-
}
|
|
379
|
-
if (respondToMentions) {
|
|
380
|
-
app.event(
|
|
381
|
-
"app_mention",
|
|
382
|
-
async ({
|
|
383
|
-
event,
|
|
384
|
-
say,
|
|
385
|
-
client,
|
|
386
|
-
context,
|
|
387
|
-
sayStream,
|
|
388
|
-
setStatus
|
|
389
|
-
}) => {
|
|
390
|
-
const info = parseSlackMentionActivity(
|
|
391
|
-
event
|
|
392
|
-
);
|
|
393
|
-
if (!info.text) return;
|
|
394
|
-
await processTurn(info, say, client, context, {
|
|
395
|
-
...typeof sayStream === "function" ? { sayStream } : {},
|
|
396
|
-
...typeof setStatus === "function" ? { setStatus } : {}
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
if (options.welcomeMessage != null) {
|
|
402
|
-
app.event("member_joined_channel", async ({ event, client }) => {
|
|
403
|
-
const channelId = event.channel;
|
|
404
|
-
const userId = event.user;
|
|
405
|
-
const botInfo = await client.auth.test().catch(() => void 0);
|
|
406
|
-
if (botInfo?.user_id === userId) return;
|
|
407
|
-
await client.chat.postMessage({
|
|
408
|
-
channel: userId,
|
|
409
|
-
// DM the new member
|
|
410
|
-
text: options.welcomeMessage
|
|
411
|
-
}).catch(() => void 0);
|
|
412
|
-
await client.chat.postMessage({
|
|
413
|
-
channel: channelId,
|
|
414
|
-
text: options.welcomeMessage
|
|
415
|
-
}).catch(() => void 0);
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
return {
|
|
420
|
-
mount,
|
|
421
|
-
getSessionId: (info) => sessionMap.resolve(info)
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
function formatClassicSlackStatusUpdate(status) {
|
|
425
|
-
return { status };
|
|
426
|
-
}
|
|
427
|
-
async function resolveClassicInitialStatus(options, request) {
|
|
428
|
-
if (options.initialStatus === void 0) {
|
|
429
|
-
return DEFAULT_CLASSIC_INITIAL_STATUS;
|
|
430
|
-
}
|
|
431
|
-
if (typeof options.initialStatus === "function") {
|
|
432
|
-
return await options.initialStatus(request) ?? void 0;
|
|
433
|
-
}
|
|
434
|
-
return options.initialStatus;
|
|
435
|
-
}
|
|
436
|
-
function withClassicStatusUpdates(options, setStatus) {
|
|
437
|
-
if (!setStatus) {
|
|
438
|
-
return options;
|
|
439
|
-
}
|
|
440
|
-
return {
|
|
441
|
-
...options,
|
|
442
|
-
onStatusChange: async (label, event) => {
|
|
443
|
-
await options.onStatusChange?.(label, event);
|
|
444
|
-
await setStatus(formatClassicSlackStatusUpdate(label));
|
|
445
|
-
}
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
function resolveTurnSource(options) {
|
|
449
|
-
const hasAgent = options.agent !== void 0;
|
|
450
|
-
const hasSource = options.source !== void 0;
|
|
451
|
-
if (hasAgent === hasSource) {
|
|
452
|
-
throw new Error(
|
|
453
|
-
"Provide exactly one of SlackChannelOptions.agent or SlackChannelOptions.source."
|
|
454
|
-
);
|
|
455
|
-
}
|
|
456
|
-
if (options.source) return options.source;
|
|
457
|
-
if (options.agent) return options.agent;
|
|
458
|
-
throw new Error(
|
|
459
|
-
"Provide exactly one of SlackChannelOptions.agent or SlackChannelOptions.source."
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
async function resolveTurnPreparation(options, request, user) {
|
|
463
|
-
if (options.prepareTurn) {
|
|
464
|
-
return await options.prepareTurn(request) ?? {};
|
|
465
|
-
}
|
|
466
|
-
if (options.resolveUserContext) {
|
|
467
|
-
const ctx = await options.resolveUserContext(user);
|
|
468
|
-
return ctx ?? {};
|
|
469
|
-
}
|
|
470
|
-
return {};
|
|
471
|
-
}
|
|
472
|
-
function formatErrorForLog(error) {
|
|
473
|
-
if (error instanceof Error) {
|
|
474
|
-
return error.stack ?? error.message;
|
|
475
|
-
}
|
|
476
|
-
return String(error);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
export {
|
|
480
|
-
createSlackSessionMap,
|
|
481
|
-
createSlackChannelAdapter
|
|
482
|
-
};
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { Server } from 'node:http';
|
|
2
|
-
import { Application } from 'express';
|
|
3
|
-
import { App, ExpressReceiver } from '@slack/bolt';
|
|
4
|
-
import { CreateSlackBoltAppOptions } from '@cuylabs/channel-slack/transports/http';
|
|
5
|
-
import { SlackDirectAuthOptions, SlackDirectAuthMode } from '@cuylabs/channel-slack/auth';
|
|
6
|
-
import { C as CreateSlackAssistantBridgeOptions, d as SlackAssistantFeedbackConfig, S as SlackAssistantBridge } from './options-ByNm2o89.js';
|
|
7
|
-
import { SlackFeedbackHandler } from '@cuylabs/channel-slack/feedback';
|
|
8
|
-
import '@cuylabs/agent-core';
|
|
9
|
-
import '@slack/web-api';
|
|
10
|
-
import '@cuylabs/channel-slack/core';
|
|
11
|
-
import './interactive-BigrPKnu.js';
|
|
12
|
-
import '@cuylabs/channel-slack/interactive';
|
|
13
|
-
import './options-CGUfVStV.js';
|
|
14
|
-
import './artifacts/index.js';
|
|
15
|
-
import '@cuylabs/channel-slack/artifacts';
|
|
16
|
-
import '@cuylabs/channel-slack/assistant';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Express helper for mounting the Slack assistant bridge.
|
|
20
|
-
*
|
|
21
|
-
* Companion to `mountSlackAgent` (which wires the classic
|
|
22
|
-
* `app.message`/`app.event` listeners). This one uses
|
|
23
|
-
* `createSlackAssistantBridge` so the bot uses Bolt's
|
|
24
|
-
* `app.assistant(new Assistant({...}))` lifecycle — `setStatus`,
|
|
25
|
-
* `setSuggestedPrompts`, `chatStream`, feedback buttons.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```ts
|
|
29
|
-
* import { mountSlackAssistantAgent } from "@cuylabs/channel-slack-agent-core";
|
|
30
|
-
*
|
|
31
|
-
* await mountSlackAssistantAgent(agent, {
|
|
32
|
-
* getSuggestedPrompts: () => ({
|
|
33
|
-
* title: "Try one of these:",
|
|
34
|
-
* prompts: [
|
|
35
|
-
* { title: "Roll some dice", message: "Roll 2d20" },
|
|
36
|
-
* { title: "Summarize this thread", message: "Summarize the last 20 messages" },
|
|
37
|
-
* ],
|
|
38
|
-
* }),
|
|
39
|
-
* onFeedback: ({ verdict, sessionId }) => {
|
|
40
|
-
* metrics.increment(`feedback.${verdict}`, { sessionId });
|
|
41
|
-
* },
|
|
42
|
-
* });
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
interface MountSlackAssistantAgentOptions extends Omit<CreateSlackAssistantBridgeOptions, "feedback">, Omit<CreateSlackBoltAppOptions, "app" | "path" | "botToken" | "signingSecret" | "auth"> {
|
|
47
|
-
/**
|
|
48
|
-
* Slack bot token (`xoxb-...`).
|
|
49
|
-
* @default process.env.SLACK_BOT_TOKEN
|
|
50
|
-
*/
|
|
51
|
-
botToken?: string;
|
|
52
|
-
/**
|
|
53
|
-
* Slack signing secret used to verify incoming webhook requests.
|
|
54
|
-
* @default process.env.SLACK_SIGNING_SECRET
|
|
55
|
-
*/
|
|
56
|
-
signingSecret?: string;
|
|
57
|
-
/**
|
|
58
|
-
* Structured direct-mode auth config (single-workspace, OAuth, custom).
|
|
59
|
-
* Defaults to `botToken` / `SLACK_BOT_TOKEN` single-workspace mode.
|
|
60
|
-
*/
|
|
61
|
-
auth?: SlackDirectAuthOptions;
|
|
62
|
-
/**
|
|
63
|
-
* Slack Events API callback path handled by Bolt.
|
|
64
|
-
*
|
|
65
|
-
* @default "/slack/events"
|
|
66
|
-
*/
|
|
67
|
-
path?: string;
|
|
68
|
-
/**
|
|
69
|
-
* Port to listen on. Set to `null` to skip `app.listen()` — caller manages
|
|
70
|
-
* the server.
|
|
71
|
-
*
|
|
72
|
-
* @default process.env.PORT || 3000
|
|
73
|
-
*/
|
|
74
|
-
port?: number | null;
|
|
75
|
-
/** Optional host passed to `app.listen(port, host)`. */
|
|
76
|
-
host?: string;
|
|
77
|
-
/**
|
|
78
|
-
* Pre-existing Express app. If not provided, a new one is created and the
|
|
79
|
-
* helper calls `app.listen()` itself.
|
|
80
|
-
*/
|
|
81
|
-
app?: Application;
|
|
82
|
-
/**
|
|
83
|
-
* Feedback config — block + handler. Pass `false` to omit feedback buttons
|
|
84
|
-
* entirely. Pass an object to override action ids, button labels, or the
|
|
85
|
-
* feedback handler. Pass a function as `onFeedback` for the most common
|
|
86
|
-
* case where only the handler differs.
|
|
87
|
-
*/
|
|
88
|
-
feedback?: SlackAssistantFeedbackConfig | false;
|
|
89
|
-
/**
|
|
90
|
-
* Convenience shorthand: `onFeedback: handler` is equivalent to
|
|
91
|
-
* `feedback: { onFeedback: handler }`. Ignored if `feedback` is set.
|
|
92
|
-
*/
|
|
93
|
-
onFeedback?: SlackFeedbackHandler;
|
|
94
|
-
}
|
|
95
|
-
interface MountSlackAssistantAgentResult {
|
|
96
|
-
app: Application;
|
|
97
|
-
boltApp: App;
|
|
98
|
-
receiver: ExpressReceiver;
|
|
99
|
-
authMode: SlackDirectAuthMode;
|
|
100
|
-
routePath: string;
|
|
101
|
-
bridge: SlackAssistantBridge;
|
|
102
|
-
server?: Server;
|
|
103
|
-
}
|
|
104
|
-
declare function mountSlackAssistantAgent(options: MountSlackAssistantAgentOptions): Promise<MountSlackAssistantAgentResult>;
|
|
105
|
-
|
|
106
|
-
export { type MountSlackAssistantAgentOptions, type MountSlackAssistantAgentResult, mountSlackAssistantAgent };
|
package/dist/express.d.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import * as _slack_bolt from '@slack/bolt';
|
|
2
|
-
import { Server } from 'node:http';
|
|
3
|
-
import { AgentTurnSource } from '@cuylabs/agent-core';
|
|
4
|
-
import { Application } from 'express';
|
|
5
|
-
import { c as createSlackChannelAdapter } from './adapter-vbqtraAr.js';
|
|
6
|
-
import { a as SlackChannelOptions } from './types-BeGPexio.js';
|
|
7
|
-
import { CreateSlackBoltAppOptions } from '@cuylabs/channel-slack/transports/http';
|
|
8
|
-
import { SlackDirectAuthOptions, SlackDirectAuthMode } from '@cuylabs/channel-slack/auth';
|
|
9
|
-
import '@cuylabs/channel-slack/core';
|
|
10
|
-
import './options-CGUfVStV.js';
|
|
11
|
-
import './artifacts/index.js';
|
|
12
|
-
import '@cuylabs/channel-slack/artifacts';
|
|
13
|
-
import './interactive-BigrPKnu.js';
|
|
14
|
-
import '@cuylabs/channel-slack/interactive';
|
|
15
|
-
|
|
16
|
-
interface MountSlackAgentOptions extends Omit<SlackChannelOptions, "agent" | "source">, Omit<CreateSlackBoltAppOptions, "app" | "path" | "botToken" | "signingSecret" | "auth"> {
|
|
17
|
-
/**
|
|
18
|
-
* Slack bot token (`xoxb-...`).
|
|
19
|
-
* @default process.env.SLACK_BOT_TOKEN
|
|
20
|
-
*/
|
|
21
|
-
botToken?: string;
|
|
22
|
-
/**
|
|
23
|
-
* Slack signing secret used to verify incoming webhook requests.
|
|
24
|
-
* @default process.env.SLACK_SIGNING_SECRET
|
|
25
|
-
*/
|
|
26
|
-
signingSecret?: string;
|
|
27
|
-
/**
|
|
28
|
-
* Structured direct-mode auth config.
|
|
29
|
-
*
|
|
30
|
-
* Use this for:
|
|
31
|
-
* - multi-workspace OAuth installs
|
|
32
|
-
* - custom Bolt authorize callbacks
|
|
33
|
-
*
|
|
34
|
-
* When omitted, `mountSlackAgent()` defaults to single-workspace mode
|
|
35
|
-
* using `botToken` / `SLACK_BOT_TOKEN`.
|
|
36
|
-
*/
|
|
37
|
-
auth?: SlackDirectAuthOptions;
|
|
38
|
-
/**
|
|
39
|
-
* Exact Slack Events API callback path handled by Bolt.
|
|
40
|
-
*
|
|
41
|
-
* This becomes the request URL you configure in the Slack app:
|
|
42
|
-
* `https://<your-host>${path}`.
|
|
43
|
-
*
|
|
44
|
-
* @default "/slack/events"
|
|
45
|
-
*/
|
|
46
|
-
path?: string;
|
|
47
|
-
/**
|
|
48
|
-
* Port to listen on.
|
|
49
|
-
* Set to `null` to skip `app.listen()` — caller manages the server.
|
|
50
|
-
* @default process.env.PORT || 3000
|
|
51
|
-
*/
|
|
52
|
-
port?: number | null;
|
|
53
|
-
/**
|
|
54
|
-
* Optional host/interface passed to `app.listen(port, host)`.
|
|
55
|
-
*/
|
|
56
|
-
host?: string;
|
|
57
|
-
/**
|
|
58
|
-
* Pre-existing Express app. If not provided, a new one is created.
|
|
59
|
-
*
|
|
60
|
-
* When provided, the Bolt receiver router is mounted on `path` and no
|
|
61
|
-
* internal `app.listen()` is called (the caller must start the server).
|
|
62
|
-
*/
|
|
63
|
-
app?: Application;
|
|
64
|
-
}
|
|
65
|
-
interface MountSlackAgentResult {
|
|
66
|
-
/** The Express application */
|
|
67
|
-
app: Application;
|
|
68
|
-
/** The Bolt App instance */
|
|
69
|
-
boltApp: _slack_bolt.App;
|
|
70
|
-
/** The Bolt ExpressReceiver */
|
|
71
|
-
receiver: _slack_bolt.ExpressReceiver;
|
|
72
|
-
/** Resolved direct Slack auth mode */
|
|
73
|
-
authMode: SlackDirectAuthMode;
|
|
74
|
-
/** Exact Slack callback path handled by Bolt */
|
|
75
|
-
routePath: string;
|
|
76
|
-
/** The Slack channel adapter */
|
|
77
|
-
channelAdapter: ReturnType<typeof createSlackChannelAdapter>;
|
|
78
|
-
/** The Node HTTP server when `listen()` was started internally */
|
|
79
|
-
server?: Server;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Mount an agent-core-compatible turn source as a Slack bot on an Express app.
|
|
83
|
-
*
|
|
84
|
-
* This is the simplest way to deploy an agent-core agent to Slack. It handles:
|
|
85
|
-
* 1. Creating a Bolt `ExpressReceiver` with request verification.
|
|
86
|
-
* 2. Creating a Bolt `App` using one of the supported direct auth modes.
|
|
87
|
-
* 3. Creating the Slack channel adapter and mounting it on the Bolt App.
|
|
88
|
-
* 4. Registering `receiver.router` on the Express app.
|
|
89
|
-
* 5. Optionally starting the server.
|
|
90
|
-
*
|
|
91
|
-
* Single-workspace mode environment variables (if not passed explicitly):
|
|
92
|
-
* - `SLACK_BOT_TOKEN` — Bot OAuth token (`xoxb-...`)
|
|
93
|
-
* - `SLACK_SIGNING_SECRET` — App signing secret for request verification
|
|
94
|
-
*
|
|
95
|
-
* OAuth mode environment variables:
|
|
96
|
-
* - `SLACK_SIGNING_SECRET`
|
|
97
|
-
* - `SLACK_CLIENT_ID`
|
|
98
|
-
* - `SLACK_CLIENT_SECRET`
|
|
99
|
-
* - `SLACK_STATE_SECRET` unless you provide a custom state store
|
|
100
|
-
*/
|
|
101
|
-
declare function mountSlackAgent(source: AgentTurnSource, options?: MountSlackAgentOptions): Promise<MountSlackAgentResult>;
|
|
102
|
-
|
|
103
|
-
export { type MountSlackAgentOptions, type MountSlackAgentResult, mountSlackAgent };
|