Skip to content

Commit

Permalink
Add support for Slack mentions
Browse files Browse the repository at this point in the history
  • Loading branch information
lasryaric committed Oct 5, 2023
1 parent b0fbb24 commit 2588324
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 3 deletions.
54 changes: 51 additions & 3 deletions connectors/src/connectors/slack/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
DustAPI,
RetrievalDocumentType,
} from "@connectors/lib/dust_api";
import { editDistance } from "@connectors/lib/edit_distance";
import {
Connector,
ModelId,
Expand Down Expand Up @@ -189,13 +190,59 @@ async function botAnswerMessage(
}
}
}
// Extract all ~mentions.
const mentionCandidates = message.match(/~(\S+)/g) || [];

let mentions: { assistantName: string; assistantId: string }[] = [];
if (mentionCandidates.length > 0) {
const agentConfigurationsRes = await dustAPI.getAgentConfigurations();
if (agentConfigurationsRes.isErr()) {
return new Err(new Error(agentConfigurationsRes.error.message));
}
const agentConfigurations = agentConfigurationsRes.value;
for (const mc of mentionCandidates) {
const scores: {
assistantId: string;
assistantName: string;
distance: number;
}[] = [];
for (const agentConfiguration of agentConfigurations) {
const distance = editDistance(
mc.slice(1).toLocaleLowerCase(),
agentConfiguration.name.toLowerCase()
);
scores.push({
assistantId: agentConfiguration.sId,
assistantName: agentConfiguration.name,
distance: distance,
});
}
scores.sort((a, b) => {
return a.distance - b.distance;
});
const bestScore = scores[0];
if (bestScore) {
mentions.push({
assistantId: bestScore.assistantId,
assistantName: bestScore.assistantName,
});
}
}
}

if (mentions.length === 0) {
mentions.push({ assistantId: "dust", assistantName: "dust" });
}
// for now we support only one mention.
mentions = mentions.slice(0, 1);
const convRes = await dustAPI.createConversation({
title: null,
visibility: "unlisted",
message: {
content: message,
mentions: [{ configurationId: "dust" }],
mentions: mentions.map((m) => {
return { configurationId: m.assistantId };
}),
context: {
timezone: slackChatBotMessage.slackTimezone || "Europe/Paris",
username: slackChatBotMessage.slackUserName,
Expand Down Expand Up @@ -239,7 +286,8 @@ async function botAnswerMessage(
return new Err(new Error(streamRes.error.message));
}

let fullAnswer = "";
const botIdentity = `@${mentions[0]?.assistantName}:\n`;
let fullAnswer = botIdentity;
let action: AgentActionType | null = null;
let lastSentDate = new Date();
for await (const event of streamRes.value.eventStream) {
Expand Down Expand Up @@ -282,7 +330,7 @@ async function botAnswerMessage(
break;
}
case "agent_generation_success": {
fullAnswer = event.text;
fullAnswer = `${botIdentity}${event.text}`;

let finalAnswer = _processCiteMention(fullAnswer, action);
finalAnswer += `\n\n <${DUST_API}/w/${connector.workspaceId}/assistant/${conversation.sId}|Continue this conversation on Dust>`;
Expand Down
25 changes: 25 additions & 0 deletions connectors/src/lib/dust_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,11 @@ export type ConversationType = {
content: (UserMessageType[] | AgentMessageType[])[];
};

type AgentConfigurationType = {
sId: string;
name: string;
};

export class DustAPI {
_credentials: DustAPICredentials;

Expand Down Expand Up @@ -504,4 +509,24 @@ export class DustAPI {
}
return new Ok(json.conversation as ConversationType);
}

async getAgentConfigurations() {
const res = await fetch(
`${DUST_API}/api/v1/w/${this.workspaceId()}/assistant/agent_configurations`,
{
method: "GET",
headers: {
Authorization: `Bearer ${this._credentials.apiKey}`,
"Content-Type": "application/json",
},
}
);

const json = await res.json();

if (json.error) {
return new Err(json.error as DustAPIErrorResponse);
}
return new Ok(json.agentConfigurations as AgentConfigurationType[]);
}
}
41 changes: 41 additions & 0 deletions connectors/src/lib/edit_distance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Returns the Levenshtein distance between str1 and str2.
export function editDistance(str1: string, str2: string): number {
const matrix: number[][] = Array.from({ length: str1.length + 1 }, () =>
Array(str2.length + 1).fill(0)
);

const len1 = str1.length;
const len2 = str2.length;

for (let i = 0; i <= len1; i++) {
// @ts-expect-error array of array apparently don't play well with TS
matrix[i][0] = i;
}

for (let j = 0; j <= len2; j++) {
// @ts-expect-error array of array apparently don't play well with TS
matrix[0][j] = j;
}

for (let i = 1; i <= len1; i++) {
for (let j = 1; j <= len2; j++) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
// @ts-expect-error array of array apparently don't play well with TS
matrix[i][j] = matrix[i - 1][j - 1];
} else {
// @ts-expect-error array of array apparently don't play well with TS
matrix[i][j] = Math.min(
// @ts-expect-error array of array apparently don't play well with TS
matrix[i - 1][j - 1] + 1,
// @ts-expect-error array of array apparently don't play well with TS
Math.min(matrix[i][j - 1] + 1, matrix[i - 1][j] + 1)
);
}
}
}
// @ts-expect-error array of array apparently don't play well with TS
return matrix[len1][len2];
}

// Test the function
console.log(editDistance("kitten", "sitting")); // Output: 3

0 comments on commit 2588324

Please sign in to comment.