@inkeep/agents-work-apps 0.53.0 → 0.53.2

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.
@@ -1,6 +1,6 @@
1
+ import { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./utils.js";
1
2
  import { InlineSelectorMetadata, handleAppMention } from "./app-mention.js";
2
3
  import { handleMessageShortcut, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleToolApproval } from "./block-actions.js";
3
4
  import { handleFollowUpSubmission, handleModalSubmission } from "./modal-submission.js";
4
- import { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./utils.js";
5
5
  import { StreamResult, streamAgentResponse } from "./streaming.js";
6
6
  export { type InlineSelectorMetadata, SlackErrorType, type StreamResult, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, handleAppMention, handleFollowUpSubmission, handleMessageShortcut, handleModalSubmission, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleToolApproval, markdownToMrkdwn, sendResponseUrlMessage, streamAgentResponse };
@@ -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;
14
15
  tenantId: string;
15
16
  clientId: string;
16
- slackUserId: string;
17
17
  slackTeamId: string;
18
18
  slackEnterpriseId: string | null;
19
19
  inkeepUserId: string;
@@ -112,6 +112,24 @@ declare function checkIfBotThread(slackClient: {
112
112
  }>;
113
113
  };
114
114
  }, channel: string, threadTs: string): Promise<boolean>;
115
+ interface SlackAttachment {
116
+ text?: string;
117
+ fallback?: string;
118
+ pretext?: string;
119
+ author_name?: string;
120
+ author_id?: string;
121
+ channel_name?: string;
122
+ channel_id?: string;
123
+ title?: string;
124
+ is_msg_unfurl?: boolean;
125
+ is_share?: boolean;
126
+ from_url?: string;
127
+ fields?: Array<{
128
+ title?: string;
129
+ value?: string;
130
+ }>;
131
+ }
132
+ declare function formatAttachments(attachments: SlackAttachment[] | undefined): string;
115
133
  interface ThreadContextOptions {
116
134
  includeLastMessage?: boolean;
117
135
  resolveUserNames?: boolean;
@@ -128,6 +146,7 @@ declare function getThreadContext(slackClient: {
128
146
  user?: string;
129
147
  text?: string;
130
148
  ts?: string;
149
+ attachments?: SlackAttachment[];
131
150
  }>;
132
151
  }>;
133
152
  };
@@ -160,4 +179,4 @@ declare function formatChannelContext(channelInfo: {
160
179
  name?: string;
161
180
  } | null): string;
162
181
  //#endregion
