@inkeep/agents-work-apps 0.0.0-dev-20260224195557 → 0.0.0-dev-20260225020733

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/env.d.ts CHANGED
@@ -14,11 +14,11 @@ declare const envSchema: z.ZodObject<{
14
14
  pentest: "pentest";
15
15
  }>>;
16
16
  LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
17
- error: "error";
18
17
  trace: "trace";
19
18
  debug: "debug";
20
19
  info: "info";
21
20
  warn: "warn";
21
+ error: "error";
22
22
  }>>;
23
23
  INKEEP_AGENTS_RUN_DATABASE_URL: z.ZodOptional<z.ZodString>;
24
24
  INKEEP_AGENTS_MANAGE_UI_URL: z.ZodOptional<z.ZodString>;
@@ -44,7 +44,7 @@ declare const envSchema: z.ZodObject<{
44
44
  declare const env: {
45
45
  NODE_ENV: "development" | "production" | "test";
46
46
  ENVIRONMENT: "development" | "production" | "test" | "pentest";
47
- LOG_LEVEL: "error" | "trace" | "debug" | "info" | "warn";
47
+ LOG_LEVEL: "trace" | "debug" | "info" | "warn" | "error";
48
48
  INKEEP_AGENTS_RUN_DATABASE_URL?: string | undefined;
49
49
  INKEEP_AGENTS_MANAGE_UI_URL?: string | undefined;
50
50
  GITHUB_APP_ID?: string | undefined;
@@ -1,7 +1,7 @@
1
- import * as hono1 from "hono";
1
+ import * as hono0 from "hono";
2
2
 
3
3
  //#region src/github/mcp/auth.d.ts
4
- declare const githubMcpAuth: () => hono1.MiddlewareHandler<{
4
+ declare const githubMcpAuth: () => hono0.MiddlewareHandler<{
5
5
  Variables: {
6
6
  toolId: string;
7
7
  };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types6 from "hono/types";
2
+ import * as hono_types4 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/setup.d.ts
5
- declare const app: Hono<hono_types6.BlankEnv, hono_types6.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types4.BlankEnv, hono_types4.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types4 from "hono/types";
2
+ import * as hono_types6 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/tokenExchange.d.ts
5
- declare const app: Hono<hono_types4.BlankEnv, hono_types4.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types6.BlankEnv, hono_types6.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -62,6 +62,7 @@ async function dispatchSlackEvent(eventType, payload, options, span) {
62
62
  slackUserId: event.user,
63
63
  channel: event.channel,
64
64
  text: question,
65
+ attachments: event.attachments,
65
66
  threadTs: event.thread_ts || event.ts || "",
66
67
  messageTs: event.ts || "",
67
68
  teamId,
@@ -1,18 +1,7 @@
1
+ import { SlackAttachment } from "./utils.js";
2
+
1
3
  //#region src/slack/services/events/app-mention.d.ts
2
- /**
3
- * Handler for Slack @mention events
4
- *
5
- * Flow:
6
- * 1. Resolve workspace connection (single lookup, cached)
7
- * 2. Parallel: resolve agent config + check user link
8
- * 3. If no agent configured → prompt to set up in dashboard
9
- * 4. If not linked → prompt to link account
10
- * 5. Handle based on context:
11
- * - Channel + no query → Show usage hint
12
- * - Channel + query → Execute agent with streaming response
13
- * - Thread + no query → Auto-execute agent with thread context as query
14
- * - Thread + query → Execute agent with thread context included
15
- */
4
+
16
5
  /**
17
6
  * Metadata passed to the agent selector modal via button value
18
7
  */
@@ -32,6 +21,7 @@ declare function handleAppMention(params: {
32
21
  slackUserId: string;
33
22
  channel: string;
34
23
  text: string;
24
+ attachments?: SlackAttachment[];
35
25
  threadTs: string;
36
26
  messageTs: string;
37
27
  teamId: string;
@@ -1,7 +1,7 @@
1
1
  import { env } from "../../../env.js";
2
2
  import { getLogger } from "../../../logger.js";
3
3
  import { findWorkspaceConnectionByTeamId } from "../nango.js";
4
- import { checkIfBotThread, classifyError, findCachedUserMapping, formatChannelContext, generateSlackConversationId, getThreadContext, getUserFriendlyErrorMessage, timedOp } from "./utils.js";
4
+ import { checkIfBotThread, classifyError, findCachedUserMapping, formatAttachments, formatChannelContext, generateSlackConversationId, getThreadContext, getUserFriendlyErrorMessage, timedOp } from "./utils.js";
5
5
  import { resolveEffectiveAgent } from "../agent-resolution.js";
6
6
  import { SlackStrings } from "../../i18n/strings.js";
7
7
  import { getSlackChannelInfo, getSlackClient, getSlackUserInfo, postMessageInThread } from "../client.js";
@@ -17,7 +17,7 @@ const logger = getLogger("slack-app-mention");
17
17
  */
18
18
  async function handleAppMention(params) {
19
19
  return tracer.startActiveSpan(SLACK_SPAN_NAMES.APP_MENTION, async (span) => {
20
- const { slackUserId, channel, text, threadTs, messageTs, teamId, dispatchedAt } = params;
20
+ const { slackUserId, channel, text, attachments, threadTs, messageTs, teamId, dispatchedAt } = params;
21
21
  const handlerStartedAt = Date.now();
22
22
  const manageUiUrl = env.INKEEP_AGENTS_MANAGE_UI_URL || "http://localhost:3000";
23
23
  const dispatchDelayMs = dispatchedAt ? handlerStartedAt - dispatchedAt : void 0;
@@ -253,6 +253,7 @@ Respond naturally as if you're joining the conversation to help.`;
253
253
  return;
254
254
  }
255
255
  let queryText = text;
256
+ const attachmentContext = formatAttachments(attachments);
256
257
  if (isInThread && threadTs) {
257
258
  const { result: [contextMessages, channelInfo] } = await timedOp(Promise.all([getThreadContext(slackClient, channel, threadTs), getSlackChannelInfo(slackClient, channel)]), {
258
259
  label: "thread context fetch",
@@ -262,7 +263,12 @@ Respond naturally as if you're joining the conversation to help.`;
262
263
  threadTs
263
264
  }
264
265
  });
265
- if (contextMessages) queryText = `The following is thread context from ${formatChannelContext(channelInfo)}:\n\n<slack_thread_context>\n${contextMessages}\n</slack_thread_context>\n\nMessage from ${slackUserId}: ${text}`;
266
+ if (contextMessages) {
267
+ const channelContext = formatChannelContext(channelInfo);
268
+ let messageContent = text;
269
+ if (attachmentContext) messageContent = `${text}\n\n<attached_content>\n${attachmentContext}\n</attached_content>`;
270
+ queryText = `The following is thread context from ${channelContext}:\n\n<slack_thread_context>\n${contextMessages}\n</slack_thread_context>\n\nMessage from ${slackUserId}: ${messageContent}`;
271
+ }
266
272
  } else {
267
273
  const { result: [channelInfo, userInfo] } = await timedOp(Promise.all([getSlackChannelInfo(slackClient, channel), getSlackUserInfo(slackClient, slackUserId)]), {
268
274
  label: "channel/user info fetch",
@@ -271,7 +277,10 @@ Respond naturally as if you're joining the conversation to help.`;
271
277
  channel
272
278
  }
273
279
  });
274
- queryText = `The following is a message from ${formatChannelContext(channelInfo)} from ${userInfo?.displayName || "User"}: """${text}"""`;
280
+ const channelContext = formatChannelContext(channelInfo);
281
+ const userName = userInfo?.displayName || "User";
282
+ if (attachmentContext) queryText = `The following is a message from ${channelContext} from ${userName}: """${text}"""\n\nThe message also includes the following shared/forwarded content:\n\n<attached_content>\n${attachmentContext}\n</attached_content>`;
283
+ else queryText = `The following is a message from ${channelContext} from ${userName}: """${text}"""`;
275
284
  }
276
285
  const slackUserToken = await signSlackUserToken({
277
286
  inkeepUserId: existingLink.inkeepUserId,
@@ -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 };
@@ -8,12 +8,12 @@ import { AgentOption } from "../modals.js";
8
8
  * Called on every @mention and /inkeep command — caching avoids redundant DB queries.
9
9
  */
10
10
  declare function findCachedUserMapping(tenantId: string, slackUserId: string, teamId: string, clientId?: string): Promise<{
11
- id: string;
12
11
  createdAt: string;
13
12
  updatedAt: string;
14
- slackUserId: string;
13
+ id: 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;
@@ -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 };
@@ -330,6 +330,27 @@ async function checkIfBotThread(slackClient, channel, threadTs) {
330
330
  return false;
331
331
  }
332
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
+ }
333
354
  async function getThreadContext(slackClient, channel, threadTs, options = {}) {
334
355
  const { includeLastMessage = false, resolveUserNames = true } = options;
335
356
  try {
@@ -379,7 +400,9 @@ async function getThreadContext(slackClient, channel, threadTs, options = {}) {
379
400
  else role = "Unknown";
380
401
  const prefix = isParent ? "[Thread Start] " : "";
381
402
  const messageText = msg.text || "";
382
- return `${prefix}${role}: """${messageText}"""`;
403
+ const attachmentText = formatAttachments(msg.attachments);
404
+ const fullText = attachmentText ? `${messageText}\n${attachmentText}` : messageText;
405
+ return `${prefix}${role}: """${fullText}"""`;
383
406
  }).join("\n\n")}`;
384
407
  } catch (threadError) {
385
408
  logger.warn({
@@ -414,4 +437,4 @@ function formatChannelContext(channelInfo) {
414
437
  }
415
438
 
416
439
  //#endregion
417
- 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 };
@@ -4,11 +4,11 @@ import { checkUserIsChannelMember, getSlackChannelInfo, getSlackChannels, getSla
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";
@@ -1,5 +1,5 @@
1
1
  import { SlackLinkIntent } from "@inkeep/agents-core";
2
- import * as slack_block_builder0 from "slack-block-builder";
2
+ import * as slack_block_builder7 from "slack-block-builder";
3
3
 
4
4
  //#region src/slack/services/link-prompt.d.ts
5
5
  type LinkPromptResult = {
@@ -22,6 +22,6 @@ interface ResolveLinkActionParams {
22
22
  intent?: SlackLinkIntent;
23
23
  }
24
24
  declare function resolveUnlinkedUserAction(params: ResolveLinkActionParams): Promise<LinkPromptResult>;
25
- declare function buildLinkPromptMessage(result: LinkPromptResult): Readonly<slack_block_builder0.SlackMessageDto>;
25
+ declare function buildLinkPromptMessage(result: LinkPromptResult): Readonly<slack_block_builder7.SlackMessageDto>;
26
26
  //#endregion
27
27
  export { LinkPromptResult, ResolveLinkActionParams, buildLinkPromptMessage, resolveUnlinkedUserAction };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-work-apps",
3
- "version": "0.0.0-dev-20260224195557",
3
+ "version": "0.0.0-dev-20260225020733",
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.0.0-dev-20260224195557"
36
+ "@inkeep/agents-core": "0.0.0-dev-20260225020733"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@hono/zod-openapi": "^1.1.5",