diff --git a/connectors/src/connectors/slack/bot.ts b/connectors/src/connectors/slack/bot.ts index 37b1ea5837a6..532c34241cbe 100644 --- a/connectors/src/connectors/slack/bot.ts +++ b/connectors/src/connectors/slack/bot.ts @@ -403,6 +403,7 @@ async function botAnswerMessage( slackChatBotMessage.slackFullName || slackChatBotMessage.slackUserName, email: slackChatBotMessage.slackEmail, profilePictureUrl: slackChatBotMessage.slackAvatar || null, + origin: "slack" as const, }, }; diff --git a/front/components/assistant/conversation/lib.ts b/front/components/assistant/conversation/lib.ts index d28ea52ab2a3..9ae4c029ec1f 100644 --- a/front/components/assistant/conversation/lib.ts +++ b/front/components/assistant/conversation/lib.ts @@ -71,6 +71,7 @@ export function createPlaceholderUserMessage({ profilePictureUrl: image, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone ?? "UTC", username, + origin: "web", }, }; } diff --git a/front/components/assistant_builder/AssistantBuilder.tsx b/front/components/assistant_builder/AssistantBuilder.tsx index 9e83197a7d27..cdcbeaddcbcf 100644 --- a/front/components/assistant_builder/AssistantBuilder.tsx +++ b/front/components/assistant_builder/AssistantBuilder.tsx @@ -343,7 +343,7 @@ export default function AssistantBuilder({ icon, }) ), - [screen] + [screen, multiActionsEnabled] ); const modalTitle = agentConfigurationId ? `Edit @${builderState.handle}` diff --git a/front/lib/api/assistant/conversation.ts b/front/lib/api/assistant/conversation.ts index dc8aae9e2b57..c6542b5d1b95 100644 --- a/front/lib/api/assistant/conversation.ts +++ b/front/lib/api/assistant/conversation.ts @@ -727,6 +727,7 @@ export async function* postUserMessage( userContextFullName: context.fullName, userContextEmail: context.email, userContextProfilePictureUrl: context.profilePictureUrl, + userContextOrigin: context.origin, userId: user ? user.id : null, }, { transaction: t } @@ -1189,6 +1190,7 @@ export async function* editUserMessage( userContextEmail: userMessageRow.userContextEmail, userContextProfilePictureUrl: userMessageRow.userContextProfilePictureUrl, + userContextOrigin: userMessageRow.userContextOrigin, userId: userMessageRow.userId, }, { transaction: t } diff --git a/front/lib/api/assistant/messages.ts b/front/lib/api/assistant/messages.ts index a1105c388f52..9813ec9557da 100644 --- a/front/lib/api/assistant/messages.ts +++ b/front/lib/api/assistant/messages.ts @@ -109,6 +109,7 @@ export async function batchRenderUserMessages( fullName: userMessage.userContextFullName, email: userMessage.userContextEmail, profilePictureUrl: userMessage.userContextProfilePictureUrl, + origin: userMessage.userContextOrigin, }, } satisfies UserMessageType; return { m, rank: message.rank, version: message.version }; diff --git a/front/lib/models/assistant/conversation.ts b/front/lib/models/assistant/conversation.ts index 37da982a2589..a6b80ad8ddf2 100644 --- a/front/lib/models/assistant/conversation.ts +++ b/front/lib/models/assistant/conversation.ts @@ -3,6 +3,7 @@ import type { ConversationVisibility, MessageVisibility, ParticipantActionType, + UserMessageOrigin, } from "@dust-tt/types"; import type { CreationOptional, @@ -175,6 +176,7 @@ export class UserMessage extends Model< declare userContextFullName: string | null; declare userContextEmail: string | null; declare userContextProfilePictureUrl: string | null; + declare userContextOrigin: UserMessageOrigin | null; declare userId: ForeignKey | null; } @@ -220,6 +222,10 @@ UserMessage.init( type: DataTypes.STRING(2048), allowNull: true, }, + userContextOrigin: { + type: DataTypes.STRING, + allowNull: true, + }, }, { modelName: "user_message", diff --git a/front/lib/workspace_usage.ts b/front/lib/workspace_usage.ts index 8257295f66c6..33ab42ea325a 100644 --- a/front/lib/workspace_usage.ts +++ b/front/lib/workspace_usage.ts @@ -51,13 +51,7 @@ export async function unsafeGetUsageData( WHEN COUNT(DISTINCT arc."id") + COUNT(DISTINCT atqc."id") + COUNT(DISTINCT adarc."id") > 1 THEN 'multiActions' ELSE NULL END AS "actionType", - CASE - WHEN um."id" IS NOT NULL THEN - CASE - WHEN um."userId" IS NOT NULL THEN 'web' - ELSE 'slack' - END - END AS "source" + um."userContextOrigin" AS "source" FROM "messages" m JOIN diff --git a/front/migrations/20240620_backfill_user_message_origin.sql b/front/migrations/20240620_backfill_user_message_origin.sql new file mode 100644 index 000000000000..12aafa23fe81 --- /dev/null +++ b/front/migrations/20240620_backfill_user_message_origin.sql @@ -0,0 +1,5 @@ +UPDATE user_messages SET "userContextOrigin" = 'slack' WHERE "userContextOrigin" IS NULL AND "userContextProfilePictureUrl" ILIKE '%slack%'; +UPDATE user_messages SET "userContextOrigin" = 'web' WHERE "userContextOrigin" IS NULL AND "userId" IS NOT NULL; +UPDATE user_messages SET "userContextOrigin" = 'api' WHERE "userContextOrigin" IS NULL AND "userId" IS NULL; + +SELECT "userContextOrigin", COUNT(*) FROM user_messages GROUP BY "userContextOrigin"; diff --git a/front/migrations/db/migration_24.sql b/front/migrations/db/migration_24.sql new file mode 100644 index 000000000000..0dd29cfefbc3 --- /dev/null +++ b/front/migrations/db/migration_24.sql @@ -0,0 +1,2 @@ +-- Migration created on Jun 20, 2024 +ALTER TABLE "public"."user_messages" ADD COLUMN "userContextOrigin" VARCHAR(255); diff --git a/front/pages/api/v1/w/[wId]/assistant/conversations/[cId]/messages/index.ts b/front/pages/api/v1/w/[wId]/assistant/conversations/[cId]/messages/index.ts index 34f3a7f8f361..473d28b6f3e8 100644 --- a/front/pages/api/v1/w/[wId]/assistant/conversations/[cId]/messages/index.ts +++ b/front/pages/api/v1/w/[wId]/assistant/conversations/[cId]/messages/index.ts @@ -103,7 +103,10 @@ async function handler( conversation, content, mentions, - context, + context: { + ...context, + origin: context.origin ?? "api", + }, }, { resolveAfterFullGeneration: blocking === true } ); diff --git a/front/pages/api/v1/w/[wId]/assistant/conversations/index.ts b/front/pages/api/v1/w/[wId]/assistant/conversations/index.ts index f19a87bc9d5c..40e1da579e95 100644 --- a/front/pages/api/v1/w/[wId]/assistant/conversations/index.ts +++ b/front/pages/api/v1/w/[wId]/assistant/conversations/index.ts @@ -176,6 +176,7 @@ async function handler( fullName: message.context.fullName, email: message.context.email, profilePictureUrl: message.context.profilePictureUrl, + origin: message.context.origin ?? "api", }, }, { resolveAfterFullGeneration: blocking === true } diff --git a/front/pages/api/w/[wId]/assistant/conversations/[cId]/messages/index.ts b/front/pages/api/w/[wId]/assistant/conversations/[cId]/messages/index.ts index 41ccfe52040d..da8eda8d7473 100644 --- a/front/pages/api/w/[wId]/assistant/conversations/[cId]/messages/index.ts +++ b/front/pages/api/w/[wId]/assistant/conversations/[cId]/messages/index.ts @@ -156,6 +156,7 @@ async function handler( fullName: user.fullName, email: user.email, profilePictureUrl: context.profilePictureUrl ?? user.image, + origin: "web", }, }, { resolveAfterFullGeneration: false } diff --git a/front/pages/api/w/[wId]/assistant/conversations/index.ts b/front/pages/api/w/[wId]/assistant/conversations/index.ts index 82c032bc8d01..f500e5ab9488 100644 --- a/front/pages/api/w/[wId]/assistant/conversations/index.ts +++ b/front/pages/api/w/[wId]/assistant/conversations/index.ts @@ -149,10 +149,9 @@ async function handler( } if (message) { - /* If a message was provided we do await for the message to be created - before returning the conversation along with the message. - PostUserMessageWithPubSub returns swiftly since it only waits for the - initial message creation event (or error) */ + // If a message was provided we do await for the message to be created before returning the + // conversation along with the message. PostUserMessageWithPubSub returns swiftly since it + // only waits for the initial message creation event (or error) */ const messageRes = await postUserMessageWithPubSub( auth, { @@ -165,6 +164,7 @@ async function handler( fullName: user.fullName, email: user.email, profilePictureUrl: message.context.profilePictureUrl, + origin: "web", }, }, { resolveAfterFullGeneration: false } diff --git a/front/temporal/labs/activities.ts b/front/temporal/labs/activities.ts index f91c3b7478d9..6f8db7bd6eea 100644 --- a/front/temporal/labs/activities.ts +++ b/front/temporal/labs/activities.ts @@ -257,6 +257,7 @@ export async function processTranscriptActivity( fullName: user.name, email: user.email, profilePictureUrl: user.imageUrl, + origin: null, }, }, contentFragment: { diff --git a/types/src/front/api_handlers/public/assistant.ts b/types/src/front/api_handlers/public/assistant.ts index 4672f5623586..7327fdf65ee7 100644 --- a/types/src/front/api_handlers/public/assistant.ts +++ b/types/src/front/api_handlers/public/assistant.ts @@ -18,6 +18,13 @@ export const PublicPostMessagesRequestBodySchema = t.intersection([ fullName: t.union([t.string, t.null]), email: t.union([t.string, t.null]), profilePictureUrl: t.union([t.string, t.null]), + origin: t.union([ + t.literal("slack"), + t.literal("web"), + t.literal("api"), + t.null, + t.undefined, + ]), }), }), t.partial({ diff --git a/types/src/front/assistant/conversation.ts b/types/src/front/assistant/conversation.ts index 79a6877ae352..92c6b3f8e386 100644 --- a/types/src/front/assistant/conversation.ts +++ b/types/src/front/assistant/conversation.ts @@ -52,12 +52,15 @@ export type MessageWithRankType = WithRank; * User messages */ +export type UserMessageOrigin = "slack" | "web" | "api"; + export type UserMessageContext = { username: string; timezone: string; fullName: string | null; email: string | null; profilePictureUrl: string | null; + origin: UserMessageOrigin | null; }; export type UserMessageType = {