163
- export { ProjectOption, SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
182
+ export { ProjectOption, SlackAttachment, SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatAttachments, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
@@ -34,17 +34,19 @@ async function findCachedUserMapping(tenantId, slackUserId, teamId, clientId = "
34
34
  const cached = userMappingCache.get(cacheKey);
35
35
  if (cached && cached.expiresAt > Date.now()) return cached.mapping;
36
36
  const mapping = await findWorkAppSlackUserMapping(runDbClient_default)(tenantId, slackUserId, teamId, clientId);
37
- if (userMappingCache.size >= USER_MAPPING_CACHE_MAX_SIZE) {
38
- evictExpiredEntries();
37
+ if (mapping) {
39
38
  if (userMappingCache.size >= USER_MAPPING_CACHE_MAX_SIZE) {
40
- const oldestKey = userMappingCache.keys().next().value;
41
- if (oldestKey) userMappingCache.delete(oldestKey);
39
+ evictExpiredEntries();
40
+ if (userMappingCache.size >= USER_MAPPING_CACHE_MAX_SIZE) {
41
+ const oldestKey = userMappingCache.keys().next().value;
42
+ if (oldestKey) userMappingCache.delete(oldestKey);
43
+ }
42
44
  }
45
+ userMappingCache.set(cacheKey, {
46
+ mapping,
47
+ expiresAt: Date.now() + USER_MAPPING_CACHE_TTL_MS
48
+ });
43
49
  }
44
- userMappingCache.set(cacheKey, {
45
- mapping,
46
- expiresAt: Date.now() + USER_MAPPING_CACHE_TTL_MS
47
- });
48
50
  return mapping;
49
51
  }
50
52
  /**
@@ -328,6 +330,27 @@ async function checkIfBotThread(slackClient, channel, threadTs) {
328
330
  return false;
329
331
  }
330
332
  }
333
+ function formatAttachments(attachments) {
334
+ if (!attachments || attachments.length === 0) return "";
335
+ const parts = [];
336
+ for (const att of attachments) {
337
+ const content = att.text || att.fallback;
338
+ if (!content) continue;
339
+ const isSharedMessage = att.is_msg_unfurl || att.is_share;
340
+ const meta = [];
341
+ if (att.author_name) meta.push(`from ${att.author_name}`);
342
+ if (att.channel_name) meta.push(`in #${att.channel_name}`);
343
+ else if (att.channel_id) meta.push(`in channel ${att.channel_id}`);
344
+ const label = isSharedMessage ? "Shared message" : "Attachment";
345
+ const metaSuffix = meta.length > 0 ? ` (${meta.join(", ")})` : "";
346
+ const sourceLine = att.from_url ? `\n[Source: ${att.from_url}]` : "";
347
+ parts.push(`[${label}${metaSuffix}]:\n\`\`\`\n${content}\n\`\`\`${sourceLine}`);
348
+ if (att.fields && att.fields.length > 0) {
349
+ for (const field of att.fields) if (field.title && field.value) parts.push(`${field.title}: ${field.value}`);
350
+ }
351
+ }
352
+ return parts.join("\n\n");
353
+ }
331
354
  async function getThreadContext(slackClient, channel, threadTs, options = {}) {
332
355
  const { includeLastMessage = false, resolveUserNames = true } = options;
333
356
  try {
@@ -377,7 +400,9 @@ async function getThreadContext(slackClient, channel, threadTs, options = {}) {
377
400
  else role = "Unknown";
378
401
  const prefix = isParent ? "[Thread Start] " : "";
379
402
  const messageText = msg.text || "";
380
- return `${prefix}${role}: """${messageText}"""`;
403
+ const attachmentText = formatAttachments(msg.attachments);
404
+ const fullText = attachmentText ? `${messageText}\n${attachmentText}` : messageText;
405
+ return `${prefix}${role}: """${fullText}"""`;
381
406
  }).join("\n\n")}`;
382
407
  } catch (threadError) {
383
408
  logger.warn({
@@ -412,4 +437,4 @@ function formatChannelContext(channelInfo) {
412
437
  }
413
438
 
414
439
  //#endregion
415
- export { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
440
+ export { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatAttachments, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
@@ -1,16 +1,16 @@
1
1
  import { AgentResolutionParams, ResolvedAgentConfig, getAgentConfigSources, resolveEffectiveAgent } from "./agent-resolution.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";
2
+ import { AgentConfigSources, ContextBlockParams, FollowUpButtonParams, ToolApprovalButtonValue, ToolApprovalButtonValueSchema, buildCitationsBlock, buildConversationResponseBlocks, buildDataArtifactBlocks, buildDataComponentBlocks, buildFollowUpButton, buildSummaryBreadcrumbBlock, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, buildToolOutputErrorBlock, createAlreadyLinkedMessage, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createNotLinkedMessage, createSmartLinkMessage, 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";
6
6
  import { handleAgentPickerCommand, handleCommand, handleHelpCommand, handleLinkCommand, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand } from "./commands/index.js";
7
+ import { AgentOption, BuildAgentSelectorModalParams, BuildMessageShortcutModalParams, FollowUpModalMetadata, ModalMetadata, buildAgentSelectorModal, buildFollowUpModal, buildMessageShortcutModal } from "./modals.js";
8
+ import { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./events/utils.js";
7
9
  import { InlineSelectorMetadata, handleAppMention } from "./events/app-mention.js";
8
10
  import { handleMessageShortcut, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleToolApproval } from "./events/block-actions.js";
9
11
  import { handleFollowUpSubmission, handleModalSubmission } from "./events/modal-submission.js";
10
- import { AgentOption, BuildAgentSelectorModalParams, BuildMessageShortcutModalParams, FollowUpModalMetadata, ModalMetadata, buildAgentSelectorModal, buildFollowUpModal, buildMessageShortcutModal } from "./modals.js";
11
- import { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./events/utils.js";
12
12
  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, 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 };
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, createNotLinkedMessage, createSmartLinkMessage, 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,7 +1,7 @@
1
1
  import { clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setWorkspaceDefaultAgent, storeWorkspaceInstallation, updateConnectionMetadata } from "./nango.js";
2
2
  import { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./events/utils.js";
3
3
  import { getAgentConfigSources, resolveEffectiveAgent } from "./agent-resolution.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
+ import { ToolApprovalButtonValueSchema, buildCitationsBlock, buildConversationResponseBlocks, buildDataArtifactBlocks, buildDataComponentBlocks, buildFollowUpButton, buildSummaryBreadcrumbBlock, buildToolApprovalBlocks, buildToolApprovalDoneBlocks, buildToolApprovalExpiredBlocks, buildToolOutputErrorBlock, createAlreadyLinkedMessage, createContextBlock, createCreateInkeepAccountMessage, createErrorMessage, createNotLinkedMessage, createSmartLinkMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "./blocks/index.js";
5
5
  import { checkUserIsChannelMember, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackTeamInfo, getSlackUserInfo, postMessage, postMessageInThread, revokeSlackToken } from "./client.js";
6
6
  import { buildAgentSelectorModal, buildFollowUpModal, buildMessageShortcutModal } from "./modals.js";
7
7
  import { handleAgentPickerCommand, handleCommand, handleHelpCommand, handleLinkCommand, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand } from "./commands/index.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, 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 };
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, createNotLinkedMessage, createSmartLinkMessage, 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 };
@@ -0,0 +1,27 @@
1
+ import { SlackLinkIntent } from "@inkeep/agents-core";
2
+ import * as slack_block_builder7 from "slack-block-builder";
3
+
4
+ //#region src/slack/services/link-prompt.d.ts
5
+ type LinkPromptResult = {
6
+ type: 'auto_invite';
7
+ url: string;
8
+ email: string;
9
+ expiresInMinutes: number;
10
+ } | {
11
+ type: 'jwt_link';
12
+ url: string;
13
+ expiresInMinutes: number;
14
+ };
15
+ interface ResolveLinkActionParams {
16
+ tenantId: string;
17
+ teamId: string;
18
+ slackUserId: string;
19
+ botToken: string;
20
+ slackEnterpriseId?: string;
21
+ slackUsername?: string;
22
+ intent?: SlackLinkIntent;
23
+ }
24
+ declare function resolveUnlinkedUserAction(params: ResolveLinkActionParams): Promise<LinkPromptResult>;
25
+ declare function buildLinkPromptMessage(result: LinkPromptResult): Readonly<slack_block_builder7.SlackMessageDto>;
26
+ //#endregion
27
+ export { LinkPromptResult, ResolveLinkActionParams, buildLinkPromptMessage, resolveUnlinkedUserAction };
@@ -0,0 +1,142 @@
1
+ import { env } from "../../env.js";
2
+ import { getLogger } from "../../logger.js";
3
+ import runDbClient_default from "../../db/runDbClient.js";
4
+ import { createCreateInkeepAccountMessage, createSmartLinkMessage } from "./blocks/index.js";
5
+ import { getSlackClient } from "./client.js";
6
+ import { createInvitationInDb, findWorkAppSlackWorkspaceByTeamId, getOrganizationMemberByEmail, getPendingInvitationsByEmail, signSlackLinkToken } from "@inkeep/agents-core";
7
+
8
+ //#region src/slack/services/link-prompt.ts
9
+ const logger = getLogger("slack-link-prompt");
10
+ const LINK_CODE_TTL_MINUTES = 10;
11
+ async function resolveUnlinkedUserAction(params) {
12
+ const { tenantId, teamId, slackUserId, botToken, slackEnterpriseId, slackUsername, intent } = params;
13
+ const manageUiUrl = env.INKEEP_AGENTS_MANAGE_UI_URL || "http://localhost:3000";
14
+ const autoInvite = await tryAutoInvite({
15
+ tenantId,
16
+ teamId,
17
+ slackUserId,
18
+ botToken
19
+ });
20
+ if (autoInvite) {
21
+ const linkToken$1 = await signSlackLinkToken({
22
+ tenantId,
23
+ slackTeamId: teamId,
24
+ slackUserId,
25
+ slackEnterpriseId,
26
+ slackUsername,
27
+ intent
28
+ });
29
+ const authMethod = autoInvite.authMethod;
30
+ const linkReturnUrl = `/link?token=${encodeURIComponent(linkToken$1)}`;
31
+ const acceptUrl = authMethod === "email-password" ? `${manageUiUrl}/accept-invitation/${autoInvite.invitationId}?email=${encodeURIComponent(autoInvite.email)}&returnUrl=${encodeURIComponent(linkReturnUrl)}` : `${manageUiUrl}/login?invitation=${encodeURIComponent(autoInvite.invitationId)}&returnUrl=${encodeURIComponent(linkReturnUrl)}&email=${encodeURIComponent(autoInvite.email)}&authMethod=${encodeURIComponent(authMethod)}`;
32
+ logger.info({
33
+ invitationId: autoInvite.invitationId,
34
+ email: autoInvite.email,
35
+ hasIntent: !!intent
36
+ }, "Directing unlinked user to accept-invitation page");
37
+ return {
38
+ type: "auto_invite",
39
+ url: acceptUrl,
40
+ email: autoInvite.email,
41
+ expiresInMinutes: LINK_CODE_TTL_MINUTES
42
+ };
43
+ }
44
+ const linkToken = await signSlackLinkToken({
45
+ tenantId,
46
+ slackTeamId: teamId,
47
+ slackUserId,
48
+ slackEnterpriseId,
49
+ slackUsername,
50
+ intent
51
+ });
52
+ const linkUrl = `${manageUiUrl}/link?token=${encodeURIComponent(linkToken)}`;
53
+ logger.info({
54
+ slackUserId,
55
+ tenantId,
56
+ hasIntent: !!intent
57
+ }, "Generated JWT link token for unlinked user");
58
+ return {
59
+ type: "jwt_link",
60
+ url: linkUrl,
61
+ expiresInMinutes: LINK_CODE_TTL_MINUTES
62
+ };
63
+ }
64
+ function buildLinkPromptMessage(result) {
65
+ if (result.type === "auto_invite") return createCreateInkeepAccountMessage(result.url, result.expiresInMinutes);
66
+ return createSmartLinkMessage(result.url);
67
+ }
68
+ async function tryAutoInvite(params) {
69
+ const { tenantId, teamId, slackUserId, botToken } = params;
70
+ if (!botToken) return null;
71
+ try {
72
+ if (!(await findWorkAppSlackWorkspaceByTeamId(runDbClient_default)(tenantId, teamId))?.shouldAllowJoinFromWorkspace) {
73
+ logger.warn({
74
+ userId: slackUserId,
75
+ tenantId,
76
+ teamId
77
+ }, "Workspace should not allow join from workspace");
78
+ return null;
79
+ }
80
+ const slackClient = getSlackClient(botToken);
81
+ let userEmail;
82
+ try {
83
+ userEmail = (await slackClient.users.info({ user: slackUserId })).user?.profile?.email;
84
+ } catch (error) {
85
+ logger.warn({
86
+ error,
87
+ userId: slackUserId
88
+ }, "Failed to get user info from Slack");
89
+ return null;
90
+ }
91
+ if (!userEmail) {
92
+ logger.warn({ userId: slackUserId }, "No email found in Slack user profile");
93
+ return null;
94
+ }
95
+ if (await getOrganizationMemberByEmail(runDbClient_default)(tenantId, userEmail)) {
96
+ logger.debug({
97
+ userId: slackUserId,
98
+ email: userEmail
99
+ }, "User already has Inkeep account, skipping auto-invite");
100
+ return null;
101
+ }
102
+ const existingInvitation = (await getPendingInvitationsByEmail(runDbClient_default)(userEmail)).find((inv) => inv.organizationId === tenantId);
103
+ if (existingInvitation) {
104
+ logger.info({
105
+ userId: slackUserId,
106
+ tenantId,
107
+ invitationId: existingInvitation.id,
108
+ email: userEmail
109
+ }, "Reusing existing pending invitation for Slack user");
110
+ return {
111
+ invitationId: existingInvitation.id,
112
+ email: userEmail,
113
+ authMethod: existingInvitation.authMethod ?? "email-password"
114
+ };
115
+ }
116
+ const invitation = await createInvitationInDb(runDbClient_default)({
117
+ organizationId: tenantId,
118
+ email: userEmail
119
+ });
120
+ logger.info({
121
+ userId: slackUserId,
122
+ tenantId,
123
+ invitationId: invitation.id,
124
+ email: userEmail
125
+ }, "Invitation created for Slack user without Inkeep account");
126
+ return {
127
+ invitationId: invitation.id,
128
+ email: userEmail,
129
+ authMethod: invitation.authMethod
130
+ };
131
+ } catch (error) {
132
+ logger.warn({
133
+ error,
134
+ userId: slackUserId,
135
+ tenantId
136
+ }, "Auto-invite attempt failed");
137
+ return null;
138
+ }
139
+ }
140
+
141
+ //#endregion
142
+ export { buildLinkPromptMessage, resolveUnlinkedUserAction };
@@ -0,0 +1,15 @@
1
+ import { SlackLinkIntent } from "@inkeep/agents-core";
2
+
3
+ //#region src/slack/services/resume-intent.d.ts
4
+ interface ResumeSmartLinkIntentParams {
5
+ intent: SlackLinkIntent;
6
+ teamId: string;
7
+ slackUserId: string;
8
+ inkeepUserId: string;
9
+ tenantId: string;
10
+ slackEnterpriseId?: string;
11
+ slackUsername?: string;
12
+ }
13
+ declare function resumeSmartLinkIntent(params: ResumeSmartLinkIntentParams): Promise<void>;
14
+ //#endregion
15
+ export { ResumeSmartLinkIntentParams, resumeSmartLinkIntent };