diff --git a/chat_ui/Dockerfile.dev b/chat_ui/Dockerfile.dev deleted file mode 100644 index 881db05..0000000 --- a/chat_ui/Dockerfile.dev +++ /dev/null @@ -1,20 +0,0 @@ -# pull official base image -FROM node:14-slim - -# set working directory -WORKDIR /app - -# add `/app/node_modules/.bin` to $PATH -ENV PATH /app/node_modules/.bin:$PATH - -# install app dependencies -COPY package.json ./ -RUN npm install - -# add app -COPY . ./ - -EXPOSE 3001 - -# start app -CMD ["npm", "start"] \ No newline at end of file diff --git a/chat_ui/chat_deployment_dev.yaml b/chat_ui/chat_deployment_dev.yaml deleted file mode 100644 index 9520f72..0000000 --- a/chat_ui/chat_deployment_dev.yaml +++ /dev/null @@ -1,40 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: chat-service -spec: - ports: - - port: 80 - targetPort: 3001 - protocol: TCP - name: http - selector: - app: chat-app - # type: LoadBalancer - # loadBalancerIP: "34.118.4.64" - type: NodePort ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: chat-app -spec: - selector: - matchLabels: - app.kubernetes.io/name: chat-app-custom - replicas: 1 - template: - metadata: - labels: - app: chat-app - app.kubernetes.io/name: chat-app-custom - spec: - containers: - - name: chat - image: europe-west2-docker.pkg.dev/agentdialogue-2cd4b/task-mad-images-repository/chat:latest - #imagePullPolicy: Never - imagePullPolicy: Always - stdin: true - ports: - - containerPort: 3001 - diff --git a/chat_ui/chat_deployment_nginx.yaml b/chat_ui/deployment_config/cloud/chat_deployment.yaml similarity index 88% rename from chat_ui/chat_deployment_nginx.yaml rename to chat_ui/deployment_config/cloud/chat_deployment.yaml index e7a7f63..8d6aa7f 100644 --- a/chat_ui/chat_deployment_nginx.yaml +++ b/chat_ui/deployment_config/cloud/chat_deployment.yaml @@ -10,8 +10,6 @@ spec: name: http selector: app: chat-app - # type: LoadBalancer - # loadBalancerIP: "34.118.4.64" type: NodePort --- apiVersion: apps/v1 @@ -32,7 +30,6 @@ spec: containers: - name: chat image: europe-west2-docker.pkg.dev/agentdialogue-2cd4b/task-mad-images-repository/chat:latest - #imagePullPolicy: Never imagePullPolicy: Always stdin: true ports: diff --git a/chat_ui/chat_managed_cert.yaml b/chat_ui/deployment_config/cloud/chat_managed_cert.yaml similarity index 100% rename from chat_ui/chat_managed_cert.yaml rename to chat_ui/deployment_config/cloud/chat_managed_cert.yaml diff --git a/chat_ui/chat_managed_cert_ingress.yaml b/chat_ui/deployment_config/cloud/chat_managed_cert_ingress.yaml similarity index 100% rename from chat_ui/chat_managed_cert_ingress.yaml rename to chat_ui/deployment_config/cloud/chat_managed_cert_ingress.yaml diff --git a/chat_ui/cloudbuild.yaml b/chat_ui/deployment_config/cloud/cloudbuild.yaml similarity index 84% rename from chat_ui/cloudbuild.yaml rename to chat_ui/deployment_config/cloud/cloudbuild.yaml index 0f6d920..b38b8c0 100644 --- a/chat_ui/cloudbuild.yaml +++ b/chat_ui/deployment_config/cloud/cloudbuild.yaml @@ -13,7 +13,7 @@ steps: args: - apply - -f - - ${_ROOT_FOLDER}/${_FRONTEND_CONFIG_FILE} + - ${_ROOT_FOLDER}/${_CONFIG_PATH}/${_FRONTEND_CONFIG_FILE} env: - CLOUDSDK_COMPUTE_REGION=${_CLUSTER_LOCATION} - CLOUDSDK_CONTAINER_CLUSTER=${_CLUSTER_NAME} @@ -22,7 +22,7 @@ steps: args: - apply - -f - - ${_ROOT_FOLDER}/${_K8_FILE} + - ${_ROOT_FOLDER}/${_CONFIG_PATH}/${_K8_FILE} env: - CLOUDSDK_COMPUTE_REGION=${_CLUSTER_LOCATION} - CLOUDSDK_CONTAINER_CLUSTER=${_CLUSTER_NAME} @@ -31,21 +31,22 @@ steps: args: - apply - -f - - ${_ROOT_FOLDER}/${_INGRESS_FILE} + - ${_ROOT_FOLDER}/${_CONFIG_PATH}/${_INGRESS_FILE} env: - CLOUDSDK_COMPUTE_REGION=${_CLUSTER_LOCATION} - CLOUDSDK_CONTAINER_CLUSTER=${_CLUSTER_NAME} substitutions: - _ROOT_FOLDER: chat_ui _ARTIFACT_REGISTRY_REPOSITORY: task-mad-images-repository + _CLUSTER_LOCATION: europe-central2-a + _CLUSTER_NAME: chat-cluster _IMAGE_NAME: chat _IMAGE_VERSION: latest + _ROOT_FOLDER: chat_ui + _CONFIG_PATH: deployment_config/cloud _FRONTEND_CONFIG_FILE: frontend_config.yaml - _K8_FILE: chat_deployment_nginx.yaml _INGRESS_FILE: chat_managed_cert_ingress.yaml - _CLUSTER_LOCATION: europe-central2-a - _CLUSTER_NAME: chat-cluster + _K8_FILE: chat_deployment.yaml # Time out after 30 minutes diff --git a/chat_ui/frontend_config.yaml b/chat_ui/deployment_config/cloud/frontend_config.yaml similarity index 100% rename from chat_ui/frontend_config.yaml rename to chat_ui/deployment_config/cloud/frontend_config.yaml diff --git a/chat_ui/src/App.module.css b/chat_ui/src/App.module.css index 50d6a59..ae7e153 100644 --- a/chat_ui/src/App.module.css +++ b/chat_ui/src/App.module.css @@ -3,7 +3,6 @@ :root{ - --main-background-image: url("https://images.unsplash.com/photo-1547592180-85f173990554?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2370&q=80"); --header-height: 60px; --logo-height: 40px; --main-title-font-size: 40px; @@ -21,14 +20,12 @@ position: absolute; display: flex; flex-direction: column; - background-image: var(--main-background-image); background-size: cover; } .appHeader { background-color: var(--header-top); height: var(--header-height); - background-color: black; } .appLogo { diff --git a/chat_ui/src/App.tsx b/chat_ui/src/App.tsx index ccdaeab..9154553 100644 --- a/chat_ui/src/App.tsx +++ b/chat_ui/src/App.tsx @@ -1,8 +1,7 @@ import React, { Component } from "react" import css from "./App.module.css" -// import {HomePanel} from "./home/HomePanel" -// import {RatingsPanel} from "./ratings/RatingsPanel" -import logo from "./resources/img/uog_logo.png" +import { ChatConfigs } from "./common/chat_ui_configs" +import logo from "./resources/img/chat_ui_logo.png" import { WoZPanel } from "./woz/WoZPanel" // tslint:disable-next-line:interface-name @@ -18,12 +17,14 @@ class App extends Component<{}, IAppState> { super(props) const params: StringMap = { - conversationID: "test", - url: "https://backend-server.online", - userID: "user", - isAudioRecordingEnabled: '', - isTextToSpeechEnabled: '', - isSequentialNavigationEnabled: '' + conversationID: ChatConfigs.conversation_id, + url: ChatConfigs.url, + userID: ChatConfigs.userID, + isAudioRecordingEnabled: ChatConfigs.isAudioRecordingEnabled, + isTextToSpeechEnabled: ChatConfigs.isTextToSpeechEnabled, + isSequentialNavigationEnabled: ChatConfigs.isSequentialNavigationEnabled, + isSequentialComponentFullPage: ChatConfigs.isSequentialComponentFullPage, + showSequentialPageCheckboxes: ChatConfigs.showSequentialPageCheckboxes } new URL(window.location.href) .searchParams.forEach((value, key) => { @@ -38,39 +39,14 @@ class App extends Component<{}, IAppState> { public render() { - // const panes = [ - // { - // menuItem: "Home", - // render: () => , - // }, - // { menuItem: "Offline MT Ratings", - // render: () => , - // }, - // { menuItem: "TaskMAD", - // render: () => - // , - // }, - // ] - return ( -
+
-
+
logo -

