@inkeep/agents-work-apps 0.50.0 → 0.50.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/rolldown_runtime.js +32 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.js +1 -0
- package/dist/github/mcp/auth.d.ts +2 -2
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/mcp/schemas.d.ts +1 -1
- package/dist/github/routes/tokenExchange.d.ts +2 -2
- package/dist/github/routes/webhooks.d.ts +2 -2
- package/dist/node_modules/.pnpm/@slack_logger@4.0.0/node_modules/@slack/logger/dist/index.js +89 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/package.js +85 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/SlackWebSocket.js +223 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/SocketModeClient.js +367 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/UnrecoverableSocketModeStartError.js +20 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/errors.js +71 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/index.js +44 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/logger.js +32 -0
- package/dist/node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.js +241 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/index.js +23 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/buffer-util.js +107 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js +29 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/event-target.js +226 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/extension.js +150 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/limiter.js +57 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/permessage-deflate.js +342 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/receiver.js +457 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/sender.js +505 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/stream.js +123 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/subprotocol.js +46 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js +203 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket-server.js +385 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js +985 -0
- package/dist/slack/dispatcher.d.ts +16 -0
- package/dist/slack/dispatcher.js +335 -0
- package/dist/slack/i18n/strings.d.ts +5 -5
- package/dist/slack/i18n/strings.js +9 -9
- package/dist/slack/index.d.ts +3 -1
- package/dist/slack/index.js +4 -2
- package/dist/slack/middleware/permissions.js +120 -107
- package/dist/slack/routes/events.js +10 -328
- package/dist/slack/routes/oauth.js +6 -3
- package/dist/slack/routes/users.js +12 -6
- package/dist/slack/routes/workspaces.js +31 -36
- package/dist/slack/services/blocks/index.js +7 -11
- package/dist/slack/services/commands/index.js +2 -2
- package/dist/slack/services/dev-config.d.ts +23 -0
- package/dist/slack/services/dev-config.js +91 -0
- package/dist/slack/services/events/app-mention.js +6 -17
- package/dist/slack/services/events/modal-submission.js +5 -5
- package/dist/slack/services/events/streaming.js +4 -3
- package/dist/slack/services/events/utils.js +8 -8
- package/dist/slack/services/index.js +1 -1
- package/dist/slack/services/modals.js +4 -4
- package/dist/slack/services/nango.d.ts +2 -0
- package/dist/slack/services/nango.js +84 -2
- package/dist/slack/socket-mode.d.ts +4 -0
- package/dist/slack/socket-mode.js +130 -0
- package/package.json +3 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SlackOutcome } from "./tracer.js";
|
|
2
|
+
|
|
3
|
+
//#region src/slack/dispatcher.d.ts
|
|
4
|
+
interface SlackEventDispatchResult {
|
|
5
|
+
outcome: SlackOutcome;
|
|
6
|
+
response?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
interface DispatchOptions {
|
|
9
|
+
registerBackgroundWork: (work: Promise<unknown>) => void;
|
|
10
|
+
}
|
|
11
|
+
declare function dispatchSlackEvent(eventType: string, payload: Record<string, unknown>, options: DispatchOptions, span: {
|
|
12
|
+
setAttribute: (key: string, value: string | boolean | number) => void;
|
|
13
|
+
updateName: (name: string) => void;
|
|
14
|
+
}): Promise<SlackEventDispatchResult>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { DispatchOptions, SlackEventDispatchResult, dispatchSlackEvent };
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { getLogger } from "../logger.js";
|
|
2
|
+
import { findWorkspaceConnectionByTeamId } from "./services/nango.js";
|
|
3
|
+
import { getSlackClient } from "./services/client.js";
|
|
4
|
+
import { sendResponseUrlMessage } from "./services/events/utils.js";
|
|
5
|
+
import { SLACK_SPAN_KEYS } from "./tracer.js";
|
|
6
|
+
import { handleAppMention } from "./services/events/app-mention.js";
|
|
7
|
+
import { handleMessageShortcut, handleOpenAgentSelectorModal, handleOpenFollowUpModal } from "./services/events/block-actions.js";
|
|
8
|
+
import { handleFollowUpSubmission, handleModalSubmission } from "./services/events/modal-submission.js";
|
|
9
|
+
import "./services/events/index.js";
|
|
10
|
+
import "./services/index.js";
|
|
11
|
+
import { flushTraces } from "@inkeep/agents-core";
|
|
12
|
+
|
|
13
|
+
//#region src/slack/dispatcher.ts
|
|
14
|
+
const logger = getLogger("slack-dispatcher");
|
|
15
|
+
async function dispatchSlackEvent(eventType, payload, options, span) {
|
|
16
|
+
const { registerBackgroundWork } = options;
|
|
17
|
+
let outcome = "ignored_unknown_event";
|
|
18
|
+
if (eventType === "event_callback") {
|
|
19
|
+
const teamId = payload.team_id;
|
|
20
|
+
const event = payload.event;
|
|
21
|
+
const innerEventType = event?.type || "unknown";
|
|
22
|
+
span.setAttribute(SLACK_SPAN_KEYS.INNER_EVENT_TYPE, innerEventType);
|
|
23
|
+
if (teamId) span.setAttribute(SLACK_SPAN_KEYS.TEAM_ID, teamId);
|
|
24
|
+
if (event?.channel) span.setAttribute(SLACK_SPAN_KEYS.CHANNEL_ID, event.channel);
|
|
25
|
+
if (event?.user) span.setAttribute(SLACK_SPAN_KEYS.USER_ID, event.user);
|
|
26
|
+
if (event?.bot_id || event?.subtype === "bot_message") {
|
|
27
|
+
outcome = "ignored_bot_message";
|
|
28
|
+
span.setAttribute(SLACK_SPAN_KEYS.IS_BOT_MESSAGE, true);
|
|
29
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
30
|
+
logger.info({
|
|
31
|
+
botId: event.bot_id,
|
|
32
|
+
subtype: event?.subtype,
|
|
33
|
+
teamId,
|
|
34
|
+
innerEventType
|
|
35
|
+
}, "Ignoring bot message");
|
|
36
|
+
return { outcome };
|
|
37
|
+
}
|
|
38
|
+
if (event?.type === "app_mention" && event.channel && event.user && teamId) {
|
|
39
|
+
outcome = "handled";
|
|
40
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
41
|
+
const question = (event.text || "").replace(/<@[A-Z0-9]+>/g, "").trim();
|
|
42
|
+
span.setAttribute(SLACK_SPAN_KEYS.HAS_QUERY, question.length > 0);
|
|
43
|
+
if (event.thread_ts) span.setAttribute(SLACK_SPAN_KEYS.THREAD_TS, event.thread_ts);
|
|
44
|
+
if (event.ts) span.setAttribute(SLACK_SPAN_KEYS.MESSAGE_TS, event.ts);
|
|
45
|
+
logger.info({
|
|
46
|
+
userId: event.user,
|
|
47
|
+
channel: event.channel,
|
|
48
|
+
teamId,
|
|
49
|
+
hasQuery: question.length > 0
|
|
50
|
+
}, "Handling event: app_mention");
|
|
51
|
+
const dispatchedAt = Date.now();
|
|
52
|
+
registerBackgroundWork(handleAppMention({
|
|
53
|
+
slackUserId: event.user,
|
|
54
|
+
channel: event.channel,
|
|
55
|
+
text: question,
|
|
56
|
+
threadTs: event.thread_ts || event.ts || "",
|
|
57
|
+
messageTs: event.ts || "",
|
|
58
|
+
teamId,
|
|
59
|
+
dispatchedAt
|
|
60
|
+
}).catch((err) => {
|
|
61
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
62
|
+
const errorStack = err instanceof Error ? err.stack : void 0;
|
|
63
|
+
logger.error({
|
|
64
|
+
errorMessage,
|
|
65
|
+
errorStack
|
|
66
|
+
}, "Failed to handle app mention (outer catch)");
|
|
67
|
+
}).finally(() => flushTraces()));
|
|
68
|
+
logger.info({
|
|
69
|
+
teamId,
|
|
70
|
+
channel: event.channel,
|
|
71
|
+
dispatchedAt
|
|
72
|
+
}, "app_mention work registered");
|
|
73
|
+
} else {
|
|
74
|
+
outcome = "ignored_unknown_event";
|
|
75
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
76
|
+
logger.info({
|
|
77
|
+
innerEventType,
|
|
78
|
+
teamId
|
|
79
|
+
}, `Ignoring unhandled event_callback: ${innerEventType}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (eventType === "block_actions" || eventType === "interactive_message") {
|
|
83
|
+
const actions = payload.actions;
|
|
84
|
+
const teamId = payload.team?.id;
|
|
85
|
+
const responseUrl = payload.response_url;
|
|
86
|
+
const triggerId = payload.trigger_id;
|
|
87
|
+
const actionIds = actions?.map((a) => a.action_id) || [];
|
|
88
|
+
if (teamId) span.setAttribute(SLACK_SPAN_KEYS.TEAM_ID, teamId);
|
|
89
|
+
span.setAttribute(SLACK_SPAN_KEYS.ACTION_IDS, actionIds.join(","));
|
|
90
|
+
if (actions && teamId) {
|
|
91
|
+
let anyHandled = false;
|
|
92
|
+
for (const action of actions) {
|
|
93
|
+
if (action.action_id === "open_agent_selector_modal" && action.value && triggerId) {
|
|
94
|
+
anyHandled = true;
|
|
95
|
+
logger.info({
|
|
96
|
+
teamId,
|
|
97
|
+
actionId: action.action_id
|
|
98
|
+
}, "Handling block_action: open_agent_selector_modal");
|
|
99
|
+
registerBackgroundWork(handleOpenAgentSelectorModal({
|
|
100
|
+
triggerId,
|
|
101
|
+
actionValue: action.value,
|
|
102
|
+
teamId,
|
|
103
|
+
responseUrl: responseUrl || ""
|
|
104
|
+
}).catch(async (err) => {
|
|
105
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
106
|
+
logger.error({
|
|
107
|
+
errorMessage,
|
|
108
|
+
actionId: action.action_id
|
|
109
|
+
}, "Failed to open agent selector modal");
|
|
110
|
+
if (responseUrl) await sendResponseUrlMessage(responseUrl, {
|
|
111
|
+
text: "Sorry, something went wrong while opening the agent selector. Please try again.",
|
|
112
|
+
response_type: "ephemeral"
|
|
113
|
+
}).catch((e) => logger.warn({ error: e }, "Failed to send error notification via response URL"));
|
|
114
|
+
}).finally(() => flushTraces()));
|
|
115
|
+
}
|
|
116
|
+
if (action.action_id === "modal_project_select") {
|
|
117
|
+
anyHandled = true;
|
|
118
|
+
const selectedProjectId = action.selected_option?.value;
|
|
119
|
+
const view = payload.view;
|
|
120
|
+
logger.info({
|
|
121
|
+
teamId,
|
|
122
|
+
actionId: action.action_id,
|
|
123
|
+
selectedProjectId
|
|
124
|
+
}, "Handling block_action: modal_project_select");
|
|
125
|
+
if (selectedProjectId && view?.id) registerBackgroundWork((async () => {
|
|
126
|
+
try {
|
|
127
|
+
const metadata = JSON.parse(view.private_metadata || "{}");
|
|
128
|
+
const tenantId = metadata.tenantId;
|
|
129
|
+
if (!tenantId) {
|
|
130
|
+
logger.warn({ teamId }, "No tenantId in modal metadata — skipping project update");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const workspace = await findWorkspaceConnectionByTeamId(teamId);
|
|
134
|
+
if (!workspace?.botToken) {
|
|
135
|
+
logger.warn({ teamId }, "Workspace found but no botToken — skipping modal project update");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const slackClient = getSlackClient(workspace.botToken);
|
|
139
|
+
const { fetchProjectsForTenant, fetchAgentsForProject } = await import("./services/events/utils.js");
|
|
140
|
+
const { buildAgentSelectorModal, buildMessageShortcutModal } = await import("./services/modals.js");
|
|
141
|
+
const projectList = await fetchProjectsForTenant(tenantId);
|
|
142
|
+
const agentList = await fetchAgentsForProject(tenantId, selectedProjectId);
|
|
143
|
+
const agentOptions = agentList.map((a) => ({
|
|
144
|
+
id: a.id,
|
|
145
|
+
name: a.name,
|
|
146
|
+
projectId: a.projectId,
|
|
147
|
+
projectName: a.projectName || a.projectId
|
|
148
|
+
}));
|
|
149
|
+
const modal = metadata.messageContext ? buildMessageShortcutModal({
|
|
150
|
+
projects: projectList,
|
|
151
|
+
agents: agentOptions,
|
|
152
|
+
metadata,
|
|
153
|
+
selectedProjectId,
|
|
154
|
+
messageContext: metadata.messageContext
|
|
155
|
+
}) : buildAgentSelectorModal({
|
|
156
|
+
projects: projectList,
|
|
157
|
+
agents: agentOptions,
|
|
158
|
+
metadata,
|
|
159
|
+
selectedProjectId
|
|
160
|
+
});
|
|
161
|
+
await slackClient.views.update({
|
|
162
|
+
view_id: view.id,
|
|
163
|
+
view: modal
|
|
164
|
+
});
|
|
165
|
+
logger.debug({
|
|
166
|
+
selectedProjectId,
|
|
167
|
+
agentCount: agentList.length
|
|
168
|
+
}, "Updated modal with agents for selected project");
|
|
169
|
+
} catch (err) {
|
|
170
|
+
logger.error({
|
|
171
|
+
err,
|
|
172
|
+
selectedProjectId
|
|
173
|
+
}, "Failed to update modal on project change");
|
|
174
|
+
} finally {
|
|
175
|
+
await flushTraces();
|
|
176
|
+
}
|
|
177
|
+
})());
|
|
178
|
+
}
|
|
179
|
+
if (action.action_id === "open_follow_up_modal" && action.value && triggerId) {
|
|
180
|
+
anyHandled = true;
|
|
181
|
+
logger.info({
|
|
182
|
+
teamId,
|
|
183
|
+
actionId: action.action_id
|
|
184
|
+
}, "Handling block_action: open_follow_up_modal");
|
|
185
|
+
registerBackgroundWork(handleOpenFollowUpModal({
|
|
186
|
+
triggerId,
|
|
187
|
+
actionValue: action.value,
|
|
188
|
+
teamId,
|
|
189
|
+
responseUrl: responseUrl || void 0
|
|
190
|
+
}).catch(async (err) => {
|
|
191
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
192
|
+
logger.error({
|
|
193
|
+
errorMessage,
|
|
194
|
+
actionId: action.action_id
|
|
195
|
+
}, "Failed to open follow-up modal");
|
|
196
|
+
if (responseUrl) await sendResponseUrlMessage(responseUrl, {
|
|
197
|
+
text: "Sorry, something went wrong while opening the follow-up form. Please try again.",
|
|
198
|
+
response_type: "ephemeral"
|
|
199
|
+
}).catch((e) => logger.warn({ error: e }, "Failed to send error notification via response URL"));
|
|
200
|
+
}).finally(() => flushTraces()));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
outcome = anyHandled ? "handled" : "ignored_no_action_match";
|
|
204
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
205
|
+
if (!anyHandled) logger.info({
|
|
206
|
+
teamId,
|
|
207
|
+
actionIds,
|
|
208
|
+
eventType
|
|
209
|
+
}, "Ignoring block_actions: no matching action handlers");
|
|
210
|
+
} else {
|
|
211
|
+
outcome = "ignored_no_action_match";
|
|
212
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
213
|
+
logger.info({
|
|
214
|
+
teamId,
|
|
215
|
+
eventType,
|
|
216
|
+
hasActions: Boolean(actions)
|
|
217
|
+
}, "Ignoring block_actions: missing actions or teamId");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (eventType === "message_action") {
|
|
221
|
+
const callbackId = payload.callback_id;
|
|
222
|
+
span.setAttribute(SLACK_SPAN_KEYS.CALLBACK_ID, callbackId || "unknown");
|
|
223
|
+
if (callbackId === "ask_agent_shortcut") {
|
|
224
|
+
const triggerId = payload.trigger_id;
|
|
225
|
+
const teamId = payload.team?.id;
|
|
226
|
+
const channelId = payload.channel?.id;
|
|
227
|
+
const userId = payload.user?.id;
|
|
228
|
+
const message = payload.message;
|
|
229
|
+
const responseUrl = payload.response_url;
|
|
230
|
+
if (teamId) span.setAttribute(SLACK_SPAN_KEYS.TEAM_ID, teamId);
|
|
231
|
+
if (channelId) span.setAttribute(SLACK_SPAN_KEYS.CHANNEL_ID, channelId);
|
|
232
|
+
if (userId) span.setAttribute(SLACK_SPAN_KEYS.USER_ID, userId);
|
|
233
|
+
if (triggerId && teamId && channelId && userId && message?.ts) {
|
|
234
|
+
outcome = "handled";
|
|
235
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
236
|
+
logger.info({
|
|
237
|
+
teamId,
|
|
238
|
+
channelId,
|
|
239
|
+
userId,
|
|
240
|
+
callbackId
|
|
241
|
+
}, "Handling message_action: ask_agent_shortcut");
|
|
242
|
+
registerBackgroundWork(handleMessageShortcut({
|
|
243
|
+
triggerId,
|
|
244
|
+
teamId,
|
|
245
|
+
channelId,
|
|
246
|
+
userId,
|
|
247
|
+
messageTs: message.ts,
|
|
248
|
+
messageText: message.text || "",
|
|
249
|
+
threadTs: message.thread_ts,
|
|
250
|
+
responseUrl
|
|
251
|
+
}).catch((err) => {
|
|
252
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
253
|
+
logger.error({
|
|
254
|
+
errorMessage,
|
|
255
|
+
callbackId
|
|
256
|
+
}, "Failed to handle message shortcut");
|
|
257
|
+
}).finally(() => flushTraces()));
|
|
258
|
+
} else {
|
|
259
|
+
outcome = "ignored_unknown_event";
|
|
260
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
261
|
+
logger.info({
|
|
262
|
+
teamId,
|
|
263
|
+
channelId,
|
|
264
|
+
userId,
|
|
265
|
+
callbackId,
|
|
266
|
+
hasTriggerId: Boolean(triggerId)
|
|
267
|
+
}, "Ignoring message_action: missing required fields");
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
outcome = "ignored_unknown_event";
|
|
271
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
272
|
+
logger.info({ callbackId }, `Ignoring unhandled message_action: ${callbackId}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (eventType === "view_submission") {
|
|
276
|
+
const callbackId = payload.view?.callback_id;
|
|
277
|
+
span.setAttribute(SLACK_SPAN_KEYS.CALLBACK_ID, callbackId || "unknown");
|
|
278
|
+
if (callbackId === "agent_selector_modal") {
|
|
279
|
+
const view = payload.view;
|
|
280
|
+
const values = view.state?.values || {};
|
|
281
|
+
const agentSelectEntry = Object.entries(values).find(([, block]) => block.agent_select);
|
|
282
|
+
const agentSelectBlockId = agentSelectEntry?.[0];
|
|
283
|
+
const agentSelect = agentSelectEntry ? agentSelectEntry[1].agent_select : void 0;
|
|
284
|
+
if (!agentSelect?.selected_option?.value || agentSelect.selected_option.value === "none") {
|
|
285
|
+
outcome = "validation_error";
|
|
286
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
287
|
+
logger.info({ callbackId }, "Rejecting view_submission: no agent selected");
|
|
288
|
+
return {
|
|
289
|
+
outcome,
|
|
290
|
+
response: {
|
|
291
|
+
response_action: "errors",
|
|
292
|
+
errors: { [agentSelectBlockId || "agent_select_block"]: "Please select an agent. If none are available, add agents to this project in the dashboard." }
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
outcome = "handled";
|
|
297
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
298
|
+
logger.info({ callbackId }, "Handling view_submission: agent_selector_modal");
|
|
299
|
+
registerBackgroundWork(handleModalSubmission(view).catch((err) => {
|
|
300
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
301
|
+
logger.error({
|
|
302
|
+
errorMessage,
|
|
303
|
+
callbackId
|
|
304
|
+
}, "Failed to handle modal submission");
|
|
305
|
+
}).finally(() => flushTraces()));
|
|
306
|
+
return { outcome };
|
|
307
|
+
}
|
|
308
|
+
if (callbackId === "follow_up_modal") {
|
|
309
|
+
const view = payload.view;
|
|
310
|
+
outcome = "handled";
|
|
311
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
312
|
+
logger.info({ callbackId }, "Handling view_submission: follow_up_modal");
|
|
313
|
+
registerBackgroundWork(handleFollowUpSubmission(view).catch((err) => {
|
|
314
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
315
|
+
logger.error({
|
|
316
|
+
errorMessage,
|
|
317
|
+
callbackId
|
|
318
|
+
}, "Failed to handle follow-up submission");
|
|
319
|
+
}).finally(() => flushTraces()));
|
|
320
|
+
return { outcome };
|
|
321
|
+
}
|
|
322
|
+
outcome = "ignored_unknown_event";
|
|
323
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
324
|
+
logger.info({ callbackId }, `Ignoring unhandled view_submission: ${callbackId}`);
|
|
325
|
+
}
|
|
326
|
+
if (eventType !== "event_callback" && eventType !== "block_actions" && eventType !== "interactive_message" && eventType !== "message_action" && eventType !== "view_submission") {
|
|
327
|
+
outcome = "ignored_unknown_event";
|
|
328
|
+
span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, outcome);
|
|
329
|
+
logger.info({ eventType }, `Ignoring unhandled Slack event type: ${eventType}`);
|
|
330
|
+
}
|
|
331
|
+
return { outcome };
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
//#endregion
|
|
335
|
+
export { dispatchSlackEvent };
|
|
@@ -11,7 +11,7 @@ declare const SlackStrings: {
|
|
|
11
11
|
readonly send: "Send";
|
|
12
12
|
readonly followUp: "Follow Up";
|
|
13
13
|
readonly cancel: "Cancel";
|
|
14
|
-
readonly openDashboard: "
|
|
14
|
+
readonly openDashboard: "Open Dashboard";
|
|
15
15
|
};
|
|
16
16
|
readonly modals: {
|
|
17
17
|
readonly triggerAgent: "Trigger Agent";
|
|
@@ -46,18 +46,18 @@ declare const SlackStrings: {
|
|
|
46
46
|
readonly status: {
|
|
47
47
|
readonly thinking: (agentName: string) => string;
|
|
48
48
|
readonly noAgentsAvailable: "No agents available";
|
|
49
|
-
readonly noProjectsConfigured: "
|
|
49
|
+
readonly noProjectsConfigured: "No projects configured. Set up projects in the dashboard.";
|
|
50
50
|
};
|
|
51
51
|
readonly errors: {
|
|
52
|
-
readonly generic: "
|
|
53
|
-
readonly failedToOpenSelector: "
|
|
52
|
+
readonly generic: "Something went wrong. Please try again.";
|
|
53
|
+
readonly failedToOpenSelector: "Failed to open agent selector. Please try again.";
|
|
54
54
|
};
|
|
55
55
|
readonly help: {
|
|
56
56
|
readonly title: "Inkeep — How to Use";
|
|
57
57
|
readonly publicSection: string;
|
|
58
58
|
readonly privateSection: string;
|
|
59
59
|
readonly otherCommands: string;
|
|
60
|
-
readonly docsLink: "
|
|
60
|
+
readonly docsLink: "<https://docs.inkeep.com/talk-to-your-agents/slack/overview|Learn more>";
|
|
61
61
|
};
|
|
62
62
|
readonly messageContext: {
|
|
63
63
|
readonly label: "Message:";
|
|
@@ -11,7 +11,7 @@ const SlackStrings = {
|
|
|
11
11
|
send: "Send",
|
|
12
12
|
followUp: "Follow Up",
|
|
13
13
|
cancel: "Cancel",
|
|
14
|
-
openDashboard: "
|
|
14
|
+
openDashboard: "Open Dashboard"
|
|
15
15
|
},
|
|
16
16
|
modals: {
|
|
17
17
|
triggerAgent: "Trigger Agent",
|
|
@@ -38,22 +38,22 @@ const SlackStrings = {
|
|
|
38
38
|
poweredBy: (agentName) => `Powered by *${agentName}* via Inkeep`,
|
|
39
39
|
privateResponse: "_Private response_"
|
|
40
40
|
},
|
|
41
|
-
usage: { mentionEmpty: "*
|
|
41
|
+
usage: { mentionEmpty: "*Include a message to use your Inkeep agent:*\n\n• `@Inkeep <message>` — Message the default agent (reply appears in a thread)\n• `@Inkeep <message>` in a thread — Includes thread as context\n• `@Inkeep` in a thread — Uses the full thread as context\n\nUse `/inkeep help` for all available commands." },
|
|
42
42
|
status: {
|
|
43
43
|
thinking: (agentName) => `_${agentName} is thinking..._`,
|
|
44
44
|
noAgentsAvailable: "No agents available",
|
|
45
|
-
noProjectsConfigured: "
|
|
45
|
+
noProjectsConfigured: "No projects configured. Set up projects in the dashboard."
|
|
46
46
|
},
|
|
47
47
|
errors: {
|
|
48
|
-
generic: "
|
|
49
|
-
failedToOpenSelector: "
|
|
48
|
+
generic: "Something went wrong. Please try again.",
|
|
49
|
+
failedToOpenSelector: "Failed to open agent selector. Please try again."
|
|
50
50
|
},
|
|
51
51
|
help: {
|
|
52
52
|
title: "Inkeep — How to Use",
|
|
53
|
-
publicSection: "
|
|
54
|
-
privateSection: "
|
|
55
|
-
otherCommands: "
|
|
56
|
-
docsLink: "
|
|
53
|
+
publicSection: "*Public* — visible to everyone in the channel\n\n• `@Inkeep <message>` — Message the default agent in this channel\n• `@Inkeep <message>` in a thread — Includes thread as context\n• `@Inkeep` in a thread — Uses the full thread as context",
|
|
54
|
+
privateSection: "*Private* — only visible to you\n\n• `/inkeep <message>` — Message the default agent in this channel\n• `/inkeep` — Open the agent picker to choose an agent and write a prompt",
|
|
55
|
+
otherCommands: "*Other Commands*\n\n• `/inkeep status` — Check your connection and agent config\n• `/inkeep link` / `/inkeep unlink` — Manage account connection\n• `/inkeep help` — Show this message",
|
|
56
|
+
docsLink: "<https://docs.inkeep.com/talk-to-your-agents/slack/overview|Learn more>"
|
|
57
57
|
},
|
|
58
58
|
messageContext: { label: "Message:" }
|
|
59
59
|
};
|
package/dist/slack/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { DispatchOptions, SlackEventDispatchResult, dispatchSlackEvent } from "./dispatcher.js";
|
|
1
2
|
import { ManageAppVariables, WorkAppsVariables } from "./types.js";
|
|
2
3
|
import { DefaultAgentConfig, SlackWorkspaceConnection, WorkspaceInstallData, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setWorkspaceDefaultAgent, storeWorkspaceInstallation, updateConnectionMetadata } from "./services/nango.js";
|
|
3
4
|
import { getChannelAgentConfig, getWorkspaceDefaultAgent } from "./services/events/utils.js";
|
|
4
5
|
import "./services/events/index.js";
|
|
5
6
|
import { getBotTokenForTeam, setBotTokenForTeam } from "./services/workspace-tokens.js";
|
|
6
7
|
import "./routes/oauth.js";
|
|
8
|
+
import { startSocketMode } from "./socket-mode.js";
|
|
7
9
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
8
10
|
|
|
9
11
|
//#region src/slack/index.d.ts
|
|
@@ -15,4 +17,4 @@ declare const slackRoutes: OpenAPIHono<{
|
|
|
15
17
|
Variables: WorkAppsVariables;
|
|
16
18
|
}, {}, "/">;
|
|
17
19
|
//#endregion
|
|
18
|
-
export { DefaultAgentConfig, ManageAppVariables, SlackWorkspaceConnection, WorkAppsVariables, WorkspaceInstallData, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, createSlackRoutes, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setBotTokenForTeam, setWorkspaceDefaultAgent, slackRoutes, storeWorkspaceInstallation, updateConnectionMetadata };
|
|
20
|
+
export { DefaultAgentConfig, type DispatchOptions, ManageAppVariables, type SlackEventDispatchResult, SlackWorkspaceConnection, WorkAppsVariables, WorkspaceInstallData, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, createSlackRoutes, deleteWorkspaceInstallation, dispatchSlackEvent, findWorkspaceConnectionByTeamId, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setBotTokenForTeam, setWorkspaceDefaultAgent, slackRoutes, startSocketMode, storeWorkspaceInstallation, updateConnectionMetadata };
|
package/dist/slack/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setWorkspaceDefaultAgent, storeWorkspaceInstallation, updateConnectionMetadata } from "./services/nango.js";
|
|
2
2
|
import { getChannelAgentConfig, getWorkspaceDefaultAgent } from "./services/events/utils.js";
|
|
3
|
-
import { getBotTokenForTeam, setBotTokenForTeam } from "./services/workspace-tokens.js";
|
|
4
3
|
import "./services/events/index.js";
|
|
4
|
+
import { getBotTokenForTeam, setBotTokenForTeam } from "./services/workspace-tokens.js";
|
|
5
|
+
import { dispatchSlackEvent } from "./dispatcher.js";
|
|
5
6
|
import "./routes/oauth.js";
|
|
6
7
|
import routes_default from "./routes/index.js";
|
|
8
|
+
import { startSocketMode } from "./socket-mode.js";
|
|
7
9
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
8
10
|
|
|
9
11
|
//#region src/slack/index.ts
|
|
@@ -25,4 +27,4 @@ function createSlackRoutes() {
|
|
|
25
27
|
const slackRoutes = createSlackRoutes();
|
|
26
28
|
|
|
27
29
|
//#endregion
|
|
28
|
-
export { clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, createSlackRoutes, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setBotTokenForTeam, setWorkspaceDefaultAgent, slackRoutes, storeWorkspaceInstallation, updateConnectionMetadata };
|
|
30
|
+
export { clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, createSlackRoutes, deleteWorkspaceInstallation, dispatchSlackEvent, findWorkspaceConnectionByTeamId, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setBotTokenForTeam, setWorkspaceDefaultAgent, slackRoutes, startSocketMode, storeWorkspaceInstallation, updateConnectionMetadata };
|