diff --git a/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/RetroTopic.tsx b/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/RetroTopic.tsx index d89d5c32738..b5b46325d23 100644 --- a/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/RetroTopic.tsx +++ b/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/RetroTopic.tsx @@ -90,7 +90,6 @@ const RetroTopic = (props: Props) => { reflections { ...EmailReflectionCard_reflection } - discussionPromptQuestion } discussion { commentCount @@ -121,7 +120,7 @@ const RetroTopic = (props: Props) => { const {reflectionGroup, discussion, id: stageId} = stage const {commentCount, discussionSummary} = discussion - const {reflections, title, voteCount, discussionPromptQuestion} = reflectionGroup! + const {reflections, title, voteCount} = reflectionGroup! const imageSource = isEmail ? 'static' : 'local' const icon = imageSource === 'local' ? 'thumb_up_18.svg' : 'thumb_up_18@3x.png' const src = `${ExternalLinks.EMAIL_CDN}${icon}` @@ -143,29 +142,15 @@ const RetroTopic = (props: Props) => { - {(discussionPromptQuestion || discussionSummary) && ( + {discussionSummary && ( - {discussionPromptQuestion && ( - <> - - {'🤖 Discussion Question'} - - - {discussionPromptQuestion} - - - )} - {discussionSummary && ( - <> - - {'🤖 Discussion Summary'} - - - {discussionSummary} - - - )} + + {'🤖 Discussion Summary'} + + + {discussionSummary} + )} diff --git a/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/WholeMeetingSummary.tsx b/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/WholeMeetingSummary.tsx index 5bc27573613..820491bffde 100644 --- a/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/WholeMeetingSummary.tsx +++ b/packages/client/modules/email/components/SummaryEmail/MeetingSummaryEmail/WholeMeetingSummary.tsx @@ -26,16 +26,8 @@ const WholeMeetingSummary = (props: Props) => { } ... on RetrospectiveMeeting { reflectionGroups(sortBy: voteCount) { - summary - } - phases { - phaseType - ... on DiscussPhase { - stages { - discussion { - summary - } - } + reflections { + id } } } @@ -49,14 +41,11 @@ const WholeMeetingSummary = (props: Props) => { meetingRef ) if (meeting.__typename === 'RetrospectiveMeeting') { - const {summary: wholeMeetingSummary, reflectionGroups, phases} = meeting - const discussPhase = phases!.find((phase) => phase.phaseType === 'discuss') - const {stages} = discussPhase ?? {} - const hasTopicSummary = reflectionGroups!.some((group) => group.summary) - const hasDiscussionSummary = !!stages?.some((stage) => stage.discussion?.summary) - const hasOpenAISummary = hasTopicSummary || hasDiscussionSummary - if (!hasOpenAISummary) return null - if (hasOpenAISummary && !wholeMeetingSummary) return + const {summary: wholeMeetingSummary, reflectionGroups, organization} = meeting + const reflections = reflectionGroups?.flatMap((group) => group.reflections) // reflectionCount hasn't been calculated yet so check reflections length + const hasMoreThanOneReflection = reflections?.length && reflections.length > 1 + if (!hasMoreThanOneReflection || organization.featureFlags.noAISummary) return null + if (!wholeMeetingSummary) return return } else if (meeting.__typename === 'TeamPromptMeeting') { const {summary: wholeMeetingSummary, responses, organization} = meeting diff --git a/packages/client/mutations/EndRetrospectiveMutation.ts b/packages/client/mutations/EndRetrospectiveMutation.ts index 5d27418cdd1..f087fbe1197 100644 --- a/packages/client/mutations/EndRetrospectiveMutation.ts +++ b/packages/client/mutations/EndRetrospectiveMutation.ts @@ -31,8 +31,12 @@ graphql` autogroupReflectionGroups { groupTitle } + organization { + featureFlags { + noAISummary + } + } reflectionGroups(sortBy: voteCount) { - summary reflections { id } @@ -43,13 +47,6 @@ graphql` } phases { phaseType - ... on DiscussPhase { - stages { - discussion { - summary - } - } - } } } team { @@ -109,7 +106,14 @@ export const endRetrospectiveTeamOnNext: OnNextHandler< const {isKill, meeting} = payload const {atmosphere, history} = context if (!meeting) return - const {id: meetingId, teamId, reflectionGroups, phases, autogroupReflectionGroups} = meeting + const { + id: meetingId, + teamId, + reflectionGroups, + phases, + autogroupReflectionGroups, + organization + } = meeting if (meetingId === RetroDemo.MEETING_ID) { if (isKill) { window.localStorage.removeItem('retroDemo') @@ -122,12 +126,9 @@ export const endRetrospectiveTeamOnNext: OnNextHandler< history.push(`/team/${teamId}`) popEndMeetingToast(atmosphere, meetingId) } else { - const discussPhase = phases.find((phase) => phase.phaseType === 'discuss') - const {stages} = discussPhase ?? {} - const hasTopicSummary = reflectionGroups.some((group) => group.summary) const reflections = reflectionGroups.flatMap((group) => group.reflections) // reflectionCount hasn't been calculated yet so check reflections length - const hasDiscussionSummary = !!stages?.some((stage) => stage.discussion?.summary) - const hasOpenAISummary = hasTopicSummary || hasDiscussionSummary + const hasMoreThanOneReflection = reflections.length > 1 + const hasOpenAISummary = hasMoreThanOneReflection && !organization.featureFlags.noAISummary const hasTeamHealth = phases.some((phase) => phase.phaseType === 'TEAM_HEALTH') const pathname = `/new-summary/${meetingId}` const search = new URLSearchParams() diff --git a/packages/server/graphql/mutations/helpers/addAIGeneratedContentToThreads.ts b/packages/server/graphql/mutations/helpers/addAIGeneratedContentToThreads.ts index 50b385c6a8f..fa513232f98 100644 --- a/packages/server/graphql/mutations/helpers/addAIGeneratedContentToThreads.ts +++ b/packages/server/graphql/mutations/helpers/addAIGeneratedContentToThreads.ts @@ -1,11 +1,9 @@ -import {AIExplainer} from '../../../../client/types/constEnums' import {PARABOL_AI_USER_ID} from '../../../../client/utils/constants' import getRethink from '../../../database/rethinkDriver' import Comment from '../../../database/types/Comment' import DiscussStage from '../../../database/types/DiscussStage' import {convertHtmlToTaskContent} from '../../../utils/draftjs/convertHtmlToTaskContent' import {DataLoaderWorker} from '../../graphql' -import {getFeatureTier} from '../../types/helpers/getFeatureTier' export const buildCommentContentBlock = ( title: string, @@ -28,33 +26,17 @@ export const createAIComment = (discussionId: string, content: string, order: nu const addAIGeneratedContentToThreads = async ( stages: DiscussStage[], meetingId: string, - teamId: string, dataLoader: DataLoaderWorker ) => { - const [r, groups, team] = await Promise.all([ + const [r, groups] = await Promise.all([ getRethink(), - dataLoader.get('retroReflectionGroupsByMeetingId').load(meetingId), - dataLoader.get('teams').loadNonNull(teamId) + dataLoader.get('retroReflectionGroupsByMeetingId').load(meetingId) ]) - const commentPromises = stages.map(async ({discussionId, reflectionGroupId}, idx) => { + const commentPromises = stages.map(async ({discussionId, reflectionGroupId}) => { const group = groups.find((group) => group.id === reflectionGroupId) - if (!group?.summary && !group?.discussionPromptQuestion) return + if (!group?.discussionPromptQuestion) return const comments: Comment[] = [] - if (group.summary) { - const topicSummaryExplainerText = - idx === 0 - ? getFeatureTier(team) === 'starter' - ? AIExplainer.STARTER - : AIExplainer.PREMIUM_REFLECTIONS - : undefined - const topicSummaryComment = createAIComment( - discussionId, - buildCommentContentBlock('🤖 Topic Summary', group.summary, topicSummaryExplainerText), - 0 - ) - comments.push(topicSummaryComment) - } if (group.discussionPromptQuestion) { const topicSummaryComment = createAIComment( discussionId, diff --git a/packages/server/graphql/mutations/helpers/generateGroupSummaries.ts b/packages/server/graphql/mutations/helpers/generateDiscussionPrompt.ts similarity index 68% rename from packages/server/graphql/mutations/helpers/generateGroupSummaries.ts rename to packages/server/graphql/mutations/helpers/generateDiscussionPrompt.ts index 3a827ca20d1..bb7a245ca2f 100644 --- a/packages/server/graphql/mutations/helpers/generateGroupSummaries.ts +++ b/packages/server/graphql/mutations/helpers/generateDiscussionPrompt.ts @@ -5,7 +5,7 @@ import sendToSentry from '../../../utils/sendToSentry' import {DataLoaderWorker} from '../../graphql' import canAccessAISummary from './canAccessAISummary' -const generateGroupSummaries = async ( +const generateDiscussionPrompt = async ( meetingId: string, teamId: string, dataLoader: DataLoaderWorker, @@ -30,7 +30,7 @@ const generateGroupSummaries = async ( const pg = getKysely() const manager = new OpenAIServerManager() if (!reflectionGroups.length) { - const error = new Error('No reflection groups in generateGroupSummaries') + const error = new Error('No reflection groups in generateDiscussionPrompt') sendToSentry(error, {userId: facilitator.id, tags: {meetingId}}) return } @@ -40,30 +40,22 @@ const generateGroupSummaries = async ( ({reflectionGroupId}) => reflectionGroupId === group.id ) if (reflectionsByGroupId.length <= 1) return - const reflectionTextByGroupId = reflectionsByGroupId.map( - ({plaintextContent}) => plaintextContent + const fullQuestion = await manager.getDiscussionPromptQuestion( + group.title ?? 'Unknown', + reflectionsByGroupId ) - const [fullSummary, fullQuestion] = await Promise.all([ - manager.getSummary(reflectionTextByGroupId), - manager.getDiscussionPromptQuestion(group.title ?? 'Unknown', reflectionsByGroupId) - ]) - if (!fullSummary && !fullQuestion) return - const summary = fullSummary?.slice(0, 2000) + if (!fullQuestion) return const discussionPromptQuestion = fullQuestion?.slice(0, 2000) return Promise.all([ pg .updateTable('RetroReflectionGroup') - .set({summary, discussionPromptQuestion}) + .set({discussionPromptQuestion}) .where('id', '=', group.id) .execute(), - r - .table('RetroReflectionGroup') - .get(group.id) - .update({summary, discussionPromptQuestion}) - .run() + r.table('RetroReflectionGroup').get(group.id).update({discussionPromptQuestion}).run() ]) }) ) } -export default generateGroupSummaries +export default generateDiscussionPrompt diff --git a/packages/server/graphql/mutations/helpers/handleCompletedStage.ts b/packages/server/graphql/mutations/helpers/handleCompletedStage.ts index 785568a6396..8227ec6fe69 100644 --- a/packages/server/graphql/mutations/helpers/handleCompletedStage.ts +++ b/packages/server/graphql/mutations/helpers/handleCompletedStage.ts @@ -13,8 +13,8 @@ import {DataLoaderWorker} from '../../graphql' import addAIGeneratedContentToThreads from './addAIGeneratedContentToThreads' import addDiscussionTopics from './addDiscussionTopics' import addRecallBot from './addRecallBot' +import generateDiscussionPrompt from './generateDiscussionPrompt' import generateDiscussionSummary from './generateDiscussionSummary' -import generateGroupSummaries from './generateGroupSummaries' import generateGroups from './generateGroups' import {publishToEmbedder} from './publishToEmbedder' import removeEmptyReflections from './removeEmptyReflections' @@ -92,7 +92,7 @@ const handleCompletedRetrospectiveStage = async ( .run() data.meeting = meeting // dont await for the OpenAI API response - generateGroupSummaries(meeting.id, teamId, dataLoader, facilitatorUserId) + generateDiscussionPrompt(meeting.id, teamId, dataLoader, facilitatorUserId) } return {[stage.phaseType]: data} @@ -112,7 +112,7 @@ const handleCompletedRetrospectiveStage = async ( })) await Promise.all([ insertDiscussions(discussions), - addAIGeneratedContentToThreads(discussPhaseStages, meetingId, teamId, dataLoader), + addAIGeneratedContentToThreads(discussPhaseStages, meetingId, dataLoader), publishToEmbedder({jobType: 'relatedDiscussions:start', data: {meetingId}, priority: 0}) ]) if (videoMeetingURL) { diff --git a/packages/server/graphql/types/Discussion.ts b/packages/server/graphql/types/Discussion.ts index 556401ba1cc..cdc01159736 100644 --- a/packages/server/graphql/types/Discussion.ts +++ b/packages/server/graphql/types/Discussion.ts @@ -155,7 +155,7 @@ const Discussion = new GraphQLObjectType({ }, summary: { type: GraphQLString, - description: `The GPT-3 generated summary of the discussion. Undefined if the user doesnt have access to the feature or the stage isn't completed` + description: `The AI generated summary of the discussion. Undefined if the user doesnt have access to the feature or the stage isn't completed` } }) }) diff --git a/packages/server/graphql/types/RetroReflectionGroup.ts b/packages/server/graphql/types/RetroReflectionGroup.ts index 87dca57750f..7fb07754d0c 100644 --- a/packages/server/graphql/types/RetroReflectionGroup.ts +++ b/packages/server/graphql/types/RetroReflectionGroup.ts @@ -87,10 +87,6 @@ const RetroReflectionGroup: GraphQLObjectType = new GraphQLObjectType