Skip to content

Commit

Permalink
[UXE-4942] feat: add Azion Copilot with deepchat to AI Chat component (
Browse files Browse the repository at this point in the history
…#1783)

* Added new routes and origins in azion.config.cjs for the Azion Copilot.
* Updated the AI Chat component to use new interceptor services and handle user prompts more effectively.
* Introduced contextual prompts for domain creation and editing.
  • Loading branch information
HerbertJulio authored Oct 3, 2024
1 parent 09271a5 commit 9c0c520
Show file tree
Hide file tree
Showing 14 changed files with 321 additions and 110 deletions.
19 changes: 19 additions & 0 deletions azion.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,19 @@ const backRules = [
},
rewrite: '/webhook/console_feedback'
}
},
{
name: 'Route Send Message to Copilot',
description: 'this router will send the user message to the chatbot',
match: '^/ai',
behavior: {
forwardCookies: true,
setOrigin: {
name: 'origin-console-ai',
type: 'single_origin'
},
rewrite: '/chat-completions'
}
}
]

Expand Down Expand Up @@ -303,6 +316,12 @@ const AzionConfig = {
hostHeader: `automate.azion.net`,
addresses: [`automate.azion.net`]
},
{
name: 'origin-console-ai',
type: 'single_origin',
hostHeader: `ivg5gk272b.map.azionedge.net`,
addresses: [`ivg5gk272b.map.azionedge.net`]
}
],
rules: {
request: [...commonRules, ...frontRules, ...backRules],
Expand Down
68 changes: 43 additions & 25 deletions src/modules/azion-ai-chat/azion-ai-chat-block.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,8 @@
:textInput="textInputStyles"
:submitButtonStyles="submitButtonStyles"
:request="makeRequestConfig()"
:requestInterceptor="
(requestDetails) =>
requestInterceptorService(requestDetails, {
sessionId: aiAskAzionSessionId,
url: currentRouteFullPath,
userName: account.name
})
"
:requestInterceptor="interceptor"
:responseInterceptor="responseInterceptorService"
>
<div class="deep-chat-temporary-message">
<div :style="`display:flex;align-items:center;flex-direction:column;gap:2rem;`">
Expand Down Expand Up @@ -46,7 +40,10 @@
import suggestionIconMetrics from './assets/suggestion-icon-metrics.svg?url'
import suggestionIconSecurity from './assets/suggestion-icon-security.svg?url'
import AzionAiChatSuggestion from './azion-ai-chat-suggestion.vue'
import { requestInterceptorService } from './services/request-interceptor-service'
import {
requestInterceptorService,
responseInterceptorService
} from './services/interceptor-service'
import { loadPromptSuggestion } from './services/load-prompt-suggestions'
import { makeRequestConfig } from './services/make-request-config'
import { makeSessionId } from './services/make-session-id'
Expand All @@ -55,27 +52,19 @@
import { useRouter } from 'vue-router'
import { useAccountStore } from '@/stores/account'
const { currentRoute } = useRouter()
const { account } = useAccountStore()
defineOptions({
name: 'azion-ai-chat-block'
})
onMounted(() => {
generateChatSessionId()
getUserNameInfo()
})
const accountStore = ref(null)
const deepChatRef = ref(null)
defineExpose({
deepChatRef
})
const currentRouteFullPath = currentRoute.value.path
const aiAskAzionSessionId = ref('')
const accountName = ref('')
const promptOrigin = ref(null)
const errorMessages = ref({
overrides: {
default: 'Connection failed. Try sending your message again.'
Expand Down Expand Up @@ -298,26 +287,55 @@
const handleSubmitSuggestion = (promptText) => {
deepChatRef.value.submitUserMessage({ text: promptText })
}
const generateChatSessionId = () => {
aiAskAzionSessionId.value = makeSessionId()
}
const getUserNameInfo = () => {
accountName.value = account.name
const submitUserMessageGetHelp = ({ user, system }) => {
promptOrigin.value = {
user_prompt: user,
system_prompt: system
}
deepChatRef.value.submitUserMessage({ text: user })
}
const calculateIconBySuggestionIndex = (index) => {
return index === 0 ? suggestionIconMetrics : suggestionIconSecurity
}
const interceptor = (requestDetails) => {
requestInterceptorService(requestDetails, {
sessionId: aiAskAzionSessionId.value,
url: currentRoute.value.path,
userName: accountStore.value.name,
clientId: accountStore.value.client_id,
prompt: promptOrigin.value,
allMessage: deepChatRef.value.getMessages()
})
}
const loadPromptSuggestionWithRoleDecorator = (role) => {
suggestionsOptions.value = loadPromptSuggestion(role)
}
watchEffect(() => {
const {
account: { jobRole }
} = useAccountStore()
const { account } = useAccountStore()
accountStore.value = account
loadPromptSuggestionWithRoleDecorator(accountStore.value.jobRole)
})
const clearMessages = () => {
deepChatRef.value.clearMessages()
promptOrigin.value = null
}
loadPromptSuggestionWithRoleDecorator(jobRole)
defineExpose({
deepChatRef,
clearMessages,
submitUserMessageGetHelp
})
</script>
./services/interceptor-service
22 changes: 21 additions & 1 deletion src/modules/azion-ai-chat/azion-ai-get-help.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
<script setup>
import PrimeButton from 'primevue/button'
import { computed } from 'vue'
defineOptions({ name: 'get-help' })
const props = defineProps({
prompt: {
type: String
},
context: {
type: Object,
default: null
}
})
const formatPrompt = computed(() => {
if (!props.context) return props.prompt
const replaceKeys = (text) => {
return Object.keys(props.context).reduce((str, key) => {
return str.replaceAll(`\${${key}}`, props.context[key])
}, text)
}
return {
user: replaceKeys(props.prompt.user),
system: replaceKeys(props.prompt.system)
}
})
</script>
Expand All @@ -17,6 +37,6 @@
label="Get Help"
icon="ai ai-ask-azion"
icon-pos="right"
v-prompt="props.prompt"
v-prompt="formatPrompt"
/>
</template>
43 changes: 38 additions & 5 deletions src/modules/azion-ai-chat/contextual-prompts/domains/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions src/modules/azion-ai-chat/contextual-prompts/generic/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/modules/azion-ai-chat/contextual-prompts/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import DomainsPrompts from './domains'
import Generic from './generic'

export { DomainsPrompts }
export { DomainsPrompts, Generic }
50 changes: 36 additions & 14 deletions src/modules/azion-ai-chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@

<div
class="h-full flex justify-between flex-col"
:key="renderCount"
v-if="isChatMobile"
>
<AzionAiChat ref="azionAiChatRef" />
<AzionAiChat
:key="renderCount"
ref="azionAiChatRef"
/>
</div>
<Sidebar
v-else
:visible="isChatAiOpen"
position="bottom"
headerContent="Copilot"
Expand All @@ -53,7 +57,6 @@
<div class="flex items-center justify-between">
<h2 class="flex items-center gap-2">
Copilot

<PrimeTag
class="ml-2"
value="Experimental"
Expand Down Expand Up @@ -110,11 +113,12 @@
import { useAzionAiChatStore } from '@/stores/azion-ai-chat-store'
import { updateSessionId } from './services/make-session-id'
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import hljs from 'highlight.js'
import { AZION_MESSAGE_TYPE } from '@modules/azion-ai-chat/directives/custom-ai-prompt'
import { useRouter } from 'vue-router'
import { windowOpen } from '@/helpers'
import { useWindowSize } from '@vueuse/core'
defineOptions({
name: 'azion-ai-chat-root-block'
Expand All @@ -123,6 +127,10 @@
const azionAiChatMobileRef = ref(null)
const renderCount = ref(1)
const router = useRouter()
const { width } = useWindowSize()
const currentWidth = ref(width.value)
const SCREEN_BREAKPOINT_MD = 768
onMounted(() => {
window.addEventListener('message', aiCustomPromptListenerHandler)
addSupportToHljs()
Expand All @@ -132,6 +140,10 @@
window.removeEventListener('message', aiCustomPromptListenerHandler)
})
const isChatMobile = computed(() => {
return currentWidth.value > SCREEN_BREAKPOINT_MD
})
const azionAiChatStore = useAzionAiChatStore()
const isChatAiOpen = computed(() => {
return azionAiChatStore.isOpen
Expand All @@ -148,24 +160,34 @@
}
const handleClearChat = () => {
azionAiChatRef?.value.deepChatRef.clearMessages()
azionAiChatMobileRef?.value.deepChatRef.clearMessages()
updateSessionId()
updateChatRenderInstance()
azionAiChatRef?.value?.clearMessages()
azionAiChatMobileRef?.value?.clearMessages()
updateSessionId()
}
const aiCustomPromptListenerHandler = (event) => {
if (event.data.type === AZION_MESSAGE_TYPE) {
azionAiChatStore.open()
azionAiChatRef?.value.deepChatRef.submitUserMessage({ text: event.data.prompt })
setTimeout(() => {
azionAiChatMobileRef?.value.deepChatRef.submitUserMessage({ text: event.data.prompt })
}, 100)
}
handleClearChat()
setTimeout(() => {
if (event.data.type === AZION_MESSAGE_TYPE) {
azionAiChatStore.open()
azionAiChatRef?.value?.submitUserMessageGetHelp(event.data.prompt)
azionAiChatMobileRef?.value?.submitUserMessageGetHelp(event.data.prompt)
}
}, 100)
}
const openChatInNewTab = () => {
const url = `${window.location.origin}${router.resolve({ name: 'copilot' }).path}`
windowOpen(url, '_blank')
}
watch(
width,
() => {
currentWidth.value = width.value
},
{ immediate: true }
)
</script>
Loading

0 comments on commit 9c0c520

Please sign in to comment.