TaskMAD

+

{ChatConfigs.chat_ui_title}

- {/* */} -
) diff --git a/chat_ui/src/common/chat_ui_configs.ts b/chat_ui/src/common/chat_ui_configs.ts new file mode 100644 index 0000000..2ca6736 --- /dev/null +++ b/chat_ui/src/common/chat_ui_configs.ts @@ -0,0 +1,15 @@ +export class ChatConfigs{ + public static chat_ui_title:string = "TaskMAD"; + public static chat_ui_background_image:string = "https://images.unsplash.com/photo-1547592180-85f173990554?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2370&q=80"; + public static chat_ui_header_color:string = "rgba(0,0,0,1)"; + + public static conversation_id:string = "test"; + public static url:string = "https://backend-server.online"; + public static userID:string = "user"; + public static isAudioRecordingEnabled:string = "false"; + public static isTextToSpeechEnabled:string = "false"; + public static isSequentialNavigationEnabled:string = "false"; + public static isSequentialComponentFullPage:string = "false"; + public static showSequentialPageCheckboxes:string = "false"; + +} \ No newline at end of file diff --git a/chat_ui/src/components/RecipePageComponent.module.css b/chat_ui/src/components/SequentialPageComponent.module.css similarity index 88% rename from chat_ui/src/components/RecipePageComponent.module.css rename to chat_ui/src/components/SequentialPageComponent.module.css index 25d6946..f61d1f7 100644 --- a/chat_ui/src/components/RecipePageComponent.module.css +++ b/chat_ui/src/components/SequentialPageComponent.module.css @@ -6,7 +6,7 @@ overflow-y: scroll; padding: var(--chat-container-top); } -.recipeCheckbox{ +.sequentialCheckbox{ float: left; } @@ -15,11 +15,11 @@ margin-bottom: 5px; } -.recipeSectionDiv{ +.sectionDiv{ margin-bottom: 15px; } -.recipeStepImage{ +.stepImage{ height: auto; width: 60%; border-radius: 1em; @@ -36,7 +36,7 @@ color: white !important; } -.recipeComponentContainer{ +.componentContainer{ background-color: var(--chat-container-background); padding: var(--chat-container-top); border-radius: var(--chat-container-border-radius); diff --git a/chat_ui/src/components/RecipePageComponent.tsx b/chat_ui/src/components/SequentialPageComponent.tsx similarity index 52% rename from chat_ui/src/components/RecipePageComponent.tsx rename to chat_ui/src/components/SequentialPageComponent.tsx index 95ffa85..08074e1 100644 --- a/chat_ui/src/components/RecipePageComponent.tsx +++ b/chat_ui/src/components/SequentialPageComponent.tsx @@ -2,47 +2,45 @@ import * as React from "react" import { Button, Checkbox, Container, Header, Icon, Message } from "semantic-ui-react" import { diffSecondsBetweenDates, isStringImagePath, playTextToAudio } from "../common/util"; import { InteractionAction, InteractionType } from "../generated/client_pb"; -import { RecipeCheckboxModel } from "../models/RecipeCheckboxModel"; import { RecipeModel } from "../models/RecipeModel"; +import { SequentialPageCheckboxModel } from "../models/SequentialPageCheckboxModel"; +import { ISequentialPageModel } from "../models/SequentialPageModel"; import { IDialogue } from "./DialogueModel"; -import css from "./RecipePageComponent.module.css" +import css from "./SequentialPageComponent.module.css" -interface IRecipePageComponentProperties { - recipeObj?: RecipeModel, - selectedCheckboxList: RecipeCheckboxModel[]; - onSelectCheckbox: (model: RecipeCheckboxModel) => void, - onRecipeSectionButtonClick: (sectionDescription: string) => void, - showFullPageCheckList?: boolean - showCheckBoxes?: boolean, +interface ISequentialPageComponentProperties { + sequentialPageObj?: ISequentialPageModel, + selectedCheckboxList: SequentialPageCheckboxModel[]; + onSelectCheckbox: (model: SequentialPageCheckboxModel) => void, + onSectionButtonClick: (sectionDescription: string) => void, isSequentialNavigationEnabled?: boolean - isTextToSpeechEnabled: boolean + isTextToSpeechEnabled?: boolean + isSequentialComponentFullPage?: boolean + showSequentialPageCheckboxes?: boolean dialogue?: IDialogue, us?: string } +interface ISequentialPageComponent { + generateSequentialPageCheckboxBody(): Map; +} -export class RecipePageComponent - extends React.Component { - private recipeSections: string[] = []; - // Specific recipe section to display if the view is single section rather than full page - private recipeSectionIndex: number = 0; +export class SequentialPageComponent + extends React.Component implements ISequentialPageComponent { - public static defaultProps = { - showFullPageCheckList: false, - showCheckBoxes: false, - isSequentialNavigationEnabled: false, - isTextToSpeechEnabled: false - }; + private pageSections: string[] = []; + // Specific recipe section to display if the view is single section rather than full page + private pageSectionIndex: number = 0; - constructor(props: IRecipePageComponentProperties) { + constructor(props: ISequentialPageComponentProperties) { super(props); - this.handleRecipeNavigation = this.handleRecipeNavigation.bind(this); + this.handleSectionsNavigation = this.handleSectionsNavigation.bind(this); } private wizardNavigationController(): void { @@ -74,26 +72,26 @@ export class RecipePageComponent // Here we handle the page reload based on the current step we are in if (actions[0] === InteractionAction.PREVIOUS_STEP) { // Update the recipeSectionIndex only if we are not at step 0 - if (this.recipeSectionIndex !== 0) { - this.recipeSectionIndex -= 1; + if (this.pageSectionIndex !== 0) { + this.pageSectionIndex -= 1; } } if (actions[0] === InteractionAction.NEXT_STEP) { // Update the recipeSectionIndex only if we are not at the end of the list - if (this.recipeSectionIndex < this.recipeSections.length - 1) { - this.recipeSectionIndex += 1; + if (this.pageSectionIndex < this.pageSections.length - 1) { + this.pageSectionIndex += 1; } } // Once we move the a new section we also need to read section title and provide prompt // to the user if (this.props.isTextToSpeechEnabled) { - let textString = "Here we are in section " + this.recipeSections[this.recipeSectionIndex] + "! Have a read and feel free to ask me questions!"; + let textString = "Here we are in section " + this.pageSections[this.pageSectionIndex] + "! Have a read and feel free to ask me questions!"; playTextToAudio(textString); } // At the end of the interaction we notify the Wizard of the actual change happening - this.props.onRecipeSectionButtonClick(this.recipeSections[this.recipeSectionIndex]) + this.props.onSectionButtonClick(this.pageSections[this.pageSectionIndex]) } } @@ -103,47 +101,34 @@ export class RecipePageComponent // Method used in order to generate the page body associated to this recipe - private generatePageRecipeCheckboxModel(): Map { - let tempRecipeModel = this.props.recipeObj; - let resultMap = new Map() + generateSequentialPageCheckboxBody(): Map { + let tempRecipeModel = this.props.sequentialPageObj as RecipeModel; + let resultMap = new Map() if (tempRecipeModel !== undefined) { - - // Create checkbox objects for the description - // let descriptionList = tempRecipeModel!.sentences.map((el: string) => { - // return tempRecipeModel!.recipeModelToRecipeCheckboxModel('Description', el); - // }) - - // resultMap.set('Description', descriptionList); - // Generate the time sections - let prepTimeRecipeCheckboxModel = tempRecipeModel!.recipeModelToRecipeCheckboxModel('Time', 'Preparation Time: ' + tempRecipeModel!.durationMinutesPrep + ' minutes'); - let cookingTimeRecipeCheckboxModel = tempRecipeModel!.recipeModelToRecipeCheckboxModel('Time', 'Cooking Time: ' + tempRecipeModel!.durationMinutesCooking + ' minutes'); - let totalTimeRecipeCheckboxModel = tempRecipeModel!.recipeModelToRecipeCheckboxModel('Time', 'Total Time: ' + tempRecipeModel!.durationMinutesTotal + ' minutes'); + let prepTimeRecipeCheckboxModel = tempRecipeModel.sequentialPageModelToSequentialPageCheckboxModel('Time', 'Preparation Time: ' + tempRecipeModel.durationMinutesPrep + ' minutes'); + let cookingTimeRecipeCheckboxModel = tempRecipeModel.sequentialPageModelToSequentialPageCheckboxModel('Time', 'Cooking Time: ' + tempRecipeModel.durationMinutesCooking + ' minutes'); + let totalTimeRecipeCheckboxModel = tempRecipeModel.sequentialPageModelToSequentialPageCheckboxModel('Time', 'Total Time: ' + tempRecipeModel.durationMinutesTotal + ' minutes'); - //resultMap.set('Time', [prepTimeRecipeCheckboxModel, cookingTimeRecipeCheckboxModel, totalTimeRecipeCheckboxModel]); // Create checkbox objects for the required equipment - let requiredEquipmentList = tempRecipeModel!.requiredEquipment.map((el: string) => { - return tempRecipeModel!.recipeModelToRecipeCheckboxModel('Required equipment', el); + let requiredEquipmentList = tempRecipeModel.requiredEquipment.map((el: string) => { + return tempRecipeModel.sequentialPageModelToSequentialPageCheckboxModel('Required equipment', el); }) - //resultMap.set('Required equipment', requiredEquipmentList); - // Create checkbox objects for the required ingredients - let requiredIngredientsList = tempRecipeModel!.requiredIngredient.map((el: string) => { - return tempRecipeModel!.recipeModelToRecipeCheckboxModel('Required Ingredients', el); + let requiredIngredientsList = tempRecipeModel.requiredIngredients.map((el: string) => { + return tempRecipeModel.sequentialPageModelToSequentialPageCheckboxModel('Required Ingredients', el); }) - //resultMap.set('Required Ingredients', requiredIngredientsList); - resultMap.set('Time, Equipment & Ingredients', [prepTimeRecipeCheckboxModel, cookingTimeRecipeCheckboxModel, totalTimeRecipeCheckboxModel].concat(requiredEquipmentList).concat(requiredIngredientsList)); // Generate the steps checkbox models if (tempRecipeModel?.stepsSentencesWithImages !== undefined) { for (let i = 0; i < tempRecipeModel?.stepsSentencesWithImages.length; i++) { for (let j = 0; j < tempRecipeModel?.stepsSentencesWithImages[i].length; j++) { - let tempRecipeCheckboxModel = tempRecipeModel?.recipeModelToRecipeCheckboxModel('Step ' + (i + 1), tempRecipeModel?.stepsSentencesWithImages[i][j]); + let tempRecipeCheckboxModel = tempRecipeModel?.sequentialPageModelToSequentialPageCheckboxModel('Step ' + (i + 1), tempRecipeModel?.stepsSentencesWithImages[i][j]); if (resultMap.has('Step ' + (i + 1))) { let innerRecipeStepsList = resultMap.get('Step ' + (i + 1)) if (innerRecipeStepsList !== undefined) @@ -162,30 +147,30 @@ export class RecipePageComponent } // Get the array of all the sections - this.recipeSections = Array.from(resultMap.keys()) !== undefined ? Array.from(resultMap.keys()) : []; + this.pageSections = Array.from(resultMap.keys()) !== undefined ? Array.from(resultMap.keys()) : []; - return resultMap + return resultMap; } // Method used to generate the page body private generatePageBodyFullPage(): JSX.Element[] { - let recipeMap = this.generatePageRecipeCheckboxModel(); + let sequentialPageMap = this.generateSequentialPageCheckboxBody(); let pageBody: JSX.Element[] = [] let counter = 0 - if (recipeMap.size > 0) { - recipeMap.forEach((value, key) => { + if (sequentialPageMap.size > 0) { + sequentialPageMap.forEach((value, key) => { - let sectionCheckboxes = value.map((el: RecipeCheckboxModel, index: number) => { + let sectionCheckboxes = value.map((el: SequentialPageCheckboxModel, index: number) => { - let checkboxJsxElement = this.props.showCheckBoxes ? this.props.onSelectCheckbox(el)} checked={this.props.selectedCheckboxList.filter(checkbox => checkbox.isEqual(el)).length === 1} className={css.recipeCheckbox}> : undefined; + let checkboxJsxElement = this.props.showSequentialPageCheckboxes ? this.props.onSelectCheckbox(el)} checked={this.props.selectedCheckboxList.filter(checkbox => checkbox.isEqual(el)).length === 1} className={css.sequentialCheckbox}> : undefined; // Here we show either an image or the associated checkboxes - return isStringImagePath(el.sectionValue) ? :
{checkboxJsxElement}
{this.props.showCheckBoxes ? undefined : "- "}{el.sectionValue}
+ return isStringImagePath(el.sectionValue) ? :
{checkboxJsxElement}
{this.props.showSequentialPageCheckboxes ? undefined : "- "}{el.sectionValue}
}); if (sectionCheckboxes.length !== 0) { - let section = (
{key}
{sectionCheckboxes}
) + let section = (
{key}
{sectionCheckboxes}
) pageBody.push(section); } @@ -201,25 +186,25 @@ export class RecipePageComponent // Method used to generate the page body private generatePageBodySingleSection(displaySection: number = 0): JSX.Element[] { - let recipeMap = this.generatePageRecipeCheckboxModel(); + let sequentialPageMap = this.generateSequentialPageCheckboxBody(); let pageBody: JSX.Element[] = [] - let counter = 0 + let counter = 0; - if (recipeMap.size > 0) { + if (sequentialPageMap.size > 0) { // Get the key of the section we want to display - let currentSectionKey = Array.from(recipeMap.keys())[displaySection]; - let currentSectionValues = recipeMap.get(currentSectionKey) + let currentSectionKey = Array.from(sequentialPageMap.keys())[displaySection]; + let currentSectionValues = sequentialPageMap.get(currentSectionKey) if (currentSectionValues !== undefined) { - let sectionCheckboxes = currentSectionValues.map((el: RecipeCheckboxModel, index: number) => { + let sectionCheckboxes = currentSectionValues.map((el: SequentialPageCheckboxModel, index: number) => { - let checkboxJsxElement = this.props.showCheckBoxes ? this.props.onSelectCheckbox(el)} checked={this.props.selectedCheckboxList.filter(checkbox => checkbox.isEqual(el)).length === 1} className={css.recipeCheckbox}> : undefined; + let checkboxJsxElement = this.props.showSequentialPageCheckboxes ? this.props.onSelectCheckbox(el)} checked={this.props.selectedCheckboxList.filter(checkbox => checkbox.isEqual(el)).length === 1} className={css.sequentialCheckbox}> : undefined; // Here we show either an image or the associated checkboxes - return isStringImagePath(el.sectionValue) ? :
{checkboxJsxElement}
{this.props.showCheckBoxes ? undefined : "- "}{el.sectionValue}
+ return isStringImagePath(el.sectionValue) ? :
{checkboxJsxElement}
{this.props.showSequentialPageCheckboxes ? undefined : "- "}{el.sectionValue}
}); if (sectionCheckboxes.length !== 0) { - let section = (
{currentSectionKey}
{sectionCheckboxes}
) + let section = (
{currentSectionKey}
{sectionCheckboxes}
) pageBody.push(section); } @@ -238,14 +223,14 @@ export class RecipePageComponent private generateButtonsMenu(displaySection: number = 0): JSX.Element[] { let result: JSX.Element[] = [] // We show the buttons only if we don't have the full page flag enabled - if (!this.props.showFullPageCheckList) { + if (!this.props.isSequentialComponentFullPage) { // We show the previous button only if we are not at the first section if (displaySection > 0) { - result.push() + result.push() } // We show the next button only if we are not at the last section - if (displaySection < this.recipeSections.length - 1) { - result.push() + if (displaySection < this.pageSections.length - 1) { + result.push() } } @@ -255,15 +240,15 @@ export class RecipePageComponent } // Method used in order to handle the navigation between sections - private handleRecipeNavigation(move: number) { + private handleSectionsNavigation(move: number) { - this.recipeSectionIndex += move + this.pageSectionIndex += move this.setState({ }) - if (this.recipeSections !== undefined && this.recipeSections.length !== 0) { - this.props.onRecipeSectionButtonClick(this.recipeSections[this.recipeSectionIndex]); + if (this.pageSections !== undefined && this.pageSections.length !== 0) { + this.props.onSectionButtonClick(this.pageSections[this.pageSectionIndex]); } } @@ -274,13 +259,13 @@ export class RecipePageComponent // Right before rendering check whether we should update the recipe index or not this.wizardNavigationController(); - let pageBody: JSX.Element[] = this.props.showFullPageCheckList ? this.generatePageBodyFullPage() : this.generatePageBodySingleSection(this.recipeSectionIndex); + let pageBody: JSX.Element[] = this.props.isSequentialComponentFullPage ? this.generatePageBodyFullPage() : this.generatePageBodySingleSection(this.pageSectionIndex); let errorMessage = An error occurred when retrieving the recipe. Try again later. return
- -
{this.props.recipeObj?.pageTitle}
+ +
{this.props.sequentialPageObj?.pageTitle}
{pageBody.length > 0 ? pageBody : errorMessage} - {this.props.isSequentialNavigationEnabled ? this.generateButtonsMenu(this.recipeSectionIndex) : undefined} + {this.props.isSequentialNavigationEnabled ? this.generateButtonsMenu(this.pageSectionIndex) : undefined}
diff --git a/chat_ui/src/models/RecipeModel.tsx b/chat_ui/src/models/RecipeModel.tsx index 17a7a95..da514fd 100644 --- a/chat_ui/src/models/RecipeModel.tsx +++ b/chat_ui/src/models/RecipeModel.tsx @@ -14,9 +14,11 @@ * limitations under the License. */ -import { RecipeCheckboxModel } from "./RecipeCheckboxModel"; +import { SequentialPageCheckboxModel } from "./SequentialPageCheckboxModel" +import { ISequentialPageModel } from "./SequentialPageModel" + +export class RecipeModel implements ISequentialPageModel { -export interface IRecipeModel { readonly id: string readonly hashedId: string readonly pageId: string @@ -25,78 +27,67 @@ export interface IRecipeModel { readonly durationMinutesPrep: number readonly durationMinutesTotal: number readonly requiredEquipment: string[] - readonly requiredIngredient: string[] + readonly requiredIngredients: string[] readonly sentences: string[] readonly stepsSentences: string[][] readonly stepsImages: string[][] stepsSentencesWithImages: string[][] -} -export class RecipeModel implements IRecipeModel { - constructor(model: IRecipeModel) { + constructor(model: ISequentialPageModel, + durationMinutesCooking: number, + durationMinutesPrep: number, + durationMinutesTotal: number, + requiredEquipment: string[], + requiredIngredients: string[]) { this.id = model.id; this.hashedId = model.hashedId; this.pageId = model.pageId; this.pageTitle = model.pageTitle; - this.durationMinutesCooking = model.durationMinutesCooking - this.durationMinutesPrep = model.durationMinutesPrep - this.durationMinutesTotal = model.durationMinutesTotal - this.requiredEquipment = model.requiredEquipment - this.requiredIngredient = model.requiredIngredient + this.durationMinutesCooking = durationMinutesCooking + this.durationMinutesPrep = durationMinutesPrep + this.durationMinutesTotal = durationMinutesTotal + this.requiredEquipment = requiredEquipment + this.requiredIngredients = requiredIngredients this.sentences = model.sentences this.stepsSentences = model.stepsSentences this.stepsImages = model.stepsImages this.stepsSentencesWithImages = model.stepsSentencesWithImages } - readonly id: string - readonly hashedId: string - readonly pageId: string - readonly pageTitle: string - readonly durationMinutesCooking: number - readonly durationMinutesPrep: number - readonly durationMinutesTotal: number - readonly requiredEquipment: string[] - readonly requiredIngredient: string[] - readonly sentences: string[] - readonly stepsSentences: string[][] - readonly stepsImages: string[][] - stepsSentencesWithImages: string[][] - public static jsonToRecipeModel = (jsonRecipe: object): RecipeModel => { - let jsonObj = JSON.parse(JSON.stringify(jsonRecipe)) - + static jsonToSequentialPageModel = (jsonObject: object): ISequentialPageModel => { + let jsonObj = JSON.parse(JSON.stringify(jsonObject)) + let recipeModelObj = new RecipeModel({ id: jsonObj['id'], hashedId: jsonObj['hashed_id'], pageId: jsonObj['page_id'], pageTitle: jsonObj['page_title'], - durationMinutesCooking: jsonObj['duration_minutes_cooking'], - durationMinutesPrep: jsonObj['duration_minutes_prep'], - durationMinutesTotal: jsonObj['duration_minutes_total'], - requiredEquipment: jsonObj['required_equipment'], - requiredIngredient: jsonObj['required_ingredient'], sentences: jsonObj['sentences'], stepsSentences: jsonObj['steps_sentences'], stepsImages: jsonObj['steps_images'], - stepsSentencesWithImages: [] - }); + stepsSentencesWithImages: [], + }, + jsonObj['duration_minutes_cooking'], + jsonObj['duration_minutes_prep'], + jsonObj['duration_minutes_total'], + jsonObj['required_equipment'], + jsonObj['required_ingredient']); // Generate the field with sentences and images - if(recipeModelObj.stepsSentences !== undefined && recipeModelObj.stepsImages !== undefined){ - var tempStepsSentencesWithImages = recipeModelObj.stepsSentences.map(function(el, index) { - var mergedArrays = el.concat(recipeModelObj.stepsImages[index]); - return mergedArrays; - }); - recipeModelObj.stepsSentencesWithImages = tempStepsSentencesWithImages; - + if (recipeModelObj.stepsSentences !== undefined && recipeModelObj.stepsImages !== undefined) { + let tempStepsSentencesWithImages = recipeModelObj.stepsSentences.map(function (el, index) { + return el.concat(recipeModelObj.stepsImages[index]); + }); + recipeModelObj.stepsSentencesWithImages = tempStepsSentencesWithImages; + } return recipeModelObj; } - public recipeModelToRecipeCheckboxModel = (section: string, sectionValue: string): RecipeCheckboxModel =>{ - let tempRecipeCheckboxModel = new RecipeCheckboxModel({ + sequentialPageModelToSequentialPageCheckboxModel = (section: string, sectionValue: string): SequentialPageCheckboxModel => { + return new SequentialPageCheckboxModel({ id: this.id, hashedId: this.hashedId, pageId: this.pageId, @@ -105,6 +96,5 @@ export class RecipeModel implements IRecipeModel { sectionValue: sectionValue }); - return tempRecipeCheckboxModel; } } diff --git a/chat_ui/src/models/RecipeCheckboxModel.tsx b/chat_ui/src/models/SequentialPageCheckboxModel.tsx similarity index 72% rename from chat_ui/src/models/RecipeCheckboxModel.tsx rename to chat_ui/src/models/SequentialPageCheckboxModel.tsx index 0ede8aa..0e2ef39 100644 --- a/chat_ui/src/models/RecipeCheckboxModel.tsx +++ b/chat_ui/src/models/SequentialPageCheckboxModel.tsx @@ -17,7 +17,7 @@ // Class used in order to keep track of the different checkboxes associated // to the different parts of a recipe -export interface IRecipeCheckboxModel { +export interface ISequentialPageCheckboxModel { readonly id: string readonly hashedId: string readonly pageId: string @@ -27,8 +27,9 @@ export interface IRecipeCheckboxModel { clickedTimestamp?: Date } -export class RecipeCheckboxModel implements IRecipeCheckboxModel { - constructor(model: IRecipeCheckboxModel) { + +export class SequentialPageCheckboxModel implements ISequentialPageCheckboxModel { + constructor(model: ISequentialPageCheckboxModel) { this.id = model.id; this.hashedId = model.hashedId; this.pageId = model.pageId; @@ -45,13 +46,13 @@ export class RecipeCheckboxModel implements IRecipeCheckboxModel { readonly sectionValue: string clickedTimestamp?: Date - public isEqual = (model: RecipeCheckboxModel):boolean => { - return this.id === model.id - && this.hashedId === model.hashedId - && this.pageId === model.pageId - && this.pageTitle === model.pageTitle - && this.section === model.section - && this.sectionValue === model.sectionValue + public isEqual = (model: SequentialPageCheckboxModel): boolean => { + return this.id === model.id + && this.hashedId === model.hashedId + && this.pageId === model.pageId + && this.pageTitle === model.pageTitle + && this.section === model.section + && this.sectionValue === model.sectionValue } } diff --git a/chat_ui/src/models/SequentialPageModel.tsx b/chat_ui/src/models/SequentialPageModel.tsx new file mode 100644 index 0000000..cf93f96 --- /dev/null +++ b/chat_ui/src/models/SequentialPageModel.tsx @@ -0,0 +1,32 @@ +/* + * Copyright 2018. University of Southern California + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ISequentialPageCheckboxModel } from "./SequentialPageCheckboxModel" + + +export interface ISequentialPageModel { + readonly id: string + readonly hashedId: string + readonly pageId: string + readonly pageTitle: string + readonly sentences: string[] + readonly stepsSentences: string[][] + readonly stepsImages: string[][] + stepsSentencesWithImages: string[][] + jsonToSequentialPageModel?: (jsonObject: object) => ISequentialPageModel + sequentialPageModelToSequentialPageCheckboxModel?: (section: string, sectionValue: string) => ISequentialPageCheckboxModel + +} \ No newline at end of file diff --git a/chat_ui/src/resources/img/Agent_logo.png b/chat_ui/src/resources/img/Agent_logo.png deleted file mode 100644 index e543c4f..0000000 Binary files a/chat_ui/src/resources/img/Agent_logo.png and /dev/null differ diff --git a/chat_ui/src/resources/img/Agent_logo_old.png b/chat_ui/src/resources/img/Agent_logo_old.png deleted file mode 100644 index 9ec2907..0000000 Binary files a/chat_ui/src/resources/img/Agent_logo_old.png and /dev/null differ diff --git a/chat_ui/src/resources/img/uog_logo.png b/chat_ui/src/resources/img/chat_ui_logo.png similarity index 100% rename from chat_ui/src/resources/img/uog_logo.png rename to chat_ui/src/resources/img/chat_ui_logo.png diff --git a/chat_ui/src/services/MediaRecorderService.tsx b/chat_ui/src/services/MediaRecorderService.tsx index b94faff..179c5a1 100644 --- a/chat_ui/src/services/MediaRecorderService.tsx +++ b/chat_ui/src/services/MediaRecorderService.tsx @@ -61,13 +61,12 @@ export class MediaRecorderAPIService implements IMediaRecorderService { } private createMediaBlob(): Blob { - const blob = new Blob( + return new Blob( this.mediaChunks, { 'type': this.videoConstraints ? this.videoFormat : this.audioFormat, }); - return blob; } diff --git a/chat_ui/src/services/RecipeService.tsx b/chat_ui/src/services/RecipeService.tsx index 2437320..7b79ef3 100644 --- a/chat_ui/src/services/RecipeService.tsx +++ b/chat_ui/src/services/RecipeService.tsx @@ -1,6 +1,8 @@ import { Struct } from "google-protobuf/google/protobuf/struct_pb"; import { ADConnection } from "../common/ADConnection"; import { RecipeModel } from "../models/RecipeModel"; +import { ISequentialPageModel } from "../models/SequentialPageModel"; + // Class used in order to manage the retrieval of recipes export class RecipeService { @@ -10,7 +12,7 @@ export class RecipeService { headers: { 'Content-Type': 'application/json', 'Origin': '*' }, }; - var dataJson = undefined; + let dataJson = undefined; try { const response = await fetch('https://storage.googleapis.com/taskmad-public-bucket/associated_recipes.json', requestOptions); dataJson = await response.json(); @@ -28,7 +30,7 @@ export class RecipeService { } // Retrieve a recipe based on the id passed - public static getRecipeById = async (recipeId: string, connection: ADConnection | undefined): Promise => { + public static getRecipeById = async (recipeId: string, connection: ADConnection | undefined): Promise => { if (connection !== undefined) { @@ -52,8 +54,10 @@ export class RecipeService { // Get the documents let document: Object = Object.getOwnPropertyDescriptor(apiResponse, 'document')?.value || ""; + console.log(document); + if (document !== undefined && document !== "") { - return RecipeModel.jsonToRecipeModel(document); + return RecipeModel.jsonToSequentialPageModel(document); } } diff --git a/chat_ui/src/services/SpeechToTextService.tsx b/chat_ui/src/services/SpeechToTextService.tsx index e4e0ebc..8f6c27a 100644 --- a/chat_ui/src/services/SpeechToTextService.tsx +++ b/chat_ui/src/services/SpeechToTextService.tsx @@ -7,7 +7,7 @@ interface ISpeechToTextService { export class GoogleAPISpeechToTextService implements ISpeechToTextService { public async base64StringToText(base64String: string, connection: ADConnection): Promise { - var speechToText: string = await connection.agentSpeechToTextInteractionApi(base64String); + let speechToText: string = await connection.agentSpeechToTextInteractionApi(base64String); return speechToText; } diff --git a/chat_ui/src/woz/WoZPanel.module.css b/chat_ui/src/woz/WoZPanel.module.css index d597d96..b87aef0 100644 --- a/chat_ui/src/woz/WoZPanel.module.css +++ b/chat_ui/src/woz/WoZPanel.module.css @@ -10,7 +10,7 @@ right: 0; bottom: 0; height: calc(100% - var(--header-height) + 14px); - top: var(--header-height); + overflow: auto; } #appGroupId { @@ -21,6 +21,7 @@ #appGroupId > * { padding-left: 0; padding-right: 0; + padding-top: 0; } .gridColumn{ diff --git a/chat_ui/src/woz/WoZPanel.tsx b/chat_ui/src/woz/WoZPanel.tsx index c07877e..be22a75 100644 --- a/chat_ui/src/woz/WoZPanel.tsx +++ b/chat_ui/src/woz/WoZPanel.tsx @@ -7,10 +7,10 @@ import { convertDateToTimestamp, convertTimestampToDate, stringToBoolean } from import { ChatComponent } from "../components/ChatComponent" import { Dialogue } from "../components/DialogueModel" import { Message } from "../components/MessageModel" -import { RecipePageComponent } from "../components/RecipePageComponent" +import { SequentialPageComponent } from "../components/SequentialPageComponent" import { InteractionLogs, InteractionType } from "../generated/client_pb" -import { RecipeCheckboxModel } from "../models/RecipeCheckboxModel" -import { RecipeModel } from "../models/RecipeModel" +import { SequentialPageCheckboxModel } from "../models/SequentialPageCheckboxModel" +import { ISequentialPageModel } from "../models/SequentialPageModel" import { RecipeService } from "../services/RecipeService" import css from "./WoZPanel.module.css" @@ -32,6 +32,8 @@ interface IWozParams { isAudioRecordingEnabled?: boolean, isTextToSpeechEnabled?: boolean, isSequentialNavigationEnabled?: boolean + isSequentialComponentFullPage?: boolean + showSequentialPageCheckboxes?: boolean dropdownRecipes?: object[], } @@ -62,7 +64,9 @@ export class WoZPanel selectedRecipeId: (props.params.selectedRecipeId || "").trim(), isAudioRecordingEnabled: stringToBoolean(props.params.isAudioRecordingEnabled), isTextToSpeechEnabled: stringToBoolean(props.params.isTextToSpeechEnabled), - isSequentialNavigationEnabled: stringToBoolean(props.params.isSequentialNavigationEnabled) + isSequentialNavigationEnabled: stringToBoolean(props.params.isSequentialNavigationEnabled), + isSequentialComponentFullPage: stringToBoolean(props.params.isSequentialComponentFullPage), + showSequentialPageCheckboxes: stringToBoolean(props.params.showSequentialPageCheckboxes), } this.state = { @@ -84,7 +88,9 @@ export class WoZPanel selectedRecipeId: this.state.params.selectedRecipeId, isAudioRecordingEnabled: this.state.params.isAudioRecordingEnabled, isTextToSpeechEnabled: this.state.params.isTextToSpeechEnabled, - isSequentialNavigationEnabled: this.state.params.isSequentialNavigationEnabled + isSequentialNavigationEnabled: this.state.params.isSequentialNavigationEnabled, + isSequentialComponentFullPage: this.state.params.isSequentialComponentFullPage, + showSequentialPageCheckboxes: this.state.params.showSequentialPageCheckboxes } }) @@ -195,8 +201,8 @@ interface IWoZDialogueProperties { interface IWoZDialogueState { dialogue: Dialogue, - selectedCheckboxList: RecipeCheckboxModel[] - selectedRecipe?: RecipeModel + selectedCheckboxList: SequentialPageCheckboxModel[] + selectedSequentialPage?: ISequentialPageModel } class WoZDialogue @@ -205,8 +211,6 @@ class WoZDialogue constructor(props: IWoZDialogueProperties) { super(props) - // console.log(this.props) - this.state = { dialogue: props.dialogue === undefined ? new Dialogue({ messages: [] }) : props.dialogue, @@ -216,7 +220,6 @@ class WoZDialogue this.props.connection.subscribe({ conversationID: this.props.params.conversationID, onResponse: ((response) => { - // console.log("response: ", response) const reply = response.asTextResponse() const message = new Message({ ...reply, @@ -237,7 +240,7 @@ class WoZDialogue if (recipe !== undefined) { this.setState({ - selectedRecipe: recipe + selectedSequentialPage: recipe }); } @@ -292,7 +295,7 @@ class WoZDialogue } // Method used in order to keep track of the pressed buttons - private onSelectCheckbox = (selectedCheckbox: RecipeCheckboxModel) => { + private onSelectCheckbox = (selectedCheckbox: SequentialPageCheckboxModel) => { // Flag used in order to detect whether we are checking or unchecking a recipe let flagCheckboxRemoved = false; @@ -329,7 +332,7 @@ class WoZDialogue // Method used to send a message to the Wizard when the user navigates to a new // section - private onRecipeSectionButtonClick = (sectionKey: string) => { + private onSectionButtonClick = (sectionKey: string) => { // We need now to send a message to the wizad. This message will be of type status and the user won't be able to see it. // It will only be used by the wizard to know which parts of the interface the user is looking at. // However we first need to generate the specific message text for the wizard @@ -347,15 +350,17 @@ class WoZDialogue return ( - + isTextToSpeechEnabled={this.props.params.isTextToSpeechEnabled} + isSequentialComponentFullPage={this.props.params.isSequentialComponentFullPage} + showSequentialPageCheckboxes={this.props.params.showSequentialPageCheckboxes}> - ); + ); } } diff --git a/core/README.md b/core/README.md new file mode 100644 index 0000000..d6b85af --- /dev/null +++ b/core/README.md @@ -0,0 +1,23 @@ +# Core Module + +## Requirements + +## Core In details + +### Overview +### Implementing an Agent +#### Agent Interface +#### Agent Configuration File + + + +## Running Core Locally + + +## Deploying and Running Core on Google Cloud + +### Deployment on GCP with Docker & Kubernetes + + + + diff --git a/core/deployment_config/cloud/cloudbuild.yaml b/core/deployment_config/cloud/cloudbuild.yaml index 457e3cc..5f0f3cd 100644 --- a/core/deployment_config/cloud/cloudbuild.yaml +++ b/core/deployment_config/cloud/cloudbuild.yaml @@ -2,14 +2,14 @@ steps: # Build the image - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REGISTRY_REPOSITORY}/envoy:${_IMAGE_VERSION}', '-f', 'config/envoy_updated.Dockerfile', 'config/.'] + args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REGISTRY_REPOSITORY}/envoy:${_IMAGE_VERSION}', '-f', '${_ENVOY_ROOT_FOLDER}/envoy.Dockerfile', '${_ENVOY_ROOT_FOLDER}/.'] # Push the image - name: 'gcr.io/cloud-builders/docker' args: ['push', 'europe-west2-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REGISTRY_REPOSITORY}/envoy:${_IMAGE_VERSION}'] # Build the image - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REGISTRY_REPOSITORY}/grpc-server:${_IMAGE_VERSION}', 'agent-dialogue-core/.'] + args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REGISTRY_REPOSITORY}/grpc-server:${_IMAGE_VERSION}', '${_CORE_ROOT_FOLDER}/.'] # Push the image - name: 'gcr.io/cloud-builders/docker' @@ -17,7 +17,7 @@ steps: # Build the image - name: 'gcr.io/cloud-builders/docker' - args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REGISTRY_REPOSITORY}/grpc-health-proxy:${_IMAGE_VERSION}', '-f', 'agent-dialogue-core/grpc_health_proxy.Dockerfile', 'agent-dialogue-core/.'] + args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/${_ARTIFACT_REGISTRY_REPOSITORY}/grpc-health-proxy:${_IMAGE_VERSION}', '-f', '${_HEALTH_ROOT_FOLDER}/grpc_health_proxy.Dockerfile', '${_HEALTH_ROOT_FOLDER}/.'] # Push the image - name: 'gcr.io/cloud-builders/docker' @@ -30,7 +30,7 @@ steps: args: - apply - -f - - agent-dialogue-core/deployment_config/${_K8_BACKEND_CONFIG_FILE} + - ${_CORE_ROOT_FOLDER}/${_CONFIG_PATH}/${_K8_BACKEND_CONFIG_FILE} env: - CLOUDSDK_COMPUTE_REGION=${_CLUSTER_LOCATION} - CLOUDSDK_CONTAINER_CLUSTER=${_CLUSTER_NAME} @@ -40,7 +40,7 @@ steps: args: - apply - -f - - agent-dialogue-core/deployment_config/${_FRONTEND_CONFIG_FILE} + - ${_CORE_ROOT_FOLDER}/${_CONFIG_PATH}/${_FRONTEND_CONFIG_FILE} env: - CLOUDSDK_COMPUTE_REGION=${_CLUSTER_LOCATION} - CLOUDSDK_CONTAINER_CLUSTER=${_CLUSTER_NAME} @@ -50,7 +50,7 @@ steps: args: - apply - -f - - config/${_K8_FILE} + - ${_CORE_ROOT_FOLDER}/${_CONFIG_PATH}/${_K8_FILE} env: - CLOUDSDK_COMPUTE_REGION=${_CLUSTER_LOCATION} - CLOUDSDK_CONTAINER_CLUSTER=${_CLUSTER_NAME} @@ -60,20 +60,24 @@ steps: args: - apply - -f - - agent-dialogue-core/deployment_config/${_K8_INGRESS_FILE} + - ${_CORE_ROOT_FOLDER}/${_CONFIG_PATH}/${_K8_INGRESS_FILE} env: - CLOUDSDK_COMPUTE_REGION=${_CLUSTER_LOCATION} - CLOUDSDK_CONTAINER_CLUSTER=${_CLUSTER_NAME} substitutions: _ARTIFACT_REGISTRY_REPOSITORY: task-mad-images-repository + _CLUSTER_LOCATION: europe-central2-a + _CLUSTER_NAME: esp-core-cluster _IMAGE_VERSION: latest + _CORE_ROOT_FOLDER: core + _ENVOY_ROOT_FOLDER: envoy + _HEALTH_ROOT_FOLDER: grpc_health_proxy + _CONFIG_PATH: deployment_config/cloud _FRONTEND_CONFIG_FILE: frontend_config.yaml - _K8_FILE: core_deployment.yaml _K8_BACKEND_CONFIG_FILE: backend_config.yaml _K8_INGRESS_FILE: esp_core_managed_cert_ingress.yaml - _CLUSTER_LOCATION: europe-central2-a - _CLUSTER_NAME: esp-core-cluster + _K8_FILE: core_deployment.yaml # Timeout for 30 mins timeout: 1800s \ No newline at end of file diff --git a/core/deployment_config/cloud/core_deployment.yaml b/core/deployment_config/cloud/core_deployment.yaml index 323e3a5..e18543e 100644 --- a/core/deployment_config/cloud/core_deployment.yaml +++ b/core/deployment_config/cloud/core_deployment.yaml @@ -48,7 +48,7 @@ spec: ports: - containerPort: 8070 volumeMounts: - - mountPath: "code/keys" + - mountPath: "code/deployment_config/keys" name: disk-core-volume - name: grpc-health-proxy image: europe-west2-docker.pkg.dev/agentdialogue-2cd4b/task-mad-images-repository/grpc-health-proxy:latest