Closed shahbazsyed closed 3 months ago
Hi @shahbazsyed.
The problem is that custom elements inside Deep Chat are no longer controlled by the parent framework and use the standard web component syntax. Hence they should not be treated like Vue elements.
Let me know if this helps. Thanks!
Hi,
Does not seem to work. I still get undefined
when I log it. Here is some more code for context.
Custom component is SFC (separate .vue file)
ChatView.vue
<template>
<deep-chat :responseInterceptor />
</template>
<script setup lang="ts">
import 'deep-chat'
import { defineCustomElement } from 'vue'
const ButtonComponent = defineCustomElement({
props:['modelResponse'],
setup(props, {emit}){
const handleClick = () => {console.log(props.modelResponse)} // undefined!
},
return {handleClick}
},
template: `<button @click="handleClick">Click Me</button>`
})
// Register custom element
customElements.define('custom-button', ButtonComponent)
// The `responseInterceptor` function:
function responseInterceptor(response){
return {
text: response.choices[0].message.content,
html: '<custom-button modelResponse="text"></custom-button>'
}
}
</script>
App.vue
<template>
<div>
<ChatView/>
</div>
</template>
<script setup lang="ts">
import ChatView from '.views/ChatView.vue'
</script>
I also inspected in the dev tools that when this <custom-button>
is actually rendered, the modelResponse
prop is changed to modelresponse
in the DOM and has the value "text" (i.e. the text
property that stores the actual result in the responseInterceptor
is not substituted )
Sorry I missed that you are actually using "text" property name. Based on your last comment, here is a better example:
function responseInterceptor(response){
const textResponse = response.choices[0].message.content;
return {
text: textResponse,
html: `<custom-button modelresponse="${textResponse}"></custom-button>`
}
}
Let me know if this works for you, thanks!
This is also unfortunately rendered as the string "${response}" and not interpolated.
I figured out another way to get access to the response
object directly in the event handler of the click event. I created a reactive property in my ChatView.vue
component using const modelResponse = ref('')
and then in the responseInterceptor
function I set this property to the actual response text. Now I can directly access this in the handleClick()
function in the ButtonComponent
.
I am not sure if this is optimal but it works for now. Would like to hear your opinion or if there is a better way to do this. PS: I am new to Vue so still figuring out the best practices.
Here is a better way of doing it:
const ButtonComponent = defineCustomElement({
props: ['modelResponse'],
methods: {
handleClick() {
console.log(this.modelResponse);
},
},
template: `<button @click="handleClick">Click Me</button>`,
});
customElements.define('custom-button', ButtonComponent);
- The response interceptor should then have this code:
responseInterceptor(response) {
const textResponse = response.choices[0].message.content;
return {
text: textResponse,
html: <custom-button model-response="${textResponse}"></custom-button>
,
};
},
I have tested it locally and it works for me. Let me know if it works for you.
Thanks!
It still gives me the string "$(textResponse)" in the output. PS I renamed the modelResponse
prop to reply
Can you share your .vue
file used for testing locally? May be I am mixing up the composition API and the options API (which ideally isn't a problem) and would like to double check.
Hi @shahbazsyed.
Here is the full code I used, you will have to tailor it to your setup:
<template>
<deep-chat :demo="true" :responseInterceptor="responseInterceptor" />
</template>
<script>
import 'deep-chat';
import { defineCustomElement } from 'vue';
const ButtonComponent = defineCustomElement({
props: ['modelResponse'],
methods: {
handleClick() {
console.log(this.modelResponse);
},
},
template: `<button @click="handleClick">Click Me</button>`,
});
customElements.define('custom-button', ButtonComponent);
export default {
methods: {
responseInterceptor(response) {
const textResponse = response.text;
return {
text: textResponse,
html: `<custom-button model-response="${textResponse}"></custom-button>`,
};
},
},
};
</script>
Let me know id you have any other issues. Thanks!
Thanks! I realised my mistake. I accidentally used regular single quotes instead of back ticks in the html template that I was returning. This caused the interpolation to fail.
Thanks for your patience in resolving this issue.
Hi, Thanks for the nice work!
I am using deep-chat in Vue and have the following situation: I am connecting to the OpenAI API via
request
and add a custom element (button
) to the response via theresponseInterceptor
.Here is my custom button defined as a Web component using
defineCustomElement
. Notice themodelResponse
prop that I am adding to this custom element.Here is how I add it to the
html
usingresponseInterceptor
. Please note the way I am trying to pass the text value tomodelResponse
prop.My issue now is that this
modelResponse
prop is undefined when I log it to the console and I can't figure out if I am doing it wrong. Any guidance here would be highly appreciated.My goal is to eventually use the model response inside an event handler for the click event on my custom button to do some additional processing, for example, opening a modal that displays the response text in a specific style. For this, I would need to pass the response to the event that opens this modal.
I looked at the examples of events in
htmlClassUtilities
but could not find anything on how to pass/communicate with the response object on events dispatched by custom elements.Thanks again!