@inkeep/agents-work-apps 0.53.7 → 0.53.9
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 +2 -2
- package/dist/github/index.d.ts +3 -3
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/routes/setup.d.ts +2 -2
- package/dist/github/routes/tokenExchange.d.ts +2 -2
- package/dist/github/routes/webhooks.d.ts +2 -2
- package/dist/slack/services/blocks/index.js +20 -14
- package/dist/slack/services/commands/index.js +2 -1
- package/dist/slack/services/events/app-mention.js +4 -2
- package/dist/slack/services/events/block-actions.js +3 -1
- package/dist/slack/services/events/direct-message.js +2 -1
- package/dist/slack/services/events/execution.d.ts +3 -1
- package/dist/slack/services/events/execution.js +2 -1
- package/dist/slack/services/events/modal-submission.js +2 -1
- package/dist/slack/services/events/streaming.d.ts +1 -0
- package/dist/slack/services/events/streaming.js +13 -7
- package/dist/slack/services/events/utils.d.ts +14 -2
- package/dist/slack/services/events/utils.js +18 -2
- package/dist/slack/services/link-prompt.d.ts +2 -2
- package/dist/slack/services/resume-intent.js +9 -5
- package/package.json +4 -4
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";
|
|
17
18
|
trace: "trace";
|
|
18
19
|
debug: "debug";
|
|
19
20
|
info: "info";
|
|
20
21
|
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: "
|
|
47
|
+
LOG_LEVEL: "error" | "trace" | "debug" | "info" | "warn";
|
|
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;
|
package/dist/github/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ import "./routes/setup.js";
|
|
|
4
4
|
import "./routes/tokenExchange.js";
|
|
5
5
|
import { WebhookVerificationResult, verifyWebhookSignature } from "./routes/webhooks.js";
|
|
6
6
|
import { Hono } from "hono";
|
|
7
|
-
import * as
|
|
7
|
+
import * as hono_types0 from "hono/types";
|
|
8
8
|
|
|
9
9
|
//#region src/github/index.d.ts
|
|
10
|
-
declare function createGithubRoutes(): Hono<
|
|
11
|
-
declare const githubRoutes: Hono<
|
|
10
|
+
declare function createGithubRoutes(): Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
11
|
+
declare const githubRoutes: Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { GenerateInstallationAccessTokenResult, GenerateTokenError, GenerateTokenResult, GitHubAppConfig, InstallationAccessToken, InstallationInfo, LookupInstallationError, LookupInstallationForRepoResult, LookupInstallationResult, WebhookVerificationResult, clearConfigCache, createAppJwt, createGithubRoutes, determineStatus, fetchInstallationDetails, fetchInstallationRepositories, generateInstallationAccessToken, getGitHubAppConfig, getGitHubAppName, getStateSigningSecret, getWebhookSecret, githubRoutes, isGitHubAppConfigured, isGitHubAppNameConfigured, isStateSigningConfigured, isWebhookConfigured, lookupInstallationForRepo, validateGitHubAppConfigOnStartup, validateGitHubInstallFlowConfigOnStartup, validateGitHubWebhookConfigOnStartup, verifyWebhookSignature };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types0 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/mcp/index.d.ts
|
|
5
5
|
declare const app: Hono<{
|
|
6
6
|
Variables: {
|
|
7
7
|
toolId: string;
|
|
8
8
|
};
|
|
9
|
-
},
|
|
9
|
+
}, hono_types0.BlankSchema, "/">;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { app as default };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types4 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/setup.d.ts
|
|
5
|
-
declare const app: Hono<
|
|
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
|
|
2
|
+
import * as hono_types6 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/tokenExchange.d.ts
|
|
5
|
-
declare const app: Hono<
|
|
5
|
+
declare const app: Hono<hono_types6.BlankEnv, hono_types6.BlankSchema, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types8 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/webhooks.d.ts
|
|
5
5
|
interface WebhookVerificationResult {
|
|
@@ -7,6 +7,6 @@ interface WebhookVerificationResult {
|
|
|
7
7
|
error?: string;
|
|
8
8
|
}
|
|
9
9
|
declare function verifyWebhookSignature(payload: string, signature: string | undefined, secret: string): WebhookVerificationResult;
|
|
10
|
-
declare const app: Hono<
|
|
10
|
+
declare const app: Hono<hono_types8.BlankEnv, hono_types8.BlankSchema, "/">;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { WebhookVerificationResult, app as default, verifyWebhookSignature };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { escapeSlackLinkText, escapeSlackMrkdwn } from "../events/utils.js";
|
|
1
2
|
import { SlackStrings } from "../../i18n/strings.js";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
import { Blocks, Elements, Md, Message } from "slack-block-builder";
|
|
@@ -12,7 +13,7 @@ function createContextBlock(params) {
|
|
|
12
13
|
type: "context",
|
|
13
14
|
elements: [{
|
|
14
15
|
type: "mrkdwn",
|
|
15
|
-
text: SlackStrings.context.poweredBy(agentName)
|
|
16
|
+
text: SlackStrings.context.poweredBy(escapeSlackMrkdwn(agentName))
|
|
16
17
|
}]
|
|
17
18
|
};
|
|
18
19
|
}
|
|
@@ -73,15 +74,16 @@ function buildToolApprovalBlocks(params) {
|
|
|
73
74
|
type: "section",
|
|
74
75
|
text: {
|
|
75
76
|
type: "mrkdwn",
|
|
76
|
-
text: `*Approval required - \`${toolName}\`*`
|
|
77
|
+
text: `*Approval required - \`${escapeSlackMrkdwn(toolName)}\`*`
|
|
77
78
|
}
|
|
78
79
|
}];
|
|
79
80
|
if (input && Object.keys(input).length > 0) {
|
|
80
81
|
const fields = Object.entries(input).slice(0, 10).map(([k, v]) => {
|
|
81
82
|
const val = typeof v === "object" ? JSON.stringify(v) : String(v ?? "");
|
|
83
|
+
const truncated = val.length > 80 ? `${val.slice(0, 80)}…` : val;
|
|
82
84
|
return {
|
|
83
85
|
type: "mrkdwn",
|
|
84
|
-
text: `*${k}:*\n${
|
|
86
|
+
text: `*${escapeSlackMrkdwn(k)}:*\n${escapeSlackMrkdwn(truncated)}`
|
|
85
87
|
};
|
|
86
88
|
});
|
|
87
89
|
blocks.push({
|
|
@@ -121,7 +123,7 @@ function buildToolApprovalDoneBlocks(params) {
|
|
|
121
123
|
type: "context",
|
|
122
124
|
elements: [{
|
|
123
125
|
type: "mrkdwn",
|
|
124
|
-
text: approved ? `✅ Approved \`${toolName}\` · <@${actorUserId}>` : `❌ Denied \`${toolName}\` · <@${actorUserId}>`
|
|
126
|
+
text: approved ? `✅ Approved \`${escapeSlackMrkdwn(toolName)}\` · <@${actorUserId}>` : `❌ Denied \`${escapeSlackMrkdwn(toolName)}\` · <@${actorUserId}>`
|
|
125
127
|
}]
|
|
126
128
|
}];
|
|
127
129
|
}
|
|
@@ -130,16 +132,17 @@ function buildToolApprovalExpiredBlocks(params) {
|
|
|
130
132
|
type: "context",
|
|
131
133
|
elements: [{
|
|
132
134
|
type: "mrkdwn",
|
|
133
|
-
text: `⏱️ Expired · \`${params.toolName}\``
|
|
135
|
+
text: `⏱️ Expired · \`${escapeSlackMrkdwn(params.toolName)}\``
|
|
134
136
|
}]
|
|
135
137
|
}];
|
|
136
138
|
}
|
|
137
139
|
function buildToolOutputErrorBlock(toolName, errorText) {
|
|
140
|
+
const truncated = errorText.length > 100 ? `${errorText.slice(0, 100)}…` : errorText;
|
|
138
141
|
return {
|
|
139
142
|
type: "context",
|
|
140
143
|
elements: [{
|
|
141
144
|
type: "mrkdwn",
|
|
142
|
-
text: `⚠️ *${toolName}* · failed: ${
|
|
145
|
+
text: `⚠️ *${escapeSlackMrkdwn(toolName)}* · failed: ${escapeSlackMrkdwn(truncated)}`
|
|
143
146
|
}]
|
|
144
147
|
};
|
|
145
148
|
}
|
|
@@ -148,7 +151,7 @@ function buildSummaryBreadcrumbBlock(labels) {
|
|
|
148
151
|
type: "context",
|
|
149
152
|
elements: [{
|
|
150
153
|
type: "mrkdwn",
|
|
151
|
-
text: labels.join(" → ")
|
|
154
|
+
text: labels.map(escapeSlackMrkdwn).join(" → ")
|
|
152
155
|
}]
|
|
153
156
|
};
|
|
154
157
|
}
|
|
@@ -179,9 +182,10 @@ function buildDataComponentBlocks(component) {
|
|
|
179
182
|
if (Object.keys(payload).length > 0) if (isFlatRecord(payload)) {
|
|
180
183
|
const fields = Object.entries(payload).slice(0, 10).map(([k, v]) => {
|
|
181
184
|
const val = String(v ?? "");
|
|
185
|
+
const truncated = val.length > 80 ? `${val.slice(0, 80)}…` : val;
|
|
182
186
|
return {
|
|
183
187
|
type: "mrkdwn",
|
|
184
|
-
text: `*${k}*\n${
|
|
188
|
+
text: `*${escapeSlackMrkdwn(k)}*\n${escapeSlackMrkdwn(truncated)}`
|
|
185
189
|
};
|
|
186
190
|
});
|
|
187
191
|
blocks.push({
|
|
@@ -203,7 +207,7 @@ function buildDataComponentBlocks(component) {
|
|
|
203
207
|
type: "context",
|
|
204
208
|
elements: [{
|
|
205
209
|
type: "mrkdwn",
|
|
206
|
-
text: `data component · type: ${componentType}`
|
|
210
|
+
text: `data component · type: ${escapeSlackMrkdwn(componentType)}`
|
|
207
211
|
}]
|
|
208
212
|
});
|
|
209
213
|
return {
|
|
@@ -219,7 +223,8 @@ function buildDataArtifactBlocks(artifact) {
|
|
|
219
223
|
const MAX_SOURCES = 10;
|
|
220
224
|
const lines = sourcesArray.slice(0, MAX_SOURCES).map((s) => {
|
|
221
225
|
const url = s.url || s.href;
|
|
222
|
-
const
|
|
226
|
+
const rawTitle = s.title || s.name || url;
|
|
227
|
+
const title = rawTitle ? escapeSlackLinkText(rawTitle) : rawTitle;
|
|
223
228
|
return url ? `• <${url}|${title}>` : null;
|
|
224
229
|
}).filter((l) => l !== null);
|
|
225
230
|
if (lines.length > 0) {
|
|
@@ -247,7 +252,7 @@ function buildDataArtifactBlocks(artifact) {
|
|
|
247
252
|
type: "context",
|
|
248
253
|
elements: [{
|
|
249
254
|
type: "mrkdwn",
|
|
250
|
-
text: `type: ${artifactType}`
|
|
255
|
+
text: `type: ${escapeSlackMrkdwn(artifactType)}`
|
|
251
256
|
}]
|
|
252
257
|
});
|
|
253
258
|
let overflowContent;
|
|
@@ -267,10 +272,11 @@ function buildDataArtifactBlocks(artifact) {
|
|
|
267
272
|
}
|
|
268
273
|
function buildCitationsBlock(citations) {
|
|
269
274
|
const MAX_CITATIONS = 10;
|
|
270
|
-
const lines = citations.slice(0, MAX_CITATIONS).map((c) => {
|
|
275
|
+
const lines = citations.slice(0, MAX_CITATIONS).map((c, i) => {
|
|
271
276
|
const url = c.url;
|
|
272
|
-
const
|
|
273
|
-
|
|
277
|
+
const rawTitle = c.title || url;
|
|
278
|
+
const title = rawTitle ? escapeSlackLinkText(rawTitle) : rawTitle;
|
|
279
|
+
return url ? `<${url}|[${i + 1}] ${title}>` : null;
|
|
274
280
|
}).filter((l) => l !== null);
|
|
275
281
|
if (lines.length === 0) return [];
|
|
276
282
|
const suffix = citations.length > MAX_CITATIONS ? `\n_and ${citations.length - MAX_CITATIONS} more_` : "";
|
|
@@ -262,7 +262,8 @@ async function handleQuestionCommand(payload, question, _dashboardUrl, tenantId,
|
|
|
262
262
|
agentId: resolvedAgent.agentId,
|
|
263
263
|
agentName: resolvedAgent.agentName || resolvedAgent.agentId,
|
|
264
264
|
question,
|
|
265
|
-
conversationId
|
|
265
|
+
conversationId,
|
|
266
|
+
entryPoint: "slash_command"
|
|
266
267
|
}).catch(async (error) => {
|
|
267
268
|
logger.error({ error }, "Background execution promise rejected");
|
|
268
269
|
if (payload.responseUrl) try {
|
|
@@ -238,7 +238,8 @@ Respond naturally as if you're joining the conversation to help.`;
|
|
|
238
238
|
agentId: agentConfig.agentId,
|
|
239
239
|
agentName: agentDisplayName,
|
|
240
240
|
question: threadQuery,
|
|
241
|
-
conversationId: conversationId$1
|
|
241
|
+
conversationId: conversationId$1,
|
|
242
|
+
entryPoint: "app_mention"
|
|
242
243
|
});
|
|
243
244
|
span.end();
|
|
244
245
|
return;
|
|
@@ -308,7 +309,8 @@ Respond naturally as if you're joining the conversation to help.`;
|
|
|
308
309
|
agentId: agentConfig.agentId,
|
|
309
310
|
agentName: agentDisplayName,
|
|
310
311
|
question: queryText,
|
|
311
|
-
conversationId
|
|
312
|
+
conversationId,
|
|
313
|
+
entryPoint: "app_mention"
|
|
312
314
|
});
|
|
313
315
|
span.end();
|
|
314
316
|
} catch (error) {
|
|
@@ -71,7 +71,9 @@ async function handleToolApproval(params) {
|
|
|
71
71
|
"Content-Type": "application/json",
|
|
72
72
|
Authorization: `Bearer ${slackUserToken}`,
|
|
73
73
|
"x-inkeep-project-id": projectId,
|
|
74
|
-
"x-inkeep-agent-id": agentId
|
|
74
|
+
"x-inkeep-agent-id": agentId,
|
|
75
|
+
"x-inkeep-invocation-type": "slack",
|
|
76
|
+
"x-inkeep-invocation-entry-point": "tool_approval"
|
|
75
77
|
},
|
|
76
78
|
body: JSON.stringify({
|
|
77
79
|
conversationId,
|
|
@@ -118,7 +118,8 @@ async function handleDirectMessage(params) {
|
|
|
118
118
|
agentId: defaultAgent.agentId,
|
|
119
119
|
agentName: agentDisplayName,
|
|
120
120
|
question: queryText,
|
|
121
|
-
conversationId
|
|
121
|
+
conversationId,
|
|
122
|
+
entryPoint: "direct_message"
|
|
122
123
|
});
|
|
123
124
|
span.end();
|
|
124
125
|
} catch (error) {
|
|
@@ -2,6 +2,7 @@ import { getSlackClient } from "../client.js";
|
|
|
2
2
|
import { StreamResult } from "./streaming.js";
|
|
3
3
|
|
|
4
4
|
//#region src/slack/services/events/execution.d.ts
|
|
5
|
+
type SlackEntryPoint = 'app_mention' | 'direct_message' | 'slash_command' | 'message_shortcut' | 'modal_submission' | 'smart_link_resume' | 'tool_approval';
|
|
5
6
|
interface PublicExecutionParams {
|
|
6
7
|
slackClient: ReturnType<typeof getSlackClient>;
|
|
7
8
|
channel: string;
|
|
@@ -14,7 +15,8 @@ interface PublicExecutionParams {
|
|
|
14
15
|
agentName: string;
|
|
15
16
|
question: string;
|
|
16
17
|
conversationId: string;
|
|
18
|
+
entryPoint?: SlackEntryPoint;
|
|
17
19
|
}
|
|
18
20
|
declare function executeAgentPublicly(params: PublicExecutionParams): Promise<StreamResult>;
|
|
19
21
|
//#endregion
|
|
20
|
-
export { PublicExecutionParams, executeAgentPublicly };
|
|
22
|
+
export { PublicExecutionParams, SlackEntryPoint, executeAgentPublicly };
|
|
@@ -94,7 +94,8 @@ async function handleModalSubmission(view) {
|
|
|
94
94
|
agentId,
|
|
95
95
|
agentName: agentDisplayName,
|
|
96
96
|
question: fullQuestion,
|
|
97
|
-
conversationId
|
|
97
|
+
conversationId,
|
|
98
|
+
entryPoint: metadata.messageContext ? "message_shortcut" : "modal_submission"
|
|
98
99
|
});
|
|
99
100
|
logger.info({
|
|
100
101
|
agentId,
|
|
@@ -13,7 +13,7 @@ import { getInProcessFetch, retryWithBackoff } from "@inkeep/agents-core";
|
|
|
13
13
|
* Streams responses incrementally to Slack using chatStream API.
|
|
14
14
|
*/
|
|
15
15
|
const logger = getLogger("slack-streaming");
|
|
16
|
-
const STREAM_TIMEOUT_MS =
|
|
16
|
+
const STREAM_TIMEOUT_MS = 18e5;
|
|
17
17
|
const CHATSTREAM_OP_TIMEOUT_MS = 2e4;
|
|
18
18
|
/** Shorter timeout for best-effort cleanup in error paths to bound total error handling time. */
|
|
19
19
|
const CLEANUP_TIMEOUT_MS = 3e3;
|
|
@@ -62,7 +62,7 @@ async function cleanupThinkingMessage(params) {
|
|
|
62
62
|
}
|
|
63
63
|
async function streamAgentResponse(params) {
|
|
64
64
|
return tracer.startActiveSpan(SLACK_SPAN_NAMES.STREAM_AGENT_RESPONSE, async (span) => {
|
|
65
|
-
const { slackClient, channel, threadTs, thinkingMessageTs, slackUserId, teamId, jwtToken, projectId, agentId, question, agentName, conversationId } = params;
|
|
65
|
+
const { slackClient, channel, threadTs, thinkingMessageTs, slackUserId, teamId, jwtToken, projectId, agentId, question, agentName, conversationId, entryPoint } = params;
|
|
66
66
|
const threadParam = threadTs ? { thread_ts: threadTs } : {};
|
|
67
67
|
const cleanupParams = {
|
|
68
68
|
slackClient,
|
|
@@ -109,7 +109,9 @@ async function streamAgentResponse(params) {
|
|
|
109
109
|
"Content-Type": "application/json",
|
|
110
110
|
Authorization: `Bearer ${jwtToken}`,
|
|
111
111
|
"x-inkeep-project-id": projectId,
|
|
112
|
-
"x-inkeep-agent-id": agentId
|
|
112
|
+
"x-inkeep-agent-id": agentId,
|
|
113
|
+
"x-inkeep-invocation-type": "slack",
|
|
114
|
+
...entryPoint && { "x-inkeep-invocation-entry-point": entryPoint }
|
|
113
115
|
},
|
|
114
116
|
body: JSON.stringify({
|
|
115
117
|
messages: [{
|
|
@@ -349,10 +351,14 @@ async function streamAgentResponse(params) {
|
|
|
349
351
|
const artifactData = data.data;
|
|
350
352
|
if (typeof artifactData.type === "string" && artifactData.type.toLowerCase() === "citation") {
|
|
351
353
|
const summary = artifactData.artifactSummary;
|
|
352
|
-
if (summary?.url && !citations.some((c) => c.url === summary.url))
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
354
|
+
if (summary?.url && !citations.some((c) => c.url === summary.url)) {
|
|
355
|
+
citations.push({
|
|
356
|
+
title: summary.title,
|
|
357
|
+
url: summary.url
|
|
358
|
+
});
|
|
359
|
+
const citationIndex = citations.length;
|
|
360
|
+
if (fullText.length > 0) await withTimeout(streamer.append({ markdown_text: `<${summary.url}|[${citationIndex}]>` }), CHATSTREAM_OP_TIMEOUT_MS, "streamer.append").catch((e) => logger.warn({ error: e }, "Failed to append inline citation"));
|
|
361
|
+
}
|
|
356
362
|
} else if (richMessageCount < MAX_RICH_MESSAGES) {
|
|
357
363
|
const { blocks, overflowContent, artifactName } = buildDataArtifactBlocks({ data: artifactData });
|
|
358
364
|
if (overflowContent) {
|
|
@@ -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;
|
|
@@ -22,6 +22,18 @@ declare function findCachedUserMapping(tenantId: string, slackUserId: string, te
|
|
|
22
22
|
linkedAt: string;
|
|
23
23
|
lastUsedAt: string | null;
|
|
24
24
|
} | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Escape special characters in Slack mrkdwn link display text.
|
|
27
|
+
* In Slack's <url|text> format, `>` terminates the link, `<` opens a new one,
|
|
28
|
+
* and `&` begins an HTML entity — all must be escaped.
|
|
29
|
+
*/
|
|
30
|
+
declare function escapeSlackLinkText(text: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Escape special characters in Slack mrkdwn text.
|
|
33
|
+
* In Slack's mrkdwn, `&`, `<`, and `>` are treated as HTML entities/tags
|
|
34
|
+
* and must be escaped in all dynamic mrkdwn text fields.
|
|
35
|
+
*/
|
|
36
|
+
declare function escapeSlackMrkdwn(text: string): string;
|
|
25
37
|
/**
|
|
26
38
|
* Convert standard Markdown to Slack's mrkdwn format
|
|
27
39
|
*
|
|
@@ -167,4 +179,4 @@ declare function formatChannelContext(channelInfo: {
|
|
|
167
179
|
name?: string;
|
|
168
180
|
} | null): string;
|
|
169
181
|
//#endregion
|
|
170
|
-
export { ProjectOption, SlackAttachment, SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatAttachments, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
|
|
182
|
+
export { ProjectOption, SlackAttachment, SlackErrorType, checkIfBotThread, classifyError, escapeSlackLinkText, escapeSlackMrkdwn, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatAttachments, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
|
|
@@ -50,6 +50,22 @@ async function findCachedUserMapping(tenantId, slackUserId, teamId, clientId = "
|
|
|
50
50
|
return mapping;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
+
* Escape special characters in Slack mrkdwn link display text.
|
|
54
|
+
* In Slack's <url|text> format, `>` terminates the link, `<` opens a new one,
|
|
55
|
+
* and `&` begins an HTML entity — all must be escaped.
|
|
56
|
+
*/
|
|
57
|
+
function escapeSlackLinkText(text) {
|
|
58
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Escape special characters in Slack mrkdwn text.
|
|
62
|
+
* In Slack's mrkdwn, `&`, `<`, and `>` are treated as HTML entities/tags
|
|
63
|
+
* and must be escaped in all dynamic mrkdwn text fields.
|
|
64
|
+
*/
|
|
65
|
+
function escapeSlackMrkdwn(text) {
|
|
66
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
53
69
|
* Convert standard Markdown to Slack's mrkdwn format
|
|
54
70
|
*
|
|
55
71
|
* Key differences:
|
|
@@ -63,7 +79,7 @@ function markdownToMrkdwn(markdown) {
|
|
|
63
79
|
if (!markdown) return markdown;
|
|
64
80
|
let result = markdown;
|
|
65
81
|
result = result.replace(/^#{1,6}\s+(.+)$/gm, "*$1*");
|
|
66
|
-
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g,
|
|
82
|
+
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, text, url) => `<${url}|${escapeSlackLinkText(text)}>`);
|
|
67
83
|
result = result.replace(/\*\*([^*]+)\*\*/g, "*$1*");
|
|
68
84
|
result = result.replace(/__([^_]+)__/g, "*$1*");
|
|
69
85
|
result = result.replace(/~~([^~]+)~~/g, "~$1~");
|
|
@@ -426,4 +442,4 @@ function formatChannelContext(channelInfo) {
|
|
|
426
442
|
}
|
|
427
443
|
|
|
428
444
|
//#endregion
|
|
429
|
-
export { SlackErrorType, checkIfBotThread, classifyError, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatAttachments, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
|
|
445
|
+
export { SlackErrorType, checkIfBotThread, classifyError, escapeSlackLinkText, escapeSlackMrkdwn, extractApiErrorMessage, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, formatAttachments, formatChannelContext, formatChannelLabel, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, resolveChannelAgentConfig, sendResponseUrlMessage, timedOp };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SlackLinkIntent } from "@inkeep/agents-core";
|
|
2
|
-
import * as
|
|
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<
|
|
25
|
+
declare function buildLinkPromptMessage(result: LinkPromptResult): Readonly<slack_block_builder7.SlackMessageDto>;
|
|
26
26
|
//#endregion
|
|
27
27
|
export { LinkPromptResult, ResolveLinkActionParams, buildLinkPromptMessage, resolveUnlinkedUserAction };
|
|
@@ -7,7 +7,7 @@ import { createContextBlock } from "./blocks/index.js";
|
|
|
7
7
|
import { getSlackClient } from "./client.js";
|
|
8
8
|
import { streamAgentResponse } from "./events/streaming.js";
|
|
9
9
|
import { executeAgentPublicly } from "./events/execution.js";
|
|
10
|
-
import { signSlackUserToken } from "@inkeep/agents-core";
|
|
10
|
+
import { getInProcessFetch, signSlackUserToken } from "@inkeep/agents-core";
|
|
11
11
|
|
|
12
12
|
//#region src/slack/services/resume-intent.ts
|
|
13
13
|
const logger = getLogger("slack-resume-intent");
|
|
@@ -130,7 +130,8 @@ async function resumeMention(intent, slackClient, tokenCtx, teamId, tenantId) {
|
|
|
130
130
|
agentId: intent.agentId,
|
|
131
131
|
question: intent.question,
|
|
132
132
|
agentName: intent.agentId,
|
|
133
|
-
conversationId
|
|
133
|
+
conversationId,
|
|
134
|
+
entryPoint: "smart_link_resume"
|
|
134
135
|
});
|
|
135
136
|
}
|
|
136
137
|
async function resumeDirectMessage(intent, slackClient, tokenCtx, teamId) {
|
|
@@ -166,7 +167,8 @@ async function resumeDirectMessage(intent, slackClient, tokenCtx, teamId) {
|
|
|
166
167
|
agentId: intent.agentId,
|
|
167
168
|
agentName: intent.agentId,
|
|
168
169
|
question: intent.question,
|
|
169
|
-
conversationId
|
|
170
|
+
conversationId,
|
|
171
|
+
entryPoint: "smart_link_resume"
|
|
170
172
|
});
|
|
171
173
|
}
|
|
172
174
|
async function resumeCommand(intent, slackClient, tokenCtx, teamId, tenantId) {
|
|
@@ -291,13 +293,15 @@ async function executeAndDeliver(params) {
|
|
|
291
293
|
const timeout = setTimeout(() => controller.abort(), 3e4);
|
|
292
294
|
let response;
|
|
293
295
|
try {
|
|
294
|
-
response = await
|
|
296
|
+
response = await getInProcessFetch()(`${apiBaseUrl}/run/api/chat`, {
|
|
295
297
|
method: "POST",
|
|
296
298
|
headers: {
|
|
297
299
|
"Content-Type": "application/json",
|
|
298
300
|
Authorization: `Bearer ${slackUserToken}`,
|
|
299
301
|
"x-inkeep-project-id": projectId,
|
|
300
|
-
"x-inkeep-agent-id": agentId
|
|
302
|
+
"x-inkeep-agent-id": agentId,
|
|
303
|
+
"x-inkeep-invocation-type": "slack",
|
|
304
|
+
"x-inkeep-invocation-entry-point": "smart_link_resume"
|
|
301
305
|
},
|
|
302
306
|
body: JSON.stringify({
|
|
303
307
|
messages: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-work-apps",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.9",
|
|
4
4
|
"description": "First party integrations for Inkeep Agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"@slack/web-api": "^7.9.1",
|
|
30
30
|
"drizzle-orm": "^0.44.7",
|
|
31
31
|
"fetch-to-node": "^2.1.0",
|
|
32
|
-
"hono": "^4.
|
|
32
|
+
"hono": "^4.12.2",
|
|
33
33
|
"jose": "^6.1.0",
|
|
34
|
-
"minimatch": "^10.
|
|
34
|
+
"minimatch": "^10.2.1",
|
|
35
35
|
"slack-block-builder": "^2.8.0",
|
|
36
|
-
"@inkeep/agents-core": "0.53.
|
|
36
|
+
"@inkeep/agents-core": "0.53.9"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@hono/zod-openapi": "^1.1.5",
|