Skip to content

Commit

Permalink
feat: add ask support (non-stream) (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
anfibiacreativa authored Oct 11, 2023
1 parent 67dac3e commit 31a5d67
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 21 deletions.
8 changes: 6 additions & 2 deletions packages/chat-component/src/config/global-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const globalConfig = {
'How to cancel a confirmed booking',
'How to report a payment or refund issue, for example if a guest or host is asking to pay or be paid outside of the Contoso Real Estate platform',
],
DEFAULT_PROMPTS_HEADING: 'Start a conversation with our support team.',
DEFAULT_PROMPTS_HEADING_CHAT: 'Chat with our support team',
DEFAULT_PROMPTS_HEADING_ASK: 'Ask a question',
// This are the chat bubbles that will be displayed in the chat
CHAT_MESSAGES: [],
// This are the labels for the chat button and input
Expand Down Expand Up @@ -48,5 +49,8 @@ const chatHttpOptions = {
method: 'POST',
stream: true,
};
// these can be set from developer settings!
const INTERACTION_MODEL = ['chat', 'ask'];
const APPROACH_MODEL = ['rrr', 'rtr'];

export { globalConfig, requestOptions, chatHttpOptions, NEXT_QUESTION_INDICATOR };
export { globalConfig, requestOptions, chatHttpOptions, NEXT_QUESTION_INDICATOR, INTERACTION_MODEL, APPROACH_MODEL };
33 changes: 20 additions & 13 deletions packages/chat-component/src/core/http/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@ export async function callHttpApi(
{ question, type, approach, overrides }: ChatRequestOptions,
{ method, url, stream }: ChatHttpOptions,
) {
const chatBody = JSON.stringify({
history: [
{
user: question,
},
],
approach,
overrides,
stream,
});
const askBody = JSON.stringify({
question,
approach,
overrides,
stream: false,
});
const body = type === 'chat' ? chatBody : askBody;
return await fetch(`${url}${type}`, {
method: method,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
// must enable history persistence
history: [
{
user: question,
},
],
approach,
overrides,
stream,
}),
body,
});
}

Expand All @@ -26,8 +33,8 @@ export async function getAPIResponse(
httpOptions: ChatHttpOptions,
): Promise<BotResponse | Response> {
const response = await callHttpApi(requestOptions, httpOptions);

if (httpOptions.stream) {
const streamResponse = requestOptions.type === 'ask' ? false : httpOptions.stream;
if (streamResponse) {
return response;
}

Expand Down
22 changes: 16 additions & 6 deletions packages/chat-component/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { LitElement, html } from 'lit';
import DOMPurify from 'dompurify';
import { customElement, property, query } from 'lit/decorators.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { chatHttpOptions, globalConfig, requestOptions } from './config/global-config.js';
import { chatHttpOptions, globalConfig, requestOptions, INTERACTION_MODEL } from './config/global-config.js';
import { getAPIResponse } from './core/http/index.js';
import { parseStreamedMessages } from './core/parser/index.js';
import { mainStyle } from './style.js';
Expand Down Expand Up @@ -43,6 +43,11 @@ export class ChatComponent extends LitElement {
isResponseCopied = false;
@property({ type: Boolean })
isStreaming = false;
// interaction type: should come from dynamic settings
// INTERACTION_MODEL defines the UI presentation and behavior
// but for now we can switch between 'chat' and 'ask', using this
@property({ type: String })
interactionModel = INTERACTION_MODEL[0];
// api response
apiResponse = {} as BotResponse | Response;
// These are the chat bubbles that will be displayed in the chat
Expand Down Expand Up @@ -139,28 +144,29 @@ export class ChatComponent extends LitElement {
// Handle the click on the chat button and send the question to the API
async handleUserChatSubmit(event: Event): Promise<void> {
event.preventDefault();
const type = 'chat';
const question = DOMPurify.sanitize(this.questionInput.value);
if (question) {
this.currentQuestion = question;
try {
this.isStreaming = type === 'chat' && this.chatHttpOptions.stream;
const type = this.interactionModel;
this.isStreaming = type === 'ask' ? false : this.chatHttpOptions.stream;
// Remove default prompts
this.isChatStarted = true;
this.hasDefaultPromptsEnabled = false;
// Disable the input field and submit button while waiting for the API response
this.isDisabled = true;
// Show loading indicator while waiting for the API response
this.processApiResponse({ message: question, isUserMessage: true });

this.isAwaitingResponse = true;
if (type === 'chat') {
this.processApiResponse({ message: question, isUserMessage: true });
}
this.apiResponse = await getAPIResponse({ ...this.chatRequestOptions, question, type }, this.chatHttpOptions);

this.questionInput.value = '';
this.isAwaitingResponse = false;
this.isDisabled = false;
this.isResetInput = false;

const response = this.apiResponse as BotResponse;
const message: string = response.answer;
await this.processApiResponse({ message, isUserMessage: false });
Expand Down Expand Up @@ -356,7 +362,11 @@ export class ChatComponent extends LitElement {
${this.hasDefaultPromptsEnabled
? html`
<div class="defaults__container">
<h2 class="subheadline">${this.defaultPromptsHeading}</h2>
<h2 class="subheadline">
${this.interactionModel === 'chat'
? globalConfig.DEFAULT_PROMPTS_HEADING_CHAT
: globalConfig.DEFAULT_PROMPTS_HEADING_ASK}
</h2>
<ul class="defaults__list">
${this.defaultPrompts.map(
(prompt) => html`
Expand Down

0 comments on commit 31a5d67

Please sign in to comment.