@inkeep/agents-work-apps 0.51.0 → 0.53.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/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/mcp/index.js +120 -25
- package/dist/github/mcp/utils.d.ts +11 -1
- package/dist/github/mcp/utils.js +102 -1
- package/dist/slack/dispatcher.js +10 -1
- package/dist/slack/routes/events.js +2 -2
- package/dist/slack/routes/oauth.js +23 -4
- package/dist/slack/routes/users.js +2 -2
- package/dist/slack/services/agent-resolution.js +66 -18
- package/dist/slack/services/blocks/index.d.ts +35 -1
- package/dist/slack/services/blocks/index.js +161 -22
- package/dist/slack/services/commands/index.js +2 -2
- package/dist/slack/services/events/app-mention.js +1 -1
- package/dist/slack/services/events/block-actions.js +1 -1
- package/dist/slack/services/events/modal-submission.js +14 -7
- package/dist/slack/services/events/streaming.js +133 -8
- package/dist/slack/services/events/utils.d.ts +5 -3
- package/dist/slack/services/events/utils.js +5 -5
- package/dist/slack/services/index.d.ts +2 -2
- package/dist/slack/services/index.js +3 -3
- package/dist/slack/services/modals.d.ts +1 -0
- package/dist/slack/services/modals.js +6 -4
- package/dist/slack/services/nango.js +1 -23
- package/dist/slack/tracer.d.ts +1 -1
- package/package.json +2 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { env } from "../../../env.js";
|
|
2
2
|
import { getLogger } from "../../../logger.js";
|
|
3
|
-
import { buildToolApprovalBlocks, buildToolApprovalExpiredBlocks, createContextBlock } from "../blocks/index.js";
|
|
4
3
|
import { SlackErrorType, classifyError, extractApiErrorMessage, getUserFriendlyErrorMessage } from "./utils.js";
|
|
4
|
+
import { buildCitationsBlock, buildDataArtifactBlocks, buildDataComponentBlocks, buildSummaryBreadcrumbBlock, buildToolApprovalBlocks, buildToolApprovalExpiredBlocks, buildToolOutputErrorBlock, createContextBlock } from "../blocks/index.js";
|
|
5
5
|
import { SLACK_SPAN_KEYS, SLACK_SPAN_NAMES, setSpanWithError, tracer } from "../../tracer.js";
|
|
6
|
-
import { getInProcessFetch } from "@inkeep/agents-core";
|
|
6
|
+
import { getInProcessFetch, retryWithBackoff } from "@inkeep/agents-core";
|
|
7
7
|
|
|
8
8
|
//#region src/slack/services/events/streaming.ts
|
|
9
9
|
/**
|
|
@@ -192,6 +192,14 @@ async function streamAgentResponse(params) {
|
|
|
192
192
|
thread_ts: threadTs
|
|
193
193
|
});
|
|
194
194
|
const pendingApprovalMessages = [];
|
|
195
|
+
const toolCallIdToName = /* @__PURE__ */ new Map();
|
|
196
|
+
const toolCallIdToInput = /* @__PURE__ */ new Map();
|
|
197
|
+
const toolErrors = [];
|
|
198
|
+
const citations = [];
|
|
199
|
+
const summaryLabels = [];
|
|
200
|
+
let richMessageCount = 0;
|
|
201
|
+
let richMessageCapWarned = false;
|
|
202
|
+
const MAX_RICH_MESSAGES = 20;
|
|
195
203
|
try {
|
|
196
204
|
let agentCompleted = false;
|
|
197
205
|
while (true) {
|
|
@@ -214,9 +222,9 @@ async function streamAgentResponse(params) {
|
|
|
214
222
|
continue;
|
|
215
223
|
}
|
|
216
224
|
if (data.type === "tool-approval-request" && conversationId) {
|
|
217
|
-
const toolName = data.toolName || "Tool";
|
|
218
225
|
const toolCallId = data.toolCallId;
|
|
219
|
-
const
|
|
226
|
+
const toolName = toolCallIdToName.get(toolCallId) || "Tool";
|
|
227
|
+
const input = toolCallIdToInput.get(toolCallId);
|
|
220
228
|
const buttonValue = {
|
|
221
229
|
toolCallId,
|
|
222
230
|
conversationId,
|
|
@@ -245,11 +253,118 @@ async function streamAgentResponse(params) {
|
|
|
245
253
|
});
|
|
246
254
|
if (approvalPost?.ts) pendingApprovalMessages.push({
|
|
247
255
|
messageTs: approvalPost.ts,
|
|
248
|
-
toolName
|
|
256
|
+
toolName,
|
|
257
|
+
toolCallId
|
|
249
258
|
});
|
|
250
259
|
clearTimeout(timeoutId);
|
|
251
260
|
continue;
|
|
252
261
|
}
|
|
262
|
+
if (data.type === "tool-input-available" && data.toolCallId && data.toolName) {
|
|
263
|
+
toolCallIdToName.set(String(data.toolCallId), String(data.toolName));
|
|
264
|
+
if (data.input && typeof data.input === "object") toolCallIdToInput.set(String(data.toolCallId), data.input);
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (data.type === "tool-output-denied" && data.toolCallId) {
|
|
268
|
+
const idx = pendingApprovalMessages.findIndex((m) => m.toolCallId === data.toolCallId);
|
|
269
|
+
if (idx !== -1) pendingApprovalMessages.splice(idx, 1);
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (data.type === "tool-output-error" && data.toolCallId) {
|
|
273
|
+
const toolName = toolCallIdToName.get(String(data.toolCallId)) || "Tool";
|
|
274
|
+
toolErrors.push({
|
|
275
|
+
toolName,
|
|
276
|
+
errorText: String(data.errorText || "Unknown error")
|
|
277
|
+
});
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (data.type === "data-component" && data.data && typeof data.data === "object") {
|
|
281
|
+
if (richMessageCount < MAX_RICH_MESSAGES) {
|
|
282
|
+
const { blocks, overflowJson, componentType } = buildDataComponentBlocks({
|
|
283
|
+
id: String(data.id || ""),
|
|
284
|
+
data: data.data
|
|
285
|
+
});
|
|
286
|
+
if (overflowJson) {
|
|
287
|
+
const label = componentType || "data-component";
|
|
288
|
+
await retryWithBackoff(() => slackClient.files.uploadV2({
|
|
289
|
+
channel_id: channel,
|
|
290
|
+
thread_ts: threadTs,
|
|
291
|
+
filename: `${label}.json`,
|
|
292
|
+
content: overflowJson,
|
|
293
|
+
initial_comment: `📊 ${label}`
|
|
294
|
+
}), { label: "slack-file-upload" }).catch((e) => logger.warn({
|
|
295
|
+
error: e,
|
|
296
|
+
channel,
|
|
297
|
+
threadTs,
|
|
298
|
+
agentId,
|
|
299
|
+
componentType: label
|
|
300
|
+
}, "Failed to upload data component file"));
|
|
301
|
+
} else await slackClient.chat.postMessage({
|
|
302
|
+
channel,
|
|
303
|
+
thread_ts: threadTs,
|
|
304
|
+
text: "📊 Data component",
|
|
305
|
+
blocks
|
|
306
|
+
}).catch((e) => logger.warn({ error: e }, "Failed to post data component"));
|
|
307
|
+
richMessageCount++;
|
|
308
|
+
} else if (!richMessageCapWarned) {
|
|
309
|
+
logger.warn({
|
|
310
|
+
channel,
|
|
311
|
+
threadTs,
|
|
312
|
+
agentId,
|
|
313
|
+
eventType: "data-component",
|
|
314
|
+
MAX_RICH_MESSAGES
|
|
315
|
+
}, "MAX_RICH_MESSAGES cap reached — additional rich content will be dropped");
|
|
316
|
+
richMessageCapWarned = true;
|
|
317
|
+
}
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
if (data.type === "data-artifact" && data.data && typeof data.data === "object") {
|
|
321
|
+
const artifactData = data.data;
|
|
322
|
+
if (typeof artifactData.type === "string" && artifactData.type.toLowerCase() === "citation") {
|
|
323
|
+
const summary = artifactData.artifactSummary;
|
|
324
|
+
if (summary?.url && !citations.some((c) => c.url === summary.url)) citations.push({
|
|
325
|
+
title: summary.title,
|
|
326
|
+
url: summary.url
|
|
327
|
+
});
|
|
328
|
+
} else if (richMessageCount < MAX_RICH_MESSAGES) {
|
|
329
|
+
const { blocks, overflowContent, artifactName } = buildDataArtifactBlocks({ data: artifactData });
|
|
330
|
+
if (overflowContent) {
|
|
331
|
+
const label = artifactName || "artifact";
|
|
332
|
+
await retryWithBackoff(() => slackClient.files.uploadV2({
|
|
333
|
+
channel_id: channel,
|
|
334
|
+
thread_ts: threadTs,
|
|
335
|
+
filename: `${label}.md`,
|
|
336
|
+
content: overflowContent,
|
|
337
|
+
initial_comment: `📄 ${label}`
|
|
338
|
+
}), { label: "slack-file-upload" }).catch((e) => logger.warn({
|
|
339
|
+
error: e,
|
|
340
|
+
channel,
|
|
341
|
+
threadTs,
|
|
342
|
+
agentId,
|
|
343
|
+
artifactName: label
|
|
344
|
+
}, "Failed to upload artifact file"));
|
|
345
|
+
} else await slackClient.chat.postMessage({
|
|
346
|
+
channel,
|
|
347
|
+
thread_ts: threadTs,
|
|
348
|
+
text: "📄 Data",
|
|
349
|
+
blocks
|
|
350
|
+
}).catch((e) => logger.warn({ error: e }, "Failed to post data artifact"));
|
|
351
|
+
richMessageCount++;
|
|
352
|
+
} else if (!richMessageCapWarned) {
|
|
353
|
+
logger.warn({
|
|
354
|
+
channel,
|
|
355
|
+
threadTs,
|
|
356
|
+
agentId,
|
|
357
|
+
eventType: "data-artifact",
|
|
358
|
+
MAX_RICH_MESSAGES
|
|
359
|
+
}, "MAX_RICH_MESSAGES cap reached — additional rich content will be dropped");
|
|
360
|
+
richMessageCapWarned = true;
|
|
361
|
+
}
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (data.type === "data-summary" && data.data?.label) {
|
|
365
|
+
summaryLabels.push(String(data.data.label));
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
253
368
|
if (data.type === "text-start" || data.type === "text-end") continue;
|
|
254
369
|
if (data.type === "text-delta" && data.delta) {
|
|
255
370
|
fullText += data.delta;
|
|
@@ -267,9 +382,16 @@ async function streamAgentResponse(params) {
|
|
|
267
382
|
if (agentCompleted) break;
|
|
268
383
|
}
|
|
269
384
|
clearTimeout(timeoutId);
|
|
270
|
-
const
|
|
385
|
+
const stopBlocks = [];
|
|
386
|
+
for (const { toolName, errorText } of toolErrors) stopBlocks.push(buildToolOutputErrorBlock(toolName, errorText));
|
|
387
|
+
if (summaryLabels.length > 0) stopBlocks.push(buildSummaryBreadcrumbBlock(summaryLabels));
|
|
388
|
+
if (citations.length > 0) {
|
|
389
|
+
const citationBlocks = buildCitationsBlock(citations);
|
|
390
|
+
stopBlocks.push(...citationBlocks);
|
|
391
|
+
}
|
|
392
|
+
stopBlocks.push(createContextBlock({ agentName }));
|
|
271
393
|
try {
|
|
272
|
-
await withTimeout(streamer.stop({ blocks:
|
|
394
|
+
await withTimeout(streamer.stop({ blocks: stopBlocks.slice(0, 50) }), CHATSTREAM_OP_TIMEOUT_MS, "streamer.stop");
|
|
273
395
|
} catch (stopError) {
|
|
274
396
|
span.setAttribute(SLACK_SPAN_KEYS.STREAM_FINALIZATION_FAILED, true);
|
|
275
397
|
logger.warn({
|
|
@@ -292,7 +414,10 @@ async function streamAgentResponse(params) {
|
|
|
292
414
|
threadTs,
|
|
293
415
|
responseLength: fullText.length,
|
|
294
416
|
agentId,
|
|
295
|
-
conversationId
|
|
417
|
+
conversationId,
|
|
418
|
+
toolErrorCount: toolErrors.length,
|
|
419
|
+
citationCount: citations.length,
|
|
420
|
+
richMessageCount
|
|
296
421
|
}, "Streaming completed");
|
|
297
422
|
span.end();
|
|
298
423
|
return { success: true };
|
|
@@ -11,9 +11,9 @@ declare function findCachedUserMapping(tenantId: string, slackUserId: string, te
|
|
|
11
11
|
id: string;
|
|
12
12
|
createdAt: string;
|
|
13
13
|
updatedAt: string;
|
|
14
|
-
slackUserId: string;
|
|
15
14
|
tenantId: string;
|
|
16
15
|
clientId: string;
|
|
16
|
+
slackUserId: string;
|
|
17
17
|
slackTeamId: string;
|
|
18
18
|
slackEnterpriseId: string | null;
|
|
19
19
|
inkeepUserId: string;
|
|
@@ -137,8 +137,10 @@ declare function getThreadContext(slackClient: {
|
|
|
137
137
|
}) => Promise<{
|
|
138
138
|
user?: {
|
|
139
139
|
real_name?: string;
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
profile?: {
|
|
141
|
+
display_name?: string;
|
|
142
|
+
email?: string;
|
|
143
|
+
};
|
|
142
144
|
};
|
|
143
145
|
}>;
|
|
144
146
|
};
|
|
@@ -347,15 +347,15 @@ async function getThreadContext(slackClient, channel, threadTs, options = {}) {
|
|
|
347
347
|
try {
|
|
348
348
|
const userInfo = await slackClient.users?.info({ user: userId });
|
|
349
349
|
userNameCache.set(userId, {
|
|
350
|
-
displayName: userInfo?.user?.display_name,
|
|
350
|
+
displayName: userInfo?.user?.profile?.display_name,
|
|
351
351
|
fullName: userInfo?.user?.real_name,
|
|
352
|
-
|
|
352
|
+
email: userInfo?.user?.profile?.email
|
|
353
353
|
});
|
|
354
354
|
} catch {
|
|
355
355
|
userNameCache.set(userId, {
|
|
356
356
|
displayName: void 0,
|
|
357
357
|
fullName: void 0,
|
|
358
|
-
|
|
358
|
+
email: void 0
|
|
359
359
|
});
|
|
360
360
|
}
|
|
361
361
|
}));
|
|
@@ -365,10 +365,10 @@ async function getThreadContext(slackClient, channel, threadTs, options = {}) {
|
|
|
365
365
|
const parts = [`userId: ${userId}`];
|
|
366
366
|
if (info.displayName) parts.push(`"${info.displayName}"`);
|
|
367
367
|
if (info.fullName) parts.push(`"${info.fullName}"`);
|
|
368
|
-
if (info.
|
|
368
|
+
if (info.email) parts.push(info.email);
|
|
369
369
|
userDirectoryLines.push(`- ${parts.join(", ")}`);
|
|
370
370
|
}
|
|
371
|
-
return `${userDirectoryLines.length > 0 ? `Users in this thread (UserId - DisplayName, FullName,
|
|
371
|
+
return `${userDirectoryLines.length > 0 ? `Users in this thread (UserId - DisplayName, FullName, Email):\n${userDirectoryLines.join("\n")}\n\n` : ""}Messages in this thread:\n${messagesToProcess.map((msg, index) => {
|
|
372
372
|
const isBot = !!msg.bot_id;
|
|
373
373
|
const isParent = index === 0;
|
|
374
374
|
let role;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentResolutionParams, ResolvedAgentConfig, getAgentConfigSources, resolveEffectiveAgent } from "./agent-resolution.js";
|
|
2
|
-
import { AgentConfigSources, ContextBlockParams, FollowUpButtonParams, ToolApprovalButtonValue, ToolApprovalButtonValueSchema, buildConversationResponseBlocks, buildFollowUpButton, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, createAlreadyLinkedMessage, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "./blocks/index.js";
|
|
2
|
+
import { AgentConfigSources, ContextBlockParams, FollowUpButtonParams, ToolApprovalButtonValue, ToolApprovalButtonValueSchema, buildCitationsBlock, buildConversationResponseBlocks, buildDataArtifactBlocks, buildDataComponentBlocks, buildFollowUpButton, buildSummaryBreadcrumbBlock, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, buildToolOutputErrorBlock, createAlreadyLinkedMessage, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "./blocks/index.js";
|
|
3
3
|
import { checkUserIsChannelMember, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackTeamInfo, getSlackUserInfo, postMessage, postMessageInThread, revokeSlackToken } from "./client.js";
|
|
4
4
|
import { DefaultAgentConfig, SlackWorkspaceConnection, WorkspaceInstallData, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setWorkspaceDefaultAgent, storeWorkspaceInstallation, updateConnectionMetadata } from "./nango.js";
|
|
5
5
|
import { SlackCommandPayload, SlackCommandResponse } from "./types.js";
|
|
@@ -13,4 +13,4 @@ import { StreamResult, streamAgentResponse } from "./events/streaming.js";
|
|
|
13
13
|
import "./events/index.js";
|
|
14
14
|
import { parseSlackCommandBody, parseSlackEventBody, verifySlackRequest } from "./security.js";
|
|
15
15
|
import { getBotTokenForTeam, setBotTokenForTeam } from "./workspace-tokens.js";
|
|
16
|
-
export { AgentConfigSources, AgentOption, AgentResolutionParams, BuildAgentSelectorModalParams, BuildMessageShortcutModalParams, ContextBlockParams, DefaultAgentConfig, FollowUpButtonParams, FollowUpModalMetadata, InlineSelectorMetadata, ModalMetadata, ResolvedAgentConfig, SlackCommandPayload, SlackCommandResponse, SlackErrorType, SlackWorkspaceConnection, StreamResult, ToolApprovalButtonValue, ToolApprovalButtonValueSchema, WorkspaceInstallData, buildAgentSelectorModal, buildConversationResponseBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createAlreadyLinkedMessage, createConnectSession, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage, deleteWorkspaceInstallation, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, findWorkspaceConnectionByTeamId, generateSlackConversationId, getAgentConfigSources, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackIntegrationId, getSlackNango, getSlackTeamInfo, getSlackUserInfo, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, handleAgentPickerCommand, handleAppMention, handleCommand, handleFollowUpSubmission, handleHelpCommand, handleLinkCommand, handleMessageShortcut, handleModalSubmission, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleQuestionCommand, handleStatusCommand, handleToolApproval, handleUnlinkCommand, listWorkspaceInstallations, markdownToMrkdwn, parseSlackCommandBody, parseSlackEventBody, postMessage, postMessageInThread, resolveEffectiveAgent, revokeSlackToken, sendResponseUrlMessage, setBotTokenForTeam, setWorkspaceDefaultAgent, storeWorkspaceInstallation, streamAgentResponse, updateConnectionMetadata, verifySlackRequest };
|
|
16
|
+
export { AgentConfigSources, AgentOption, AgentResolutionParams, BuildAgentSelectorModalParams, BuildMessageShortcutModalParams, ContextBlockParams, DefaultAgentConfig, FollowUpButtonParams, FollowUpModalMetadata, InlineSelectorMetadata, ModalMetadata, ResolvedAgentConfig, SlackCommandPayload, SlackCommandResponse, SlackErrorType, SlackWorkspaceConnection, StreamResult, ToolApprovalButtonValue, ToolApprovalButtonValueSchema, WorkspaceInstallData, buildAgentSelectorModal, buildCitationsBlock, buildConversationResponseBlocks, buildDataArtifactBlocks, buildDataComponentBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, buildSummaryBreadcrumbBlock, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, buildToolOutputErrorBlock, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createAlreadyLinkedMessage, createConnectSession, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage, deleteWorkspaceInstallation, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, findWorkspaceConnectionByTeamId, generateSlackConversationId, getAgentConfigSources, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackIntegrationId, getSlackNango, getSlackTeamInfo, getSlackUserInfo, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, handleAgentPickerCommand, handleAppMention, handleCommand, handleFollowUpSubmission, handleHelpCommand, handleLinkCommand, handleMessageShortcut, handleModalSubmission, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleQuestionCommand, handleStatusCommand, handleToolApproval, handleUnlinkCommand, listWorkspaceInstallations, markdownToMrkdwn, parseSlackCommandBody, parseSlackEventBody, postMessage, postMessageInThread, resolveEffectiveAgent, revokeSlackToken, sendResponseUrlMessage, setBotTokenForTeam, setWorkspaceDefaultAgent, storeWorkspaceInstallation, streamAgentResponse, updateConnectionMetadata, verifySlackRequest };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setWorkspaceDefaultAgent, storeWorkspaceInstallation, updateConnectionMetadata } from "./nango.js";
|
|
2
|
+
import { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./events/utils.js";
|
|
2
3
|
import { getAgentConfigSources, resolveEffectiveAgent } from "./agent-resolution.js";
|
|
3
|
-
import { ToolApprovalButtonValueSchema, buildConversationResponseBlocks, buildFollowUpButton, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, createAlreadyLinkedMessage, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "./blocks/index.js";
|
|
4
|
+
import { ToolApprovalButtonValueSchema, buildCitationsBlock, buildConversationResponseBlocks, buildDataArtifactBlocks, buildDataComponentBlocks, buildFollowUpButton, buildSummaryBreadcrumbBlock, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, buildToolOutputErrorBlock, createAlreadyLinkedMessage, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "./blocks/index.js";
|
|
4
5
|
import { checkUserIsChannelMember, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackTeamInfo, getSlackUserInfo, postMessage, postMessageInThread, revokeSlackToken } from "./client.js";
|
|
5
|
-
import { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./events/utils.js";
|
|
6
6
|
import { buildAgentSelectorModal, buildFollowUpModal, buildMessageShortcutModal } from "./modals.js";
|
|
7
7
|
import { handleAgentPickerCommand, handleCommand, handleHelpCommand, handleLinkCommand, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand } from "./commands/index.js";
|
|
8
8
|
import { streamAgentResponse } from "./events/streaming.js";
|
|
@@ -13,4 +13,4 @@ import "./events/index.js";
|
|
|
13
13
|
import { parseSlackCommandBody, parseSlackEventBody, verifySlackRequest } from "./security.js";
|
|
14
14
|
import { getBotTokenForTeam, setBotTokenForTeam } from "./workspace-tokens.js";
|
|
15
15
|
|
|
16
|
-
export { SlackErrorType, ToolApprovalButtonValueSchema, buildAgentSelectorModal, buildConversationResponseBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createAlreadyLinkedMessage, createConnectSession, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage, deleteWorkspaceInstallation, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, findWorkspaceConnectionByTeamId, generateSlackConversationId, getAgentConfigSources, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackIntegrationId, getSlackNango, getSlackTeamInfo, getSlackUserInfo, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, handleAgentPickerCommand, handleAppMention, handleCommand, handleFollowUpSubmission, handleHelpCommand, handleLinkCommand, handleMessageShortcut, handleModalSubmission, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleQuestionCommand, handleStatusCommand, handleToolApproval, handleUnlinkCommand, listWorkspaceInstallations, markdownToMrkdwn, parseSlackCommandBody, parseSlackEventBody, postMessage, postMessageInThread, resolveEffectiveAgent, revokeSlackToken, sendResponseUrlMessage, setBotTokenForTeam, setWorkspaceDefaultAgent, storeWorkspaceInstallation, streamAgentResponse, updateConnectionMetadata, verifySlackRequest };
|
|
16
|
+
export { SlackErrorType, ToolApprovalButtonValueSchema, buildAgentSelectorModal, buildCitationsBlock, buildConversationResponseBlocks, buildDataArtifactBlocks, buildDataComponentBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, buildSummaryBreadcrumbBlock, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, buildToolOutputErrorBlock, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createAlreadyLinkedMessage, createConnectSession, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage, deleteWorkspaceInstallation, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, findWorkspaceConnectionByTeamId, generateSlackConversationId, getAgentConfigSources, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackIntegrationId, getSlackNango, getSlackTeamInfo, getSlackUserInfo, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, handleAgentPickerCommand, handleAppMention, handleCommand, handleFollowUpSubmission, handleHelpCommand, handleLinkCommand, handleMessageShortcut, handleModalSubmission, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleQuestionCommand, handleStatusCommand, handleToolApproval, handleUnlinkCommand, listWorkspaceInstallations, markdownToMrkdwn, parseSlackCommandBody, parseSlackEventBody, postMessage, postMessageInThread, resolveEffectiveAgent, revokeSlackToken, sendResponseUrlMessage, setBotTokenForTeam, setWorkspaceDefaultAgent, storeWorkspaceInstallation, streamAgentResponse, updateConnectionMetadata, verifySlackRequest };
|
|
@@ -29,12 +29,13 @@ function buildAgentSelectorModal(params) {
|
|
|
29
29
|
const agentOptions = agents.length > 0 ? agents.map((agent) => ({
|
|
30
30
|
text: {
|
|
31
31
|
type: "plain_text",
|
|
32
|
-
text: agent.name
|
|
32
|
+
text: agent.name ? `${agent.name} (${agent.id})` : agent.id,
|
|
33
33
|
emoji: true
|
|
34
34
|
},
|
|
35
35
|
value: JSON.stringify({
|
|
36
36
|
agentId: agent.id,
|
|
37
|
-
projectId: agent.projectId
|
|
37
|
+
projectId: agent.projectId,
|
|
38
|
+
agentName: agent.name
|
|
38
39
|
})
|
|
39
40
|
})) : [{
|
|
40
41
|
text: {
|
|
@@ -234,12 +235,13 @@ function buildMessageShortcutModal(params) {
|
|
|
234
235
|
const agentOptions = agents.length > 0 ? agents.map((agent) => ({
|
|
235
236
|
text: {
|
|
236
237
|
type: "plain_text",
|
|
237
|
-
text: agent.name
|
|
238
|
+
text: agent.name ? `${agent.name} (${agent.id})` : agent.id,
|
|
238
239
|
emoji: true
|
|
239
240
|
},
|
|
240
241
|
value: JSON.stringify({
|
|
241
242
|
agentId: agent.id,
|
|
242
|
-
projectId: agent.projectId
|
|
243
|
+
projectId: agent.projectId,
|
|
244
|
+
agentName: agent.name
|
|
243
245
|
})
|
|
244
246
|
})) : [{
|
|
245
247
|
text: {
|
|
@@ -2,7 +2,7 @@ import { env } from "../../env.js";
|
|
|
2
2
|
import { getLogger } from "../../logger.js";
|
|
3
3
|
import runDbClient_default from "../../db/runDbClient.js";
|
|
4
4
|
import { getDevDefaultAgent, isSlackDevMode, loadSlackDevConfig, saveSlackDevConfig } from "./dev-config.js";
|
|
5
|
-
import { findWorkAppSlackWorkspaceBySlackTeamId } from "@inkeep/agents-core";
|
|
5
|
+
import { findWorkAppSlackWorkspaceBySlackTeamId, retryWithBackoff } from "@inkeep/agents-core";
|
|
6
6
|
import { Nango } from "@nangohq/node";
|
|
7
7
|
|
|
8
8
|
//#region src/slack/services/nango.ts
|
|
@@ -30,28 +30,6 @@ const workspaceConnectionCache = /* @__PURE__ */ new Map();
|
|
|
30
30
|
const CACHE_TTL_MS = 6e4;
|
|
31
31
|
const logger = getLogger("slack-nango");
|
|
32
32
|
/**
|
|
33
|
-
* Retry a function with exponential backoff for transient failures.
|
|
34
|
-
* Retries on AbortError (timeout) and 5xx HTTP errors.
|
|
35
|
-
*/
|
|
36
|
-
async function retryWithBackoff(fn, maxAttempts = 3) {
|
|
37
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) try {
|
|
38
|
-
return await fn();
|
|
39
|
-
} catch (error) {
|
|
40
|
-
const isTimeout = error.name === "AbortError";
|
|
41
|
-
const isServerError = typeof error.status === "number" && error.status >= 500;
|
|
42
|
-
if (!(isTimeout || isServerError) || attempt === maxAttempts) throw error;
|
|
43
|
-
const delay = Math.min(500 * 2 ** (attempt - 1), 2e3) + Math.random() * 100;
|
|
44
|
-
logger.warn({
|
|
45
|
-
attempt,
|
|
46
|
-
maxAttempts,
|
|
47
|
-
isTimeout,
|
|
48
|
-
delay: Math.round(delay)
|
|
49
|
-
}, "Retrying Nango API call after transient failure");
|
|
50
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
51
|
-
}
|
|
52
|
-
throw new Error("Unreachable");
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
33
|
* Evict expired entries from workspace cache to bound memory.
|
|
56
34
|
*/
|
|
57
35
|
function evictWorkspaceCache() {
|
package/dist/slack/tracer.d.ts
CHANGED
|
@@ -40,6 +40,6 @@ declare const SLACK_SPAN_KEYS: {
|
|
|
40
40
|
readonly AUTHORIZED: "slack.authorized";
|
|
41
41
|
readonly AUTH_SOURCE: "slack.auth_source";
|
|
42
42
|
};
|
|
43
|
-
type SlackOutcome = 'handled' | 'ignored_bot_message' | 'ignored_unknown_event' | 'ignored_no_action_match' | 'ignored_slack_retry' | 'url_verification' | 'validation_error' | 'signature_invalid' | 'error';
|
|
43
|
+
type SlackOutcome = 'handled' | 'ignored_bot_message' | 'ignored_edited_message' | 'ignored_unknown_event' | 'ignored_no_action_match' | 'ignored_slack_retry' | 'url_verification' | 'validation_error' | 'signature_invalid' | 'error';
|
|
44
44
|
//#endregion
|
|
45
45
|
export { SLACK_SPAN_KEYS, SLACK_SPAN_NAMES, SlackOutcome, setSpanWithError, tracer };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-work-apps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "First party integrations for Inkeep Agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"jose": "^6.1.0",
|
|
34
34
|
"minimatch": "^10.1.1",
|
|
35
35
|
"slack-block-builder": "^2.8.0",
|
|
36
|
-
"@inkeep/agents-core": "0.
|
|
36
|
+
"@inkeep/agents-core": "0.53.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@hono/zod-openapi": "^1.1.5",
|