feat: add prompt suggestions and June events (#10726)
This PR adds the following two features 1. Prompt suggestions to get started with Copilot Chat 2. June events for each action  --------- Co-authored-by: Pranav <pranavrajs@gmail.com>
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
<script setup>
|
||||
import { nextTick, ref, watch } from 'vue';
|
||||
import { useTrack } from 'dashboard/composables';
|
||||
import { COPILOT_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||
|
||||
import CopilotInput from './CopilotInput.vue';
|
||||
import CopilotLoader from './CopilotLoader.vue';
|
||||
import CopilotAgentMessage from './CopilotAgentMessage.vue';
|
||||
import CopilotAssistantMessage from './CopilotAssistantMessage.vue';
|
||||
import { nextTick, ref, watch } from 'vue';
|
||||
import Icon from '../icon/Icon.vue';
|
||||
|
||||
const props = defineProps({
|
||||
supportAgent: {
|
||||
@@ -24,13 +28,24 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['sendMessage']);
|
||||
const emit = defineEmits(['sendMessage', 'reset']);
|
||||
|
||||
const COPILOT_USER_ROLES = ['assistant', 'system'];
|
||||
|
||||
const sendMessage = message => {
|
||||
emit('sendMessage', message);
|
||||
useTrack(COPILOT_EVENTS.SEND_MESSAGE);
|
||||
};
|
||||
|
||||
const useSuggestion = opt => {
|
||||
emit('sendMessage', opt.prompt);
|
||||
useTrack(COPILOT_EVENTS.SEND_SUGGESTED);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
emit('reset');
|
||||
};
|
||||
|
||||
const chatContainer = ref(null);
|
||||
|
||||
const scrollToBottom = async () => {
|
||||
@@ -40,6 +55,21 @@ const scrollToBottom = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const promptOptions = [
|
||||
{
|
||||
label: 'Summarize this conversation',
|
||||
prompt: `Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent`,
|
||||
},
|
||||
{
|
||||
label: 'Suggest an answer',
|
||||
prompt: `Analyze the customer’s inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information.`,
|
||||
},
|
||||
{
|
||||
label: 'Rate this conversation',
|
||||
prompt: `Review the conversation to see how well it meets the customer’s needs. Share a rating out of 5 based on tone, clarity, and effectiveness.`,
|
||||
},
|
||||
];
|
||||
|
||||
watch(
|
||||
[() => props.messages, () => props.isCaptainTyping],
|
||||
() => {
|
||||
@@ -50,7 +80,7 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col ]mx-auto h-full text-sm leading-6 tracking-tight">
|
||||
<div class="flex flex-col h-full text-sm leading-6 tracking-tight">
|
||||
<div ref="chatContainer" class="flex-1 px-4 py-4 space-y-6 overflow-y-auto">
|
||||
<template v-for="message in messages" :key="message.id">
|
||||
<CopilotAgentMessage
|
||||
@@ -67,7 +97,32 @@ watch(
|
||||
|
||||
<CopilotLoader v-if="isCaptainTyping" />
|
||||
</div>
|
||||
|
||||
<CopilotInput class="mx-3 mt-px mb-4" @send="sendMessage" />
|
||||
<div>
|
||||
<div v-if="!messages.length" class="flex-1 px-3 py-3 space-y-1">
|
||||
<span class="text-xs text-n-slate-10">
|
||||
{{ $t('COPILOT.TRY_THESE_PROMPTS') }}
|
||||
</span>
|
||||
<button
|
||||
v-for="prompt in promptOptions"
|
||||
:key="prompt"
|
||||
class="px-2 py-1 rounded-md border border-n-weak bg-n-slate-2 text-n-slate-11 flex items-center gap-1"
|
||||
@click="() => useSuggestion(prompt)"
|
||||
>
|
||||
<span>{{ prompt.label }}</span>
|
||||
<Icon icon="i-lucide-chevron-right" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="mx-3 mt-px mb-2 flex flex-col items-end flex-1">
|
||||
<button
|
||||
v-if="messages.length"
|
||||
class="text-xs flex items-center gap-1 hover:underline"
|
||||
@click="handleReset"
|
||||
>
|
||||
<i class="i-lucide-refresh-ccw" />
|
||||
<span>{{ $t('CAPTAIN.COPILOT.RESET') }}</span>
|
||||
</button>
|
||||
<CopilotInput class="mb-1 flex-1 w-full" @send="sendMessage" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { emitter } from 'shared/helpers/mitt';
|
||||
import { useTrack } from 'dashboard/composables';
|
||||
|
||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||
import { INBOX_TYPES } from 'dashboard/helper/inbox';
|
||||
import { COPILOT_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||
import MessageFormatter from 'shared/helpers/MessageFormatter.js';
|
||||
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
import Avatar from '../avatar/Avatar.vue';
|
||||
@@ -18,6 +22,11 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const messageContent = computed(() => {
|
||||
const formatter = new MessageFormatter(props.message.content);
|
||||
return formatter.formattedMessage;
|
||||
});
|
||||
|
||||
const insertIntoRichEditor = computed(() => {
|
||||
return [INBOX_TYPES.WEB, INBOX_TYPES.EMAIL].includes(
|
||||
props.conversationInboxType
|
||||
@@ -30,6 +39,7 @@ const useCopilotResponse = () => {
|
||||
} else {
|
||||
emitter.emit(BUS_EVENTS.INSERT_INTO_NORMAL_EDITOR, props.message?.content);
|
||||
}
|
||||
useTrack(COPILOT_EVENTS.USE_CAPTAIN_RESPONSE);
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -43,9 +53,7 @@ const useCopilotResponse = () => {
|
||||
/>
|
||||
<div class="flex flex-col gap-1 text-n-slate-12">
|
||||
<div class="font-medium">{{ $t('CAPTAIN.NAME') }}</div>
|
||||
<div class="break-words">
|
||||
{{ message.content }}
|
||||
</div>
|
||||
<div v-dompurify-html="messageContent" class="prose-sm break-words" />
|
||||
<div class="flex flex-row mt-1">
|
||||
<Button
|
||||
:label="$t('CAPTAIN.COPILOT.USE')"
|
||||
|
||||
@@ -18,6 +18,10 @@ const messages = ref([]);
|
||||
|
||||
const isCaptainTyping = ref(false);
|
||||
|
||||
const handleReset = () => {
|
||||
messages.value = [];
|
||||
};
|
||||
|
||||
const sendMessage = async message => {
|
||||
// Add user message
|
||||
messages.value.push({
|
||||
@@ -62,5 +66,6 @@ const sendMessage = async message => {
|
||||
:is-captain-typing="isCaptainTyping"
|
||||
:conversation-inbox-type="conversationInboxType"
|
||||
@send-message="sendMessage"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -100,6 +100,12 @@ export const OPEN_AI_EVENTS = Object.freeze({
|
||||
DISMISS_AI_SUGGESTION: 'OpenAI: Dismiss AI suggestions',
|
||||
});
|
||||
|
||||
export const COPILOT_EVENTS = Object.freeze({
|
||||
SEND_SUGGESTED: 'Copilot: Send suggested message',
|
||||
SEND_MESSAGE: 'Copilot: Sent a message',
|
||||
USE_CAPTAIN_RESPONSE: 'Copilot: Used captain response',
|
||||
});
|
||||
|
||||
export const GENERAL_EVENTS = Object.freeze({
|
||||
COMMAND_BAR: 'Used commandbar',
|
||||
});
|
||||
|
||||
@@ -353,5 +353,8 @@
|
||||
"ONE": "{user} is typing",
|
||||
"TWO": "{user} and {secondUser} are typing",
|
||||
"MULTIPLE": "{user} and {count} others are typing"
|
||||
},
|
||||
"COPILOT": {
|
||||
"TRY_THESE_PROMPTS": "Try these prompts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,7 +306,8 @@
|
||||
"SEND_MESSAGE": "Send message...",
|
||||
"LOADER": "Captain is thinking",
|
||||
"YOU": "You",
|
||||
"USE": "Use this"
|
||||
"USE": "Use this",
|
||||
"RESET": "Reset"
|
||||
},
|
||||
"FORM": {
|
||||
"CANCEL": "Cancel",
|
||||
|
||||
Reference in New Issue
Block a user