├── .github └── workflows │ ├── action-server-ci.yml │ └── model-ci.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── actions ├── __init__.py ├── actions.py ├── actions_base.py ├── actions_faqs.py ├── actions_helpdesk.py ├── actions_internal.py ├── actions_mock.py ├── constants.py ├── glpi.py └── parsing.py ├── alt_requirements ├── conda-requirements.txt ├── requirements_bare.txt ├── requirements_dev.txt ├── requirements_docs.txt ├── requirements_full.txt ├── requirements_pretrained_embeddings_mitie.txt └── requirements_pretrained_embeddings_spacy.txt ├── client ├── .gitignore ├── JOOMLA.md ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── chatlogo.png │ ├── favicon.ico │ ├── index.html │ ├── manifest.json │ └── profile.png └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ └── serviceWorker.js ├── config.yml ├── credentials.yml ├── data ├── departments.txt ├── faculties.txt ├── nlu.md ├── software-dtic.txt └── stories.md ├── data_bk ├── archive │ ├── test │ │ ├── nlu_v1.md │ │ └── stories_v1.md │ └── train │ │ ├── nlu_v1.md │ │ └── stories_v1.md ├── nlu.md ├── nlu_chatito │ ├── archive │ │ ├── glpiCommons_v1.chatito │ │ ├── glpiCommons_v2.chatito │ │ ├── glpiHeldesk_v1.chatito │ │ └── glpiHelpdesk_v2.chatito │ ├── glpiCommons.chatito │ ├── glpiHeldesk.chatito │ ├── test │ │ ├── testing_dataset_130919.json │ │ ├── testing_dataset_1566746285.json │ │ └── testing_dataset_270819.json │ └── train │ │ ├── training_dataset_130919.json │ │ ├── training_dataset_1566746285.json │ │ └── training_dataset_270819.json ├── stories.md ├── test │ ├── nlu.md │ ├── nlu_extras.md │ └── stories.md └── train │ ├── nlu.md │ ├── nlu_extras.md │ ├── sistemas-dtic.txt │ └── stories.md ├── docker-compose.override.yml ├── domain.yml ├── endpoints.yml ├── format_results.py ├── glpi_credentials.yml ├── rasa-stack-mockup.gif ├── requirements-actions.txt ├── requirements-dev.txt ├── requirements.txt ├── results.md ├── results ├── DIETClassifier_errors.json ├── DIETClassifier_report.json ├── confmat.png ├── hist.png ├── intent_errors.json └── intent_report.json ├── scripts ├── manage_user.py ├── startActions.sh ├── startClient.sh └── startRasaX.sh └── tests └── conversation_tests.md /.github/workflows/action-server-ci.yml: -------------------------------------------------------------------------------- 1 | name: Build Action Server Image 2 | on: 3 | push: 4 | branches: 5 | - 'develop' 6 | pull_request: 7 | types: [opened, synchronize, reopened] 8 | 9 | jobs: 10 | docker: 11 | name: Build Action Server Docker Image 12 | runs-on: ubuntu-latest 13 | 14 | env: 15 | DOCKERHUB_USERNAME: santteegt 16 | IS_PUSH_EVENT: ${{ github.event_name == 'push' }} 17 | 18 | steps: 19 | - name: Checkout git repository 🕝 20 | uses: actions/checkout@v2 21 | 22 | - name: Login to DockerHub Registry 🔢 23 | run: echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login -u ${{ env.DOCKERHUB_USERNAME }} --password-stdin || true 24 | 25 | - name: Pull latest${{ matrix.image.tag_ext }} Docker image for caching 26 | run: docker pull santteegt/glpi-action-server:latest || true 27 | 28 | - name: Build latest${{ matrix.image.tag_ext }} Docker image 29 | run: docker build . --tag santteegt/glpi-action-server:latest --cache-from santteegt/glpi-action-server:latest 30 | 31 | - name: Push image with latest tag 📦 32 | if: github.event_name == 'push' && github.ref == 'refs/heads/master' 33 | run: docker push santteegt/glpi-action-server:latest -------------------------------------------------------------------------------- /.github/workflows/model-ci.yml: -------------------------------------------------------------------------------- 1 | name: Model CI 2 | on: 3 | push: 4 | branches: 5 | - 'develop' 6 | paths-ignore: 7 | - "README.md" 8 | - "Makefile" 9 | - "Dockerfile" 10 | 11 | jobs: 12 | # lint-testing: 13 | # name: Code Formatting Tests 14 | # runs-on: ubuntu-latest 15 | # steps: 16 | # - uses: actions/checkout@v2 17 | # - name: Set up Python 3.7 18 | # uses: actions/setup-python@v1 19 | # with: 20 | # python-version: 3.7 21 | # - name: Install dependencies 22 | # run: | 23 | # python -m pip install -U pip 24 | # pip install -r requirements-dev.txt 25 | # - name: Code Formatting Tests 26 | # run: | 27 | # make formatter 28 | # type-testing: 29 | # name: Type Tests 30 | # runs-on: ubuntu-latest 31 | # steps: 32 | # - uses: actions/checkout@v2 33 | # - name: Set up Python 3.7 34 | # uses: actions/setup-python@v1 35 | # with: 36 | # python-version: 3.7 37 | # - name: Install dependencies 38 | # run: | 39 | # python -m pip install -U pip 40 | # pip install -r requirements-dev.txt 41 | # - name: Type Checking 42 | # working-directory: ${{ github.workspace }} 43 | # run: | 44 | # make types 45 | build-model: 46 | name: Build and test the model 47 | runs-on: ubuntu-latest 48 | 49 | steps: 50 | - uses: actions/checkout@v2 51 | 52 | - name: Set up Python 3.7 53 | uses: actions/setup-python@v1 54 | with: 55 | python-version: 3.7 56 | 57 | - name: Install dependencies 58 | run: | 59 | python -m pip install -U pip 60 | pip install -r requirements-dev.txt 61 | python -m spacy download es_core_news_md && python -m spacy link es_core_news_md es 62 | 63 | - name: Rasa Data Validation 64 | run: | 65 | make validate 66 | 67 | - name: Train the model 68 | run: | 69 | rasa train 70 | 71 | - name: Run Through e2e Stories 72 | run: | 73 | make e2e 74 | 75 | - name: Cross-validate NLU model 76 | if: github.event_name == 'pull_request' 77 | run: | 78 | make crossval 79 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Standard Ignores 2 | .env 3 | venv 4 | __pycache__/ 5 | .DS_Store 6 | .idea 7 | .vscode/ 8 | .history/ 9 | .pytype/ 10 | 11 | # Rasa Ignores 12 | credentials.yml 13 | *.db-* 14 | rasa.db* 15 | *.db 16 | *.logs 17 | models/ -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rasa/rasa-sdk:1.10.0 2 | 3 | WORKDIR /app 4 | 5 | COPY actions ./actions 6 | COPY requirements-actions.txt ./ 7 | 8 | USER root 9 | 10 | RUN pip install -U pip && \ 11 | pip install --no-cache-dir -r requirements-actions.txt 12 | 13 | USER 1001 14 | 15 | CMD ["start", "--actions", "actions", "--debug"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | help: 2 | @echo "make" 3 | @echo " clean" 4 | @echo " Remove Python/build artifacts." 5 | @echo " formatter" 6 | @echo " Apply black formatting to code." 7 | @echo " lint" 8 | @echo " Lint code with flake8, and check if black formatter should be applied." 9 | @echo " types" 10 | @echo " Check for type errors using pytype." 11 | @echo " validate" 12 | @echo " Runs the rasa data validate to verify data." 13 | @echo " test" 14 | @echo " Runs the rasa test suite checking for issues." 15 | @echo " crossval" 16 | @echo " Runs the rasa cross validation tests and creates results.md" 17 | @echo " shell" 18 | @echo " Runs the rasa train and rasa shell for testing" 19 | 20 | 21 | clean: 22 | find . -name '*.pyc' -exec rm -f {} + 23 | find . -name '*.pyo' -exec rm -f {} + 24 | find . -name '*~' -exec rm -f {} + 25 | rm -rf build/ 26 | rm -rf .pytype/ 27 | rm -rf dist/ 28 | rm -rf docs/_build 29 | 30 | formatter: 31 | black actions/* --line-length 90 32 | 33 | lint: 34 | flake8 actions/* 35 | black actions/* --line-length 90 36 | 37 | types: 38 | pytype --keep-going actions 39 | 40 | validate: 41 | # rasa train 42 | rasa data validate --max-history 5 --debug 43 | 44 | e2e: 45 | # rasa train 46 | rasa test core --stories tests/conversation_tests.md --fail-on-prediction-errors --e2e 47 | 48 | crossval: 49 | rasa test nlu -f 5 --cross-validation 50 | python format_results.py 51 | 52 | shell: 53 | rasa train --debug 54 | rasa shell --debug -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GLPI Helpdesk bot 2 | 3 | AI assistant for the GLPI IT Helpdesk. It includes an integration with its API to open incident reports. 4 | 5 | ## Supported features 6 | * Login & Auth validation using Google OAuth (TODO) (login) 7 | * Open an incident ticket on GLPI (open_incident) 8 | * Get the current status of a ticket (get_incident_status) 9 | * Reset my password (password_reset) 10 | * Issues with email (problem_email) 11 | * Request biometrics report (request_biometrics_report) 12 | * Request a VM (request_vm) 13 | * FAQ: How to connect to the WiFi? (connect_wifi) 14 | * FAQ: How to create a user? (create_user) 15 | 16 | ## MISC Intents 17 | * greet 18 | * goodbye 19 | * thank 20 | * bot_challenge 21 | * help 22 | * show_menu 23 | * inform 24 | * confirm 25 | * deny 26 | * out_of_scope 27 | 28 | ## Lookup Tables 29 | * [Software](data/software-dtic.txt) 30 | * [Faculties](data/faculties.txt) 31 | * [Departments](data/departments.txt) 32 | 33 | ## Requirements 34 | 35 | * Python 3.7+ 36 | * Pip3 37 | * Virtualenv or Conda (Recommended for isolated env creation) 38 | 39 | ## Setup and installation 40 | 41 | If you haven’t installed Rasa NLU and Rasa Core yet, you can do it by navigating to the project directory and running: 42 | 43 | ``` 44 | pip install -r requirements.txt 45 | ``` 46 | 47 | You also need to install the spaCy Spanish language model. You can install it by running: 48 | 49 | ``` 50 | python -m spacy download es_core_news_md 51 | python -m spacy link es_core_news_md es 52 | ``` 53 | 54 | ## Development instructions 55 | 56 | ### Validate training data 57 | 58 | ```bash 59 | rasa data validate 60 | ``` 61 | 62 | ### Training Rasa Core & NLU models 63 | 64 | The following command trains both the Core and NLU models 65 | 66 | ```bash 67 | rasa train 68 | ``` 69 | 70 | ### NLU model evaluation 71 | 72 | The following command performs a model evaluation of the latest trained NLU model under the `models` directory 73 | 74 | ```bash 75 | rasa data split nlu 76 | rasa test nlu -u train_test_split/test_data.md --out nlu_metrics/ 77 | # or 5 (default -f) cross validation 78 | rasa test nlu -u data/nlu.md --cross-validation --out nlu_metrics/ 79 | ``` 80 | 81 | Finally, check the following files for results: 82 | 83 | * [Intent Confusion Matrix](nlu_metrics/confmat.png) 84 | * [Intent Confidence Prediction][nlu_metrics/hist.png] 85 | * [Intent/Entity Metrics Report](nlu_metrics/intent_report.json) 86 | 87 | Within the [nlu_metrics](nlu_metrics) folder there are also other reportes for each the NLU pipeline components (e.g. DIETClassifier report and errors) 88 | 89 | ### Dialogue (CORE) model evaluation 90 | 91 | The following command performs a model evaluation of the latest trained dialogue model under the `models` directory 92 | 93 | ```bash 94 | rasa test core --stories tests/e2e-stories.md --out core_metrics/ 95 | ``` 96 | 97 | Finally, check the [results](core_metrics/) directory for a summary of the performed evaluation 98 | 99 | ### Visualizing stories 100 | 101 | ```bash 102 | rasa visualize -d domain.yml --stories data/stories.md -u data/nlu.md --out core_metrics/graph.html 103 | ``` 104 | ## Chatbot Deployment 105 | 106 | ### Deploying custom actions locally 107 | 108 | ```bash 109 | rasa run actions --actions actions -p 5055 110 | ``` 111 | 112 | or as a Docker container 113 | 114 | ```bash 115 | docker build . --tag glpi-action-server 116 | docker run -p 5055:5055 glpi-action-server 117 | ``` 118 | 119 | or as a background process 120 | 121 | ```bash 122 | sh scripts/startActions.sh 123 | ``` 124 | 125 | ### Deploy DucklingHTTPExtractor (Optional if Enabled on the NLU pipeline) 126 | 127 | ```bash 128 | docker run -p 8000:8000 rasa/duckling 129 | ``` 130 | 131 | ### Test your chatbot locally 132 | 133 | ```bash 134 | rasa shell --endpoints endpoints.yml 135 | ``` 136 | 137 | ### Run Chatbot + Rasa X Locally (*DEPRECATED*) 138 | 139 | Rasa X is a tool designed to make it easier to deploy and improve Rasa-powered assistants by learning from real conversations 140 | 141 | ```bash 142 | rasa x --data data/train/ --endpoints endpoints.yml --cors '*' --enable-api --port 5005 --rasa-x-port 5002 143 | ``` 144 | 145 | or as a background process 146 | 147 | ```bash 148 | sh scripts/startRasaX.sh 149 | ``` 150 | 151 | Update admin password 152 | 153 | ```bash 154 | python scripts/manage_user.py create me $RASA_X_PASSWORD admin --update 155 | ``` 156 | 157 | ### Deploy the chatbot without RasaX & enabled connection to a web channel through `sockets.io` 158 | 159 | ```bash 160 | rasa run --endpoints endpoints.yml --credentials credentials.yml --enable-api --cors "*" --port 5005 161 | ``` 162 | 163 | ### Deploy the web client 164 | 165 | ```bash 166 | cd client 167 | npm install 168 | npm start 169 | ``` 170 | 171 | or as a background process 172 | 173 | ```bash 174 | sh scripts/startClient.sh 175 | ``` 176 | 177 | ### Deployment on server 178 | 179 | * Install Rasa + RasaX using [Docker Compose Quick Start Guide](https://rasa.com/docs/rasa-x/installation-and-setup/docker-compose-script/#) 180 | 181 | * To upgrade the components to their latest release, follow this [instructions](https://rasa.com/docs/rasa-x/installation-and-setup/updating/#docker-compose-quick-install) 182 | 183 | * To update the admin password run the following command within `RASA_HOME` 184 | 185 | ```bash 186 | python rasa_x_commands.py create --update admin me glpi@dmin 187 | ``` 188 | 189 | * Build the Action Server Docker Image (in case you want to build your own locally) 190 | 191 | ```bash 192 | export GLPI_DOCKER_IMAGE=santteegt/glpi-chatbot-actions:latest 193 | docker build -t $GLPI_DOCKER_IMAGE . 194 | ``` 195 | 196 | * Each time a commit is pushed to the `develop` branch, the DockerHub registry deploys a new image with the latest changes 197 | 198 | * To do a manual push to DockerHub (Optional) 199 | 200 | ```bash 201 | docker login --username santteegt 202 | docker push $GLPI_DOCKER_IMAGE 203 | ``` 204 | 205 | * Copy `socketio` settings from [credentials.yml](credentials.yml) to the `credentials.yml` file in the `RASA_HOME` directory 206 | 207 | * Copy the [docker-compose.override.yml](docker-compose.override.yml) file to the `RASA_HOME` directory 208 | 209 | * Set the following environment variables on the `.env` file within the `RASA_HOME` directory 210 | 211 | - GLPI_API_URI: (Setup > General > API) <- where you can find the info on your GLPI instance 212 | - GLPI_APP_TOKEN: (Setup > General > API) 213 | - GLPI_AUTH_TOKEN: (User Preferences > API Token) 214 | - GLPI_LOCALMODE: false (true if you don't want ) 215 | 216 | * Start Docker Compose: 217 | 218 | ```bash 219 | docker-compose up -d 220 | ``` 221 | 222 | * If you started the service for the first time or just updated it, you need to install the ES Spacy language model in both `rasa-production` and `rasa-worker` containers: 223 | 224 | ``` 225 | docker-compose exec -u 0 rasa-production bash -c "python -m spacy download es_core_news_md && python -m spacy link es_core_news_md es" 226 | docker-compose exec -u 0 rasa-worker bash -c "python -m spacy download es_core_news_md && python -m spacy link es_core_news_md es" 227 | ``` 228 | 229 | #### Workaround with connection timeout error when trying to add your Git project to RasaX 230 | 231 | 1. Access the `rasa-x` container shell 232 | 233 | ``` 234 | docker exec -u 0 -it bash 235 | ``` 236 | 237 | 1. Add an SSH config file in `/app/.ssh/config` with the following: 238 | 239 | ``` 240 | Host github.com 241 | Hostname ssh.github.com 242 | Port 443 243 | ``` 244 | 245 | 1. Add **-F /app/.ssh/config** as parameter on the ssh executable script `/usr/local/lib/python3.7/site-packages/rasax/community/services/integrated_version_control/git_service.py`: 246 | 247 | ``` 248 | def _save_ssh_executable(path: Path, path_to_key: Path) -> None: 249 | command = f""" 250 | #!/bin/sh 251 | ID_RSA={path_to_key} 252 | # Kubernetes tends to reset file permissions on restart. Hence, re-apply the required 253 | # permissions whenever using the key. 254 | chmod 600 $ID_RSA 255 | exec /usr/bin/ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $ID_RSA -F /app/.ssh/config "$@" 256 | """ 257 | ``` 258 | 259 | 1. Restart the compose environment 260 | 261 | ## MISC Suggestions / Instructions 262 | 263 | ### Caveat for using the Webchat client (DEPRECATED) 264 | 265 | See this [issue](https://github.com/mrbot-ai/rasa-webchat/issues/28) 266 | 267 | ```bash 268 | pip install git+git://github.com/RasaHQ/rasa.git 269 | 270 | ``` 271 | 272 | ### Workaround to make Rasa work if AVX is not compatible with your CPU (DEPRECATED) 273 | 274 | You may experience the following error on an on-premise and/or cloud server (deployed with Kubernetes): `The TensorFlow library was compiled to use AVX instructions` 275 | 276 | In order to fix this issue, execute the following commands after installing rasa dependencies as shown above: 277 | 278 | ```bash 279 | pip uninstall tensorflow -y 280 | conda create --name glpi-rasax python=3.6.8 281 | conda activate glpi-rasax 282 | conda install -c anaconda -n glpi-rasax tensorflow==1.15.0 283 | conda deactivate glpi-rasax 284 | export PYTHONPATH='${HOME}/anaconda3/envs/glpi-rasax/lib/python3.6/site-packages' 285 | ``` 286 | 287 | ### Prepare dataset for training/testing (DEPRECATED) 288 | 289 | If you're (re-)generating data using Chatito, paste the related files under the `data/nlu_chatito` folder and then execute the following commands: 290 | 291 | ```bash 292 | rasa data convert nlu --data data/nlu_chatito/train/ --out data/train/nlu.md -l es -f md 293 | rasa data convert nlu --data data/nlu_chatito/test/ --out data/test/nlu.md -l es -f md 294 | ``` -------------------------------------------------------------------------------- /actions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santteegt/glpi_chatbot/5685d12216fa4c0f790ca9b85c7320a66d5ba8be/actions/__init__.py -------------------------------------------------------------------------------- /actions/actions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import logging 4 | from typing import Text, List, Dict, Any, Union, Optional 5 | from rasa_sdk import Tracker 6 | from rasa_sdk.events import EventType, SlotSet 7 | from rasa_sdk.forms import FormAction 8 | from rasa_sdk.executor import CollectingDispatcher 9 | 10 | from actions.actions_base import request_next_slot 11 | from actions.constants import EntitySlotEnum, IntentEnum, UtteranceEnum 12 | from actions.glpi import GLPIService, GlpiException, load_glpi_config, Ticket 13 | from actions.parsing import remove_accents 14 | 15 | logger = logging.getLogger(__name__) 16 | 17 | glpi_api_uri, glpi_app_token, glpi_auth_token, local_mode = load_glpi_config() 18 | glpi = ( 19 | GLPIService.get_instance(glpi_api_uri, glpi_app_token, glpi_auth_token) 20 | if not local_mode 21 | else None 22 | ) 23 | 24 | 25 | class ComputeResourceForm(FormAction): 26 | """Contextual ActionForm to handle Compute Resources requests""" 27 | 28 | def name(self) -> Text: 29 | """Unique identifier of the form""" 30 | 31 | return "compute_resource_form" 32 | 33 | @staticmethod 34 | def required_slots(tracker: Tracker) -> List[Text]: 35 | """A list of required slots that the form has to fill""" 36 | 37 | # if environment == production 38 | if ( 39 | tracker.get_slot(EntitySlotEnum.VM_ENVIRONMENT) 40 | == ComputeResourceForm.valid_environment_types()[2] 41 | ): 42 | return [ 43 | EntitySlotEnum.DEPARTMENT, 44 | EntitySlotEnum.VM_ENVIRONMENT, 45 | EntitySlotEnum.VM_RAM, 46 | EntitySlotEnum.VM_CPU_CORES, 47 | EntitySlotEnum.VM_DISK_SPACE, 48 | EntitySlotEnum.VM_SCALABILITY, 49 | EntitySlotEnum.OBSERVATIONS, 50 | EntitySlotEnum.CONFIRM, 51 | ] 52 | else: 53 | return [ 54 | EntitySlotEnum.DEPARTMENT, 55 | EntitySlotEnum.VM_ENVIRONMENT, 56 | EntitySlotEnum.VM_RAM, 57 | EntitySlotEnum.VM_CPU_CORES, 58 | EntitySlotEnum.VM_DISK_SPACE, 59 | EntitySlotEnum.OBSERVATIONS, 60 | EntitySlotEnum.CONFIRM, 61 | ] 62 | 63 | def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]: 64 | """A dictionary to map required slots to 65 | - an extracted entity 66 | - intent: value pairs 67 | - a whole message 68 | or a list of them, where a first match will be picked""" 69 | 70 | return { 71 | EntitySlotEnum.DEPARTMENT: [ 72 | self.from_entity( 73 | entity=EntitySlotEnum.DEPARTMENT, not_intent=IntentEnum.OUT_OF_SCOPE, 74 | ), 75 | self.from_text(), 76 | ], 77 | EntitySlotEnum.VM_ENVIRONMENT: self.from_entity( 78 | entity=EntitySlotEnum.VM_ENVIRONMENT, not_intent=IntentEnum.OUT_OF_SCOPE, 79 | ), 80 | EntitySlotEnum.VM_RAM: self.from_entity( 81 | entity=EntitySlotEnum.VM_RAM, not_intent=IntentEnum.OUT_OF_SCOPE, 82 | ), 83 | EntitySlotEnum.VM_CPU_CORES: self.from_entity( 84 | entity=EntitySlotEnum.VM_CPU_CORES, not_intent=IntentEnum.OUT_OF_SCOPE, 85 | ), 86 | EntitySlotEnum.VM_DISK_SPACE: self.from_entity( 87 | entity=EntitySlotEnum.VM_DISK_SPACE, not_intent=IntentEnum.OUT_OF_SCOPE, 88 | ), 89 | EntitySlotEnum.VM_SCALABILITY: [ 90 | self.from_entity( 91 | entity=EntitySlotEnum.VM_SCALABILITY, 92 | not_intent=IntentEnum.OUT_OF_SCOPE, 93 | ), 94 | self.from_intent(intent=IntentEnum.CONFIRM, value=True), 95 | self.from_intent(intent=IntentEnum.DENY, value=False), 96 | ], 97 | EntitySlotEnum.OBSERVATIONS: [ 98 | self.from_entity(entity=EntitySlotEnum.OBSERVATIONS), 99 | self.from_text(not_intent=IntentEnum.OUT_OF_SCOPE), 100 | ], 101 | EntitySlotEnum.CONFIRM: [ 102 | self.from_intent(intent=IntentEnum.CONFIRM, value=True), 103 | self.from_intent(intent=IntentEnum.DENY, value=False), 104 | ], 105 | } 106 | 107 | def request_next_slot( 108 | self, 109 | dispatcher: "CollectingDispatcher", 110 | tracker: "Tracker", 111 | domain: Dict[Text, Any], 112 | ) -> Optional[List[EventType]]: 113 | """Customize ask utterance for certain slots 114 | This is Required to enable the {form_name}_{confirm} slot 115 | """ 116 | return request_next_slot(self, dispatcher, tracker, domain) 117 | 118 | @staticmethod 119 | def valid_environment_types() -> List[Text]: 120 | """Database of supported environment types""" 121 | 122 | return ["desarrollo", "pruebas", "produccion"] 123 | 124 | @staticmethod 125 | def is_int(string: Text) -> bool: 126 | """Check if a string is an integer""" 127 | 128 | try: 129 | int(string) 130 | return True 131 | except ValueError: 132 | return False 133 | 134 | @staticmethod 135 | def is_within_bound(value: int, lower_bount: int, upper_bound: int) -> bool: 136 | """Check if an int value is within a specified bound""" 137 | 138 | return True if lower_bount <= value <= upper_bound else False 139 | 140 | def validate_vm_environment( 141 | self, 142 | value: Text, 143 | dispatcher: CollectingDispatcher, 144 | tracker: Tracker, 145 | domain: Dict[Text, Any], 146 | ) -> Dict[Text, Any]: 147 | """Validate vm_environment value""" 148 | 149 | if value.lower() in self.valid_environment_types(): 150 | # validation succeeded, set the value of the "cuisine" slot to value 151 | return {EntitySlotEnum.VM_ENVIRONMENT: value} 152 | else: 153 | dispatcher.utter_message(template=UtteranceEnum.INVALID) 154 | # validation failed, set this slot to None, meaning the 155 | # user will be asked for the slot again 156 | return {EntitySlotEnum.VM_ENVIRONMENT: None} 157 | 158 | def validate_vm_ram( 159 | self, 160 | value: Text, 161 | dispatcher: CollectingDispatcher, 162 | tracker: Tracker, 163 | domain: Dict[Text, Any], 164 | ) -> Dict[Text, Any]: 165 | """Validate ram value""" 166 | 167 | if self.is_int(value) and self.is_within_bound(int(value), 8, 64): 168 | return {EntitySlotEnum.VM_RAM: value} 169 | else: 170 | dispatcher.utter_message(template=UtteranceEnum.INVALID) 171 | return {EntitySlotEnum.VM_RAM: None} 172 | 173 | def validate_vm_cpu_cores( 174 | self, 175 | value: Text, 176 | dispatcher: CollectingDispatcher, 177 | tracker: Tracker, 178 | domain: Dict[Text, Any], 179 | ) -> Dict[Text, Any]: 180 | """Validate CPU cores value""" 181 | 182 | if self.is_int(value) and self.is_within_bound(int(value), 1, 8): 183 | return {EntitySlotEnum.VM_CPU_CORES: value} 184 | else: 185 | dispatcher.utter_message(template=UtteranceEnum.INVALID) 186 | return {EntitySlotEnum.VM_CPU_CORES: None} 187 | 188 | def validate_vm_disk_space( 189 | self, 190 | value: Text, 191 | dispatcher: CollectingDispatcher, 192 | tracker: Tracker, 193 | domain: Dict[Text, Any], 194 | ) -> Dict[Text, Any]: 195 | """Validate disk space value""" 196 | 197 | if self.is_int(value) and self.is_within_bound(int(value), 8, 1000): 198 | return {EntitySlotEnum.VM_DISK_SPACE: value} 199 | else: 200 | dispatcher.utter_message(template=UtteranceEnum.INVALID) 201 | return {EntitySlotEnum.VM_DISK_SPACE: None} 202 | 203 | def validate_vm_scalability( 204 | self, 205 | value: Text, 206 | dispatcher: CollectingDispatcher, 207 | tracker: Tracker, 208 | domain: Dict[Text, Any], 209 | ) -> Dict[Text, Any]: 210 | """Validate scalability value and set it to NO by default""" 211 | 212 | if isinstance(value, str): 213 | return {EntitySlotEnum.VM_SCALABILITY: value} 214 | else: 215 | return {EntitySlotEnum.VM_SCALABILITY: "No"} 216 | 217 | def submit( 218 | self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], 219 | ) -> List[Dict]: 220 | """Define what the form has to do after all required slots are filled""" 221 | 222 | department = tracker.get_slot(EntitySlotEnum.DEPARTMENT) 223 | vm_environment = tracker.get_slot(EntitySlotEnum.VM_ENVIRONMENT) 224 | vm_ram = tracker.get_slot(EntitySlotEnum.VM_RAM) 225 | vm_cpu_cores = tracker.get_slot(EntitySlotEnum.VM_CPU_CORES) 226 | vm_disk_space = tracker.get_slot(EntitySlotEnum.VM_DISK_SPACE) 227 | vm_scalability = tracker.get_slot(EntitySlotEnum.VM_SCALABILITY) 228 | observations = tracker.get_slot(EntitySlotEnum.OBSERVATIONS) 229 | 230 | request_description = ( 231 | "Solicito una maquina virtual con las siguientes caracteristicas: " 232 | + f"Departamento: {department} ||" 233 | + f"Entorno: {vm_environment} ||" 234 | + f"Memoria RAM: {vm_ram} ||" 235 | + f"No CPUs: {vm_cpu_cores} ||" 236 | + f"Disco duro: {vm_disk_space} Gb ||" 237 | + f"Escalabilidad: {vm_scalability if vm_scalability is not None else 'No'} ||" 238 | + f"Observaciones: {observations}" 239 | ) 240 | 241 | logger.info(f"{self.name()}: {request_description}") 242 | 243 | events = [ 244 | SlotSet(EntitySlotEnum.ITILCATEGORY_ID, None), 245 | SlotSet(EntitySlotEnum.DEPARTMENT, None), 246 | SlotSet(EntitySlotEnum.VM_ENVIRONMENT, None), 247 | SlotSet(EntitySlotEnum.VM_RAM, None), 248 | SlotSet(EntitySlotEnum.VM_CPU_CORES, None), 249 | SlotSet(EntitySlotEnum.VM_DISK_SPACE, None), 250 | SlotSet(EntitySlotEnum.VM_SCALABILITY, None), 251 | SlotSet(EntitySlotEnum.OBSERVATIONS, None), 252 | ] 253 | 254 | if tracker.get_slot(EntitySlotEnum.CONFIRM): 255 | # priorities = GLPIService.priority_values() 256 | # priority_values = list(priorities.keys()) 257 | # glpi_priority = priorities[priority_values[1]] # media 258 | ticket: Ticket = Ticket( 259 | { 260 | "username": "normal", # TODO: set the actual logged in user 261 | "title": "Peticion de Maquina Virtual", 262 | "description": remove_accents(request_description), 263 | # 'priority': glpi_priority 264 | "itilcategories_id": 54, # Equipos de computo 265 | } 266 | ) 267 | if local_mode: 268 | dispatcher.utter_message( 269 | f"Esta acción crearía un ticket con la siguiente información: {ticket}" 270 | ) 271 | ticket_id: Text = "DUMMY" 272 | events.append(SlotSet(EntitySlotEnum.TICKET_NO, ticket_id)) 273 | else: # TODO: integrate with GLPI 274 | try: 275 | response = glpi.create_ticket(ticket, ticket_type=2) # Solicitud 276 | ticket_id = response["id"] 277 | # This is not actually required as its value is sent directly to the utter_message 278 | events.append(SlotSet(EntitySlotEnum.TICKET_NO, ticket_id)) 279 | except GlpiException as e: 280 | logger.error("Error when trying to create a ticket", e) 281 | logger.error(f"Ticket: {ticket}") 282 | dispatcher.utter_message(template=UtteranceEnum.PROCESS_FAILED) 283 | return events 284 | dispatcher.utter_message( 285 | template=UtteranceEnum.TICKET_NO, ticket_no=ticket_id 286 | ) 287 | dispatcher.utter_message(template=UtteranceEnum.CONFIRM_REQUEST) 288 | else: 289 | events.append(SlotSet(EntitySlotEnum.TICKET_NO, None)) 290 | dispatcher.utter_message(template=UtteranceEnum.PROCESS_CANCELLED) 291 | 292 | return events 293 | -------------------------------------------------------------------------------- /actions/actions_base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import logging 4 | 5 | from rasa_sdk import Action, Tracker 6 | from rasa_sdk.events import EventType, SlotSet 7 | from rasa_sdk.executor import CollectingDispatcher 8 | from rasa_sdk.forms import FormAction, REQUESTED_SLOT 9 | from typing import Dict, Text, Any, List, Optional 10 | 11 | from actions.constants import EntitySlotEnum, IntentEnum, UtteranceEnum 12 | 13 | logger = logging.getLogger(__name__) 14 | 15 | 16 | def request_next_slot( 17 | form: FormAction, 18 | dispatcher: CollectingDispatcher, 19 | tracker: Tracker, 20 | domain: Dict[Text, Any], 21 | ) -> Optional[List[EventType]]: 22 | """ 23 | Custom method to set a custom utterance templata if slot == confirm 24 | :param form: Form Action object 25 | :param dispatcher: Rasa SDK Dispatcher 26 | :param tracker: Rasa SDK tracker 27 | :param domain: Rasa domain 28 | :return: SlotSet event 29 | """ 30 | for slot in form.required_slots(tracker): 31 | if form._should_request_slot(tracker, slot): 32 | utter_template = f"utter_ask{f'_{form.name()}' if slot == EntitySlotEnum.CONFIRM else ''}_{slot}" 33 | dispatcher.utter_message(template=utter_template, **tracker.slots) 34 | return [SlotSet(REQUESTED_SLOT, slot)] 35 | 36 | 37 | def ask_if_success( 38 | dispatcher: CollectingDispatcher, incident_title: Text, itilcategory_id: int = None 39 | ): 40 | """ 41 | Ask if request was succesful. Otherwise redirects to report an incident 42 | :param dispatcher: Rasa SDK Dispatcher 43 | :param incident_title: Incident title for the ticket 44 | :param itilcategory_id: ITIL category for the incident 45 | """ 46 | 47 | params = "{" 48 | params += f'"{EntitySlotEnum.INCIDENT_TITLE}":"{incident_title}"' 49 | if itilcategory_id: 50 | params += f', "{EntitySlotEnum.ITILCATEGORY_ID}":"{itilcategory_id}"' 51 | params += "}" 52 | 53 | dispatcher.utter_message( 54 | template=UtteranceEnum.CONFIRM_SUCCESS, 55 | buttons=[ 56 | {"title": "Si", "payload": f"/{IntentEnum.CONFIRM}"}, 57 | {"title": "No", "payload": f"/{IntentEnum.DENY}" + params}, 58 | ], 59 | ) 60 | 61 | 62 | class ActionDefaultAskAffirmation(Action): 63 | """Asks for an affirmation of the intent if NLU threshold is not met.""" 64 | 65 | def name(self): 66 | return "action_default_ask_affirmation" 67 | 68 | def __init__(self): 69 | self.intent_mappings = { 70 | IntentEnum.CONNECT_WIFI: "Ayuda con conexión al WiFI", 71 | IntentEnum.CREATE_USER: "Ayuda a crear un usuario", 72 | IntentEnum.REQUEST_BIOMETRICS_REPORT: "Informe de marcación en biométrico", 73 | IntentEnum.REQUEST_VM: "Solicitud de máquina virtual", 74 | IntentEnum.PASSWORD_RESET: "Recuperar contraseña", 75 | IntentEnum.PROBLEM_EMAIL: "Problema con el correo electrónico", 76 | IntentEnum.OPEN_INCIDENT: "Reportar una incidencia", 77 | IntentEnum.SHOW_MENU: "Ver menu de opciones", 78 | } 79 | # read the mapping from a csv and store it in a dictionary 80 | # with open('intent_mapping.csv', newline='', encoding='utf-8') as file: 81 | # csv_reader = csv.reader(file) 82 | # for row in csv_reader: 83 | # self.intent_mappings[row[0]] = row[1] 84 | 85 | def run(self, dispatcher, tracker, domain): 86 | # get the most likely intent 87 | last_intent_name = tracker.latest_message["intent"]["name"] 88 | 89 | mapping_exists = ( 90 | True if last_intent_name in self.intent_mappings.keys() else False 91 | ) 92 | 93 | if mapping_exists: 94 | # get the prompt for the intent 95 | intent_prompt = self.intent_mappings[last_intent_name] 96 | 97 | # Create the affirmation message and add two buttons to it. 98 | # Use '/' as payload to directly trigger '' 99 | # when the button is clicked. 100 | message = "Tal vez quiso decir '{}'?".format(intent_prompt) 101 | buttons = [ 102 | {"title": "Si", "payload": f"/{last_intent_name}"}, 103 | {"title": "No", "payload": f"/{IntentEnum.SHOW_MENU}"}, 104 | ] 105 | dispatcher.utter_button_message(message, buttons=buttons) 106 | else: 107 | # TODO: narrow a list of most probable intents? 108 | logger.info("NO ACTION FOUND. Showing suggestions") 109 | dispatcher.utter_image_url( 110 | "http://www.crear-meme.com/public/img/memes_users/what-7.jpg" 111 | ) 112 | # tracker.trigger_followup_action("utter_sugerencias") 113 | dispatcher.utter_message(template=UtteranceEnum.SUGGEST) 114 | 115 | return [] 116 | -------------------------------------------------------------------------------- /actions/actions_faqs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import logging 4 | from typing import Dict, Text, Any, List, Union 5 | from rasa_sdk import Tracker 6 | from rasa_sdk.executor import CollectingDispatcher 7 | from rasa_sdk.forms import FormAction 8 | from rasa_sdk.events import SlotSet 9 | 10 | import re 11 | 12 | from actions.actions_base import ask_if_success 13 | from actions.constants import EntitySlotEnum, IntentEnum, UtteranceEnum 14 | 15 | logger = logging.getLogger(__name__) 16 | 17 | 18 | class WifiFaqForm(FormAction): 19 | def name(self) -> Text: 20 | return "wifi_faq_form" 21 | 22 | @staticmethod 23 | def required_slots(tracker: Tracker) -> List[Text]: 24 | """A list of required slots that the form has to fill""" 25 | 26 | # logger.info(f'Current WIFI NET: {tracker.get_slot(EntitySlotEnum.WIFI_NETWORK)}') 27 | # TODO: check why it isn't asking for an email 28 | 29 | if ( 30 | tracker.get_slot(EntitySlotEnum.WIFI_NETWORK) 31 | in WifiFaqForm.wifi_network_db()[:2] 32 | ): 33 | return [EntitySlotEnum.WIFI_NETWORK, EntitySlotEnum.EMAIL] 34 | else: 35 | return [EntitySlotEnum.WIFI_NETWORK] 36 | 37 | def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]: 38 | """A dictionary to map required slots to 39 | - an extracted entity 40 | - intent: value pairs 41 | - a whole message 42 | or a list of them, where a first match will be picked""" 43 | 44 | return { 45 | EntitySlotEnum.EMAIL: self.from_entity(entity=EntitySlotEnum.EMAIL), 46 | EntitySlotEnum.WIFI_NETWORK: [ 47 | self.from_entity(entity=EntitySlotEnum.WIFI_NETWORK), 48 | self.from_text(intent=[IntentEnum.CONNECT_WIFI, IntentEnum.INFORM]), 49 | ], 50 | } 51 | 52 | @staticmethod 53 | def wifi_network_db() -> List[Text]: 54 | """Database of supported wifi networks""" 55 | 56 | return ["eduroam", "ucwifi", "guest"] 57 | 58 | def validate_wifi_network( 59 | self, 60 | value: Text, 61 | dispatcher: CollectingDispatcher, 62 | tracker: Tracker, 63 | domain: Dict[Text, Any], 64 | ) -> Dict[Text, Any]: 65 | """Validate wifi_network has a valid value.""" 66 | 67 | if value.lower() in self.wifi_network_db(): 68 | # validation succeeded 69 | return {EntitySlotEnum.WIFI_NETWORK: value} 70 | else: 71 | dispatcher.utter_message(template=UtteranceEnum.NO_WIFI_NETWORK) 72 | dispatcher.utter_message( 73 | text=f"Redes WiFi disponibles: {self.wifi_network_db()}" 74 | ) 75 | # validation failed, set this slot to None, meaning the 76 | # user will be asked for the slot again 77 | return {EntitySlotEnum.WIFI_NETWORK: None} 78 | 79 | def validate_email( 80 | self, 81 | value: Text, 82 | dispatcher: CollectingDispatcher, 83 | tracker: Tracker, 84 | domain: Dict[Text, Any], 85 | ) -> Dict[Text, Any]: 86 | """Validate email has a valid value.""" 87 | 88 | if re.search(r"@ucuenca\.edu\.ec$", value.lower()) is not None: 89 | # validation succeeded 90 | return {EntitySlotEnum.EMAIL: value.lower()} 91 | else: 92 | dispatcher.utter_message(template=UtteranceEnum.EMAIL_NO_MATCH) 93 | # validation failed, set this slot to None, meaning the 94 | # user will get info to connect to the guest network 95 | return { 96 | EntitySlotEnum.WIFI_NETWORK: "guest", 97 | EntitySlotEnum.EMAIL: value.lower(), 98 | } 99 | 100 | def submit( 101 | self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], 102 | ) -> List[Dict]: 103 | """Define what the form has to do 104 | after all required slots are filled""" 105 | 106 | wifi_network = tracker.get_slot(EntitySlotEnum.WIFI_NETWORK).lower() 107 | wifi_networks = self.wifi_network_db() 108 | instructions = { 109 | wifi_networks[0]: UtteranceEnum.EDUROAM_INSTRUCTIONS, 110 | wifi_networks[1]: UtteranceEnum.UCWIFI_INSTRUCTIONS, 111 | wifi_networks[2]: UtteranceEnum.GUEST_WIFI_INSTRUCTIONS, 112 | } 113 | 114 | dispatcher.utter_message(template=instructions[wifi_network]) 115 | 116 | ask_if_success( 117 | dispatcher, 118 | incident_title="Problema de conexion a la red WIFI", 119 | itilcategory_id=52, 120 | ) 121 | 122 | return [SlotSet(EntitySlotEnum.WIFI_NETWORK, None)] 123 | 124 | 125 | class CreateUserFaqForm(FormAction): 126 | def name(self) -> Text: 127 | return "create_user_faq_form" 128 | 129 | @staticmethod 130 | def required_slots(tracker: Tracker) -> List[Text]: 131 | """A list of required slots that the form has to fill""" 132 | 133 | if tracker.get_slot(EntitySlotEnum.HAS_EMAIL): 134 | return [EntitySlotEnum.HAS_EMAIL] 135 | else: 136 | return [EntitySlotEnum.HAS_EMAIL, EntitySlotEnum.COURSE_TYPE] 137 | 138 | def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]: 139 | """A dictionary to map required slots to 140 | - an extracted entity 141 | - intent: value pairs 142 | - a whole message 143 | or a list of them, where a first match will be picked""" 144 | 145 | return { 146 | EntitySlotEnum.HAS_EMAIL: [ 147 | self.from_intent(intent="confirm", value=True), 148 | self.from_intent(intent="deny", value=False), 149 | ], 150 | EntitySlotEnum.COURSE_TYPE: [ 151 | self.from_entity(entity=EntitySlotEnum.COURSE_TYPE), 152 | ], 153 | } 154 | 155 | @staticmethod 156 | def course_type_db() -> List[Text]: 157 | """Database of supported student types""" 158 | 159 | return ["carrera", "curso"] 160 | 161 | def validate_course_type( 162 | self, 163 | value: Text, 164 | dispatcher: CollectingDispatcher, 165 | tracker: Tracker, 166 | domain: Dict[Text, Any], 167 | ) -> Dict[Text, Any]: 168 | """Validate COURSE_TYPE has a valid value.""" 169 | 170 | # logger.info(f"COURSE TYPE ===> {value.lower()}:{value.lower() in self.course_type_db()}") 171 | if value.lower() in self.course_type_db(): 172 | # validation succeeded 173 | return {EntitySlotEnum.COURSE_TYPE: value.lower()} 174 | else: 175 | dispatcher.utter_message(template=UtteranceEnum.INVALID) 176 | # validation failed, set this slot to None, meaning the 177 | # user will be asked for the slot again 178 | return {EntitySlotEnum.COURSE_TYPE: None} 179 | 180 | def submit( 181 | self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], 182 | ) -> List[Dict]: 183 | """Define what the form has to do 184 | after all required slots are filled""" 185 | 186 | has_email = tracker.get_slot(EntitySlotEnum.HAS_EMAIL) 187 | if has_email: 188 | dispatcher.utter_message(template=UtteranceEnum.RECOVER_PASSWORD) 189 | else: 190 | course_type = tracker.get_slot(EntitySlotEnum.COURSE_TYPE) 191 | course_types = self.course_type_db() 192 | instructions = { 193 | course_types[0]: "https://admision.ucuenca.edu.ec/", 194 | course_types[1]: "https://registro.ucuenca.edu.ec/", 195 | } 196 | 197 | dispatcher.utter_message( 198 | "Para poder registrar una cuenta por favor visita el siguiente enlace: " 199 | + instructions[course_type] 200 | ) 201 | 202 | ask_if_success( 203 | dispatcher, 204 | incident_title="Problema para crear un usuario", 205 | itilcategory_id=56, 206 | ) 207 | 208 | return [ 209 | SlotSet(EntitySlotEnum.COURSE_TYPE, None), 210 | SlotSet(EntitySlotEnum.HAS_EMAIL, None), 211 | ] 212 | -------------------------------------------------------------------------------- /actions/actions_internal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import logging 4 | from typing import Dict, Text, Any, List, Union 5 | from rasa_sdk import Tracker 6 | from rasa_sdk.executor import CollectingDispatcher 7 | from rasa_sdk.forms import FormAction 8 | from rasa_sdk.events import AllSlotsReset, SlotSet 9 | 10 | import re 11 | 12 | from actions.constants import EntitySlotEnum, IntentEnum, UtteranceEnum 13 | from actions.glpi import GLPIService, GlpiException, load_glpi_config, Ticket 14 | from actions.parsing import ( 15 | get_entity_details, 16 | parse_duckling_time_as_interval, 17 | remove_accents, 18 | ) 19 | 20 | logger = logging.getLogger(__name__) 21 | 22 | glpi_api_uri, glpi_app_token, glpi_auth_token, local_mode = load_glpi_config() 23 | glpi = ( 24 | GLPIService.get_instance(glpi_api_uri, glpi_app_token, glpi_auth_token) 25 | if not local_mode 26 | else None 27 | ) 28 | 29 | 30 | class BiometricsReportForm(FormAction): 31 | def name(self) -> Text: 32 | return "biometrics_report_form" 33 | 34 | @staticmethod 35 | def required_slots(tracker: Tracker) -> List[Text]: 36 | """A list of required slots that the form has to fill""" 37 | 38 | return [ 39 | EntitySlotEnum.PERSONAL_ID, 40 | EntitySlotEnum.BIOMETRICS_ID, 41 | EntitySlotEnum.TIME_PERIOD, 42 | ] 43 | 44 | def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]: 45 | """A dictionary to map required slots to 46 | - an extracted entity 47 | - intent: value pairs 48 | - a whole message 49 | or a list of them, where a first match will be picked""" 50 | 51 | return { 52 | EntitySlotEnum.PERSONAL_ID: [ 53 | self.from_entity(entity=EntitySlotEnum.PERSONAL_ID), 54 | self.from_text(not_intent=IntentEnum.OUT_OF_SCOPE), 55 | ], 56 | EntitySlotEnum.BIOMETRICS_ID: [ 57 | self.from_entity(entity=EntitySlotEnum.BIOMETRICS_ID), 58 | self.from_text(not_intent=IntentEnum.OUT_OF_SCOPE), 59 | ], 60 | EntitySlotEnum.TIME_PERIOD: [self.from_entity(entity=EntitySlotEnum.TIME)], 61 | } 62 | 63 | @staticmethod 64 | def query_employee_db() -> List[Text]: 65 | """Database of supported wifi networks""" 66 | 67 | # TODO: Validate user is employee 68 | return ["1111111111"] 69 | 70 | def validate_personal_id( 71 | self, 72 | value: Text, 73 | dispatcher: CollectingDispatcher, 74 | tracker: Tracker, 75 | domain: Dict[Text, Any], 76 | ) -> Dict[Text, Any]: 77 | """Validate personal_id has a valid value.""" 78 | 79 | # TODO: Validate it is registered as employee 80 | if re.match(r"[0-9]+$", value) is not None and value in self.query_employee_db(): 81 | # validation succeeded 82 | return {EntitySlotEnum.PERSONAL_ID: value} 83 | else: 84 | dispatcher.utter_message(template=UtteranceEnum.NO_PERSONAL_ID) 85 | # validation failed, set this slot to None, meaning the 86 | # user will get info to connect to the guest network 87 | return {EntitySlotEnum.PERSONAL_ID: None} 88 | 89 | def validate_biometrics_id( 90 | self, 91 | value: Text, 92 | dispatcher: CollectingDispatcher, 93 | tracker: Tracker, 94 | domain: Dict[Text, Any], 95 | ) -> Dict[Text, Any]: 96 | """Validate personal_id has a valid value.""" 97 | 98 | # TODO: Validate it is registered 99 | if re.match(r"[0-9]{10}$", value) is not None: 100 | # validation succeeded 101 | return {EntitySlotEnum.BIOMETRICS_ID: value} 102 | else: 103 | dispatcher.utter_message(template=UtteranceEnum.INVALID) 104 | # validation failed, set this slot to None, meaning the 105 | # user will get info to connect to the guest network 106 | return {EntitySlotEnum.BIOMETRICS_ID: None} 107 | 108 | def validate_time_period( 109 | self, 110 | value: Text, 111 | dispatcher: CollectingDispatcher, 112 | tracker: Tracker, 113 | domain: Dict[Text, Any], 114 | ) -> Dict[Text, Any]: 115 | """Validate time value.""" 116 | time_entity = get_entity_details(tracker, EntitySlotEnum.TIME) 117 | parsed_interval = parse_duckling_time_as_interval(time_entity) 118 | if not parsed_interval: 119 | dispatcher.utter_message(template=UtteranceEnum.INVALID) 120 | return {EntitySlotEnum.TIME_PERIOD: None} 121 | # Returns { EntitySlotEnum.START_TIME, EntitySlotEnum.END_TIME, EntitySlotEnum.GRAIN } 122 | return parsed_interval 123 | 124 | def submit( 125 | self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any], 126 | ) -> List[Dict]: 127 | """Define what the form has to do 128 | after all required slots are filled""" 129 | 130 | personal_id = tracker.get_slot(EntitySlotEnum.PERSONAL_ID) 131 | biometrics_id = tracker.get_slot(EntitySlotEnum.BIOMETRICS_ID) 132 | 133 | start_time = tracker.get_slot(EntitySlotEnum.START_TIME) 134 | end_time = tracker.get_slot(EntitySlotEnum.END_TIME) 135 | grain = tracker.get_slot(EntitySlotEnum.GRAIN) 136 | 137 | events = [ 138 | SlotSet(EntitySlotEnum.ITILCATEGORY_ID, None), 139 | SlotSet(EntitySlotEnum.PERSONAL_ID, None), 140 | SlotSet(EntitySlotEnum.BIOMETRICS_ID, None), 141 | SlotSet(EntitySlotEnum.TIME, None), 142 | SlotSet(EntitySlotEnum.TIME_PERIOD, None), 143 | SlotSet(EntitySlotEnum.START_TIME, None), 144 | SlotSet(EntitySlotEnum.END_TIME, None), 145 | SlotSet(EntitySlotEnum.GRAIN, None), 146 | ] 147 | 148 | description = f"Datos de Validacion: \n ID: {personal_id}\n BIOMETRICS_ID: {biometrics_id}\n" 149 | description += f"Periodo: {start_time} / {end_time} ({grain})" 150 | 151 | ticket: Ticket = Ticket( 152 | { 153 | "username": "normal", # TODO: set the actual logged in user 154 | "title": "Solicitud Informe Sistema Biometrico", 155 | "description": remove_accents(description), 156 | # 'priority': glpi_priority 157 | "itilcategories_id": 60, # Reporte de datos 158 | } 159 | ) 160 | 161 | if local_mode: 162 | dispatcher.utter_message( 163 | f"Esta acción crearía un ticket con la siguiente información: {ticket}" 164 | ) 165 | ticket_id = "DUMMY" 166 | events.append(SlotSet(EntitySlotEnum.TICKET_NO, ticket_id)) 167 | else: 168 | try: 169 | response = glpi.create_ticket(ticket, ticket_type=2) # Solicitud 170 | ticket_id = response["id"] 171 | # This is not actually required as its value is sent directly to the utter_message 172 | events.append(SlotSet(EntitySlotEnum.TICKET_NO, ticket_id)) 173 | except GlpiException as e: 174 | logger.error("Error when trying to create a ticket", e) 175 | logger.error(f"Ticket: {ticket}") 176 | dispatcher.utter_message(template=UtteranceEnum.PROCESS_FAILED) 177 | return events 178 | dispatcher.utter_message(template=UtteranceEnum.TICKET_NO, ticket_no=ticket_id) 179 | dispatcher.utter_message(template=UtteranceEnum.CONFIRM_REQUEST) 180 | 181 | return [AllSlotsReset(), SlotSet(EntitySlotEnum.TICKET_NO, ticket_id)] 182 | -------------------------------------------------------------------------------- /actions/actions_mock.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import logging 4 | import requests 5 | import json 6 | from rasa_sdk import Action 7 | 8 | # from rasa_sdk.events import FollowupAction 9 | from rasa_sdk.events import SlotSet 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | 14 | class ActionJoke(Action): 15 | """An action to test the possibility to communicate with REST APIs""" 16 | 17 | def name(self): 18 | # define the name of the action which can then be included in training stories 19 | return "action_joke" 20 | 21 | def run(self, dispatcher, tracker, domain): 22 | # what your action should do 23 | request = json.loads( 24 | requests.get("https://api.chucknorris.io/jokes/random").text 25 | ) # make an api call 26 | joke = request["value"] # extract a joke from returned json response 27 | dispatcher.utter_message(joke) # send the message back to the user 28 | return [] 29 | 30 | 31 | class ValidateAuth(Action): 32 | """An action that validates if the user is authenticated""" 33 | 34 | def name(self): 35 | # define the name of the action which can then be included in training stories 36 | return "action_validate_auth" 37 | 38 | def run(self, dispatcher, tracker, domain): 39 | # what your action should do 40 | auth_token = tracker.get_slot("auth_token") 41 | events = [] 42 | if not auth_token: 43 | # json_payload = {self._LOGGED_IN: logged_in} 44 | # dispatcher.utter_message(\ 45 | # "Para continuar es necesario que Inicie Sesión con su cuenta institucional", json_message=json_payload) 46 | dispatcher.utter_message( 47 | "Para continuar es necesario que Inicie Sesión con su cuenta institucional" 48 | ) 49 | else: # TODO: validate auth with provider 50 | # Example: 51 | # https://stackoverflow.com/questions/359472/how-can-i-verify-a-google-authentication-api-access-token 52 | 53 | # events.append(FollowupAction("utter_intro")) 54 | # TODO get username & email from token info 55 | username = "normal" 56 | email = "normal@ucuenca.edu.ec" 57 | events.append(SlotSet("username", username)) 58 | events.append(SlotSet("email", email)) 59 | 60 | return events 61 | -------------------------------------------------------------------------------- /actions/constants.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | class EntitySlotEnum(object): 5 | CONFIRM = "confirm" 6 | EMAIL = "email" 7 | PRIORITY = "priority" 8 | TIME = "time" 9 | INCIDENT_TITLE = "incident_title" 10 | INCIDENT_DESCRIPTION = "incident_description" 11 | ITILCATEGORY_ID = "itilcategory_id" 12 | SOFTWARE = "software" 13 | DEPARTMENT = "department" 14 | VM_ENVIRONMENT = "vm_environment" 15 | VM_RAM = "vm_ram" 16 | VM_CPU_CORES = "vm_cpu_cores" 17 | VM_DISK_SPACE = "vm_disk_space" 18 | VM_SCALABILITY = "vm_scalability" 19 | OBSERVATIONS = "observations" 20 | WIFI_NETWORK = "wifi_network" 21 | HAS_EMAIL = "has_email" 22 | COURSE_TYPE = "course_type" 23 | PERSONAL_ID = "personal_id" 24 | BIOMETRICS_ID = "biometrics_id" 25 | TIME_PERIOD = "time_period" # dummy to get from time entity 26 | START_TIME = "start_time" # Obtained from Duckling 27 | END_TIME = "end_time" # Obtained from Duckling 28 | GRAIN = "grain" # Obtained from Duckling 29 | TICKET_NO = "ticket_no" 30 | 31 | 32 | class IntentEnum(object): 33 | INFORM = "inform" 34 | OUT_OF_SCOPE = "out_of_scope" 35 | SHOW_MENU = "show_menu" 36 | CONFIRM = "confirm" 37 | DENY = "deny" 38 | OPEN_INCIDENT = "open_incident" 39 | GET_INCIDENT_STATUS = "get_incident_status" 40 | CONNECT_WIFI = "connect_wifi" 41 | CREATE_USER = "create_user" 42 | REQUEST_BIOMETRICS_REPORT = "request_biometrics_report" 43 | REQUEST_VM = "request_vm" 44 | PASSWORD_RESET = "password_reset" 45 | PROBLEM_EMAIL = "problem_email" 46 | 47 | 48 | class UtteranceEnum(object): 49 | SUGGEST = "utter_suggest" 50 | INVALID = "utter_invalid" 51 | NO_WIFI_NETWORK = "utter_no_wifi_network" 52 | EMAIL_NO_MATCH = "utter_email_no_match" 53 | EDUROAM_INSTRUCTIONS = "utter_eduroam_instructions" 54 | UCWIFI_INSTRUCTIONS = "utter_ucwifi_instructions" 55 | GUEST_WIFI_INSTRUCTIONS = "utter_guest_wifi_instructions" 56 | RECOVER_PASSWORD = "utter_recover_password" 57 | NO_PERSONAL_ID = "utter_no_personal_id" 58 | COMPUTE_FORM_VALUES = "utter_compute_form_values" 59 | PRIORITY_NO_MATCH = "utter_priority_no_match" 60 | TICKET_NO = "utter_ticket_no" 61 | TICKET_STATUS = "utter_ticket_status" 62 | CONFIRM_REQUEST = "utter_confirm_request" 63 | PROCESS_FAILED = "utter_process_failed" 64 | PROCESS_CANCELLED = "utter_process_cancelled" 65 | CONFIRM_ASK_SUCCESS = "utter_confirm_ask_success" # With default buttons 66 | CONFIRM_SUCCESS = "utter_confirm_success" # Template to use custom buttons 67 | -------------------------------------------------------------------------------- /actions/parsing.py: -------------------------------------------------------------------------------- 1 | from dateutil import relativedelta, parser 2 | from typing import Dict, Text, Any, Optional 3 | from rasa_sdk import Tracker 4 | import unicodedata 5 | 6 | from actions.constants import EntitySlotEnum 7 | 8 | 9 | def close_interval_duckling_time(time_info: Dict[Text, Any]) -> Optional[Dict[Text, Any]]: 10 | """ 11 | 12 | :param time_info: interval metadata from duckling 13 | :return: Dict with fields { EntitySlotEnum.START_TIME, EntitySlotEnum.END_TIME, EntitySlotEnum.GRAIN } 14 | """ 15 | grain = time_info.get("to", time_info.get("from", {})).get("grain") 16 | start = time_info.get("to", {}).get("value") 17 | end = time_info.get("from", {}).get("value") 18 | if start or end: 19 | if start and end: 20 | parsed_start = parser.isoparse(start) 21 | parsed_end = parser.isoparse(end) 22 | else: 23 | delta_args = {f"{grain}s": 1} 24 | delta = relativedelta.relativedelta(**delta_args) 25 | if start: 26 | parsed_start = parser.isoparse(start) 27 | parsed_end = parsed_start + delta 28 | elif end: 29 | parsed_end = parser.isoparse(end) 30 | parsed_start = parsed_end - delta 31 | return { 32 | EntitySlotEnum.START_TIME: format_time_by_grain(parsed_start, grain), 33 | EntitySlotEnum.END_TIME: format_time_by_grain(parsed_end, grain), 34 | EntitySlotEnum.GRAIN: grain, 35 | } 36 | 37 | 38 | def make_interval_from_value_duckling_time(time_info: Dict[Text, Any]) -> Dict[Text, Any]: 39 | """ 40 | 41 | :param time_info: value metadata from duckling 42 | :return: Dict with fields { EntitySlotEnum.START_TIME, EntitySlotEnum.END_TIME, EntitySlotEnum.GRAIN } 43 | """ 44 | grain = time_info.get("grain") 45 | start = time_info.get("value") 46 | parsed_start = parser.isoparse(start) 47 | delta_args = {f"{grain}s": 1} 48 | delta = relativedelta.relativedelta(**delta_args) 49 | parsed_end = parsed_start + delta 50 | return { 51 | EntitySlotEnum.START_TIME: format_time_by_grain(parsed_start, grain), 52 | EntitySlotEnum.END_TIME: format_time_by_grain(parsed_end, grain), 53 | EntitySlotEnum.GRAIN: grain, 54 | } 55 | 56 | 57 | def parse_duckling_time_as_interval( 58 | time_entity: Dict[Text, Any] 59 | ) -> Optional[Dict[Text, Any]]: 60 | """ 61 | 62 | :param time_entity: metadata returned from duckling 63 | :return: Dict with fields { EntitySlotEnum.START_TIME, EntitySlotEnum.END_TIME, EntitySlotEnum.GRAIN } 64 | """ 65 | time_info = time_entity.get("additional_info", {}) 66 | if time_info.get("type") == "interval": 67 | return close_interval_duckling_time(time_info) 68 | elif time_info.get("type") == "value": 69 | return make_interval_from_value_duckling_time(time_info) 70 | 71 | 72 | def remove_accents(text: Text) -> Text: 73 | """ 74 | Remove accents from unicode text 75 | :param text: original text 76 | :return: normalized text 77 | """ 78 | nkfd_form = unicodedata.normalize("NFKD", text) 79 | return "".join([c for c in nkfd_form if not unicodedata.combining(c)]) 80 | 81 | 82 | # TODO: To be reviewed 83 | def format_time_by_grain(time, grain=None): 84 | grain_format = { 85 | "second": "%I:%M:%S%p, %A %b %d, %Y", 86 | "day": "%A %b %d, %Y", 87 | "week": "%A %b %d, %Y", 88 | "month": "%b %Y", 89 | "year": "%Y", 90 | } 91 | timeformat = grain_format.get(grain, "%I:%M%p, %A %b %d, %Y") 92 | return time.strftime(timeformat) 93 | 94 | 95 | def parse_duckling_time(timeentity: Dict[Text, Any]) -> Optional[Dict[Text, Any]]: 96 | timeinfo = timeentity.get("additional_info", {}) 97 | if timeinfo.get("type") == "value": 98 | value = timeinfo.get("value") 99 | grain = timeinfo.get("grain") 100 | parsedtime = { 101 | "time": format_time_by_grain(parser.isoparse(value), grain), 102 | "grain": grain, 103 | } 104 | return parsedtime 105 | 106 | 107 | def get_entity_details(tracker: Tracker, entity_type: Text) -> Optional[Dict[Text, Any]]: 108 | all_entities = tracker.latest_message.get("entities", []) 109 | entities = [e for e in all_entities if e.get("entity") == entity_type] 110 | if entities: 111 | return entities[0] 112 | 113 | 114 | def parse_duckling_currency(entity: Dict[Text, Any]) -> Optional[Dict[Text, Any]]: 115 | if entity.get("entity") == "amount-of-money": 116 | amount = entity.get("additional_info", {}).get("value") 117 | currency = entity.get("additional_info", {}).get("unit") 118 | return {"amount_of_money": f"{amount:.2f}", "currency": currency} 119 | elif entity.get("entity") == "number": 120 | amount = entity.get("value") 121 | return {"amount_of_money": f"{amount:.2f}", "currency": "$"} 122 | -------------------------------------------------------------------------------- /alt_requirements/conda-requirements.txt: -------------------------------------------------------------------------------- 1 | scipy==1.2.1 2 | scikit-learn==0.20.2 3 | -------------------------------------------------------------------------------- /alt_requirements/requirements_bare.txt: -------------------------------------------------------------------------------- 1 | # deprecated, will be removed. please use the `requirements.txt` 2 | # in the mainfolder instead 3 | -r ../requirements.txt 4 | -------------------------------------------------------------------------------- /alt_requirements/requirements_dev.txt: -------------------------------------------------------------------------------- 1 | # deprecated, will be removed. please use the `requirements-dev.txt` 2 | # in the mainfolder instead 3 | -r ../requirements-dev.txt 4 | -------------------------------------------------------------------------------- /alt_requirements/requirements_docs.txt: -------------------------------------------------------------------------------- 1 | # deprecated, will be removed. please use the `requirements-docs.txt` 2 | # in the mainfolder instead 3 | -r ../requirements-docs.txt 4 | -------------------------------------------------------------------------------- /alt_requirements/requirements_full.txt: -------------------------------------------------------------------------------- 1 | # Minimum Install Requirements 2 | -r ../requirements.txt 3 | 4 | # Spacy Requirements 5 | -r requirements_pretrained_embeddings_spacy.txt 6 | 7 | # MITIE Requirements 8 | # -r requirements_pretrained_embeddings_mitie.txt 9 | 10 | jieba==0.39 11 | -------------------------------------------------------------------------------- /alt_requirements/requirements_pretrained_embeddings_mitie.txt: -------------------------------------------------------------------------------- 1 | # Minimum Install Requirements 2 | -r ../requirements.txt 3 | 4 | git+https://github.com/tmbo/MITIE.git#egg=mitie 5 | -------------------------------------------------------------------------------- /alt_requirements/requirements_pretrained_embeddings_spacy.txt: -------------------------------------------------------------------------------- 1 | # Minimum Install Requirements 2 | -r ../requirements.txt 3 | 4 | spacy==2.1.4 5 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /client/JOOMLA.md: -------------------------------------------------------------------------------- 1 | # How to integrate Chatbot web client on a Joomla website 2 | 3 | 1. Clone the following repository and execute the following: 4 | 5 | ```bash 6 | $ cd rasa-webchat 7 | $ npm run install 8 | $ npm run build 9 | ``` 10 | 11 | 2. Copy the file `lib/index.js` and paste it at the following location on your Joomla server: 12 | 13 | ```bash 14 | scp lib/index.js root@:/var/www/html/ucuenca.edu.ec/public_html/chatbot.js 15 | ``` 16 | 17 | 3. Open your Joomla Admin and Go to your `Template > Custom Code` section and apply the following custom code: 18 | 19 | * Before \<\/body\> 20 | 21 | ```js 22 |
23 | 24 | 25 | 68 | ``` 69 | 70 | * Custom CSS 71 | 72 | ```css 73 | img.rw-open-launcher { 74 | margin: 0 auto 5px; 75 | } 76 | ``` -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | 70 | ## Inside that directory, you can run several commands: 71 | 72 | npm start 73 | Starts the development server. 74 | 75 | npm run build 76 | Bundles the app into static files for production. 77 | 78 | npm test 79 | Starts the test runner. 80 | 81 | npm run eject 82 | Removes this tool and copies build dependencies, configuration files 83 | and scripts into the app directory. If you do this, you can’t go back! 84 | 85 | We suggest that you begin by typing: 86 | 87 | cd my-app-visualchat 88 | npm start 89 | 90 | Happy hacking! 91 | 92 | ## Install webchat 93 | 94 | npm install mrbot-ai/rasa-webchat 95 | 96 | python -m rasa_core_sdk.endpoint --actions actions 97 | 98 | python -m rasa_core.run -d models/dialogue -u models/current/nlu --port 5002 --credentials credentials.yml 99 | 100 | 101 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "rasa-webchat": "git+https://github.com/mrbot-ai/rasa-webchat.git", 7 | "react": "^16.8.3", 8 | "react-dom": "^16.8.3", 9 | "react-scripts": "2.1.5" 10 | }, 11 | "scripts": { 12 | "start": "BROWSER=none react-scripts start", 13 | "build": "react-scripts build", 14 | "test": "react-scripts test", 15 | "eject": "react-scripts eject" 16 | }, 17 | "eslintConfig": { 18 | "extends": "react-app" 19 | }, 20 | "browserslist": [ 21 | ">0.2%", 22 | "not dead", 23 | "not ie <= 11", 24 | "not op_mini all" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /client/public/chatlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santteegt/glpi_chatbot/5685d12216fa4c0f790ca9b85c7320a66d5ba8be/client/public/chatlogo.png -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santteegt/glpi_chatbot/5685d12216fa4c0f790ca9b85c7320a66d5ba8be/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 16 | 25 | React App 26 | 27 | 28 | 29 |
30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /client/public/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santteegt/glpi_chatbot/5685d12216fa4c0f790ca9b85c7320a66d5ba8be/client/public/profile.png -------------------------------------------------------------------------------- /client/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | @keyframes App-logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /client/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | // import { Widget } from 'react-chat-widget'; 4 | import { Widget } from 'rasa-webchat'; 5 | 6 | // import 'react-chat-widget/lib/styles.css'; 7 | 8 | import logo from './logo.svg'; 9 | import './App.css'; 10 | 11 | class App extends Component { 12 | 13 | render() { 14 | return ( 15 |
16 | (
Custom React component
) } 41 | /> 42 |
43 | ); 44 | } 45 | } 46 | 47 | export default App; 48 | -------------------------------------------------------------------------------- /client/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: http://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | 14 | // io.on('user_uttered') 15 | // def handle_message(message): 16 | 17 | -------------------------------------------------------------------------------- /client/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /client/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read http://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit http://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /config.yml: -------------------------------------------------------------------------------- 1 | # Configuration for Rasa NLU. 2 | # https://rasa.com/docs/rasa/nlu/choosing-a-pipeline/ 3 | 4 | # Configuration for Rasa Core. 5 | # https://rasa.com/docs/rasa/core/policies/ 6 | # - max_history: This controls how much dialogue history the model looks at to decide which action to take next. 7 | # - nlu-threshold: the fallback action or the utter_default will be executed if the intent recognition has a confidence 8 | # below a threshold (0-1). This value can be set based on NLU model evaluation results. 9 | # Enabled Policies 10 | # - KerasPolicy: 11 | # - MemoizationPolicy: 12 | # - FormPolicy: 13 | # - FallbackPolicy: Disabled 14 | # - TwoStageFallbackPolicy: By splitting the fallback in the two stages affirmation and rephrasing the policy allows 15 | # more natural conversation flows 16 | 17 | language: es 18 | 19 | #pipeline: 20 | #- name: SpacyNLP 21 | #- name: SpacyTokenizer 22 | #- name: SpacyFeaturizer 23 | #- name: RegexFeaturizer 24 | #- name: LexicalSyntacticFeaturizer 25 | #- name: CountVectorsFeaturizer 26 | #- name: CountVectorsFeaturizer 27 | # analyzer: "char_wb" 28 | # min_ngram: 1 29 | # max_ngram: 4 30 | #- name: DucklingHTTPExtractor 31 | # url: http://localhost:8000 32 | # dimensions: 33 | # - email 34 | ##- name: "DucklingHTTPExtractor" 35 | ## url: http://localhost:8000 36 | ## dimensions: ["time", "number", "email", "distance", "amount-of-money", "duration", "url", "phone-number"] 37 | #- name: EntitySynonymMapper 38 | #- name: SpacyEntityExtractor 39 | # # https://spacy.io/api/annotation#section-named-entities 40 | # dimensions: ["PER", "LOC", "ORG"] 41 | ##- name: CRFEntityExtractor 42 | ## # BILOU_flag determines whether to use BILOU tagging or not. 43 | ## BILOU_flag: True 44 | ## features: [ 45 | ## ["low", "title", "upper"], 46 | ## [ 47 | ## "bias", 48 | ## "low", 49 | ## "prefix5", 50 | ## "prefix2", 51 | ## "suffix5", 52 | ## "suffix3", 53 | ## "suffix2", 54 | ## "upper", 55 | ## "title", 56 | ## "digit", 57 | ## "pattern", 58 | ## ], 59 | ## ["low", "title", "upper"], 60 | ## ] 61 | ### # Last features. Why? 62 | ### BILOU_flag: false 63 | ### features: [ 64 | ### ["low", "title", "upper", "pos", "pos2"], 65 | ### [ 66 | ### "bias", 67 | ### "low", 68 | ### "prefix5", 69 | ### "prefix2", 70 | ### "suffix5", 71 | ### "suffix3", 72 | ### "suffix2", 73 | ### "upper", 74 | ### "title", 75 | ### "digit", 76 | ### "pattern", 77 | ### ], 78 | ### [ "low", "title", "upper", "pos", "pos2" ], 79 | ### ] 80 | ## # The maximum number of iterations for optimization algorithms. 81 | ## max_iterations: 50 82 | ## # weight of the L1 regularization 83 | ## L1_c: 0.1 84 | ## # weight of the L2 regularization 85 | ## L2_c: 0.1 86 | ##- name: SklearnIntentClassifier 87 | #- name: DIETClassifier 88 | # epochs: 150 89 | # random_seed: 1 90 | #policies: 91 | #- name: TEDPolicy 92 | # max_history: 5 93 | # epochs: 100 94 | #- name: MappingPolicy 95 | #- name: MemoizationPolicy 96 | # max_history: 5 97 | #- name: FallbackPolicy 98 | # nlu_threshold: 0.29 99 | # ambiguity_threshold: 0.1 100 | # core_threshold: 0.29 101 | # fallback_action_name: utter_default 102 | ##- name: TwoStageFallbackPolicy 103 | ## nlu_threshold: 0.29 104 | ## ambiguity_threshold: 0.1 105 | ## core_threshold: 0.29 106 | ## fallback_core_action_name: utter_default 107 | ## fallback_nlu_action_name: action_default_ask_affirmation 108 | ## deny_suggestion_intent_name: solicitar_opciones 109 | #- name: FormPolicy 110 | 111 | pipeline: 112 | - name: SpacyNLP 113 | - name: SpacyTokenizer 114 | - name: SpacyFeaturizer 115 | - name: RegexFeaturizer 116 | - name: LexicalSyntacticFeaturizer 117 | - name: CountVectorsFeaturizer 118 | - name: CountVectorsFeaturizer 119 | analyzer: "char_wb" 120 | min_ngram: 1 121 | max_ngram: 4 122 | - name: DIETClassifier 123 | epochs: 150 124 | random_seed: 1 125 | - name: DucklingHTTPExtractor 126 | url: http://localhost:8000 127 | dimensions: 128 | - email 129 | - time 130 | - number 131 | - duration 132 | locale: "es_CO" 133 | timezone: "America/Guayaquil" 134 | - name: EntitySynonymMapper 135 | policies: 136 | - name: TEDPolicy 137 | max_history: 4 138 | epochs: 100 139 | - name: MappingPolicy 140 | - name: AugmentedMemoizationPolicy 141 | max_history: 4 142 | - name: FallbackPolicy 143 | nlu_threshold: 0.7 144 | - name: FormPolicy -------------------------------------------------------------------------------- /credentials.yml: -------------------------------------------------------------------------------- 1 | # This file contains the credentials for the voice & chat platforms 2 | # which your bot is using. 3 | # https://rasa.com/docs/rasa/user-guide/messaging-and-voice-channels/ 4 | 5 | rest: 6 | # # you don't need to provide anything here - this channel doesn't 7 | # # require any credentials 8 | 9 | 10 | #facebook: 11 | # verify: "" 12 | # secret: "" 13 | # page-access-token: "" 14 | 15 | #slack: 16 | # slack_token: "" 17 | # slack_channel: "" 18 | 19 | socketio: 20 | user_message_evt: user_uttered 21 | bot_message_evt: bot_uttered 22 | session_persistence: true 23 | 24 | #mattermost: 25 | # url: "https:///api/v4" 26 | # team: "" 27 | # user: "" 28 | # pw: "" 29 | # webhook_url: "" 30 | 31 | #telegram 32 | # access_token: "" 33 | # verify: ">" 34 | # webhook_url: "" 35 | 36 | rasa: 37 | url: "http://localhost:5002/api" -------------------------------------------------------------------------------- /data/departments.txt: -------------------------------------------------------------------------------- 1 | DTIC 2 | DIUC 3 | Recursos Humanos 4 | Idiomas -------------------------------------------------------------------------------- /data/faculties.txt: -------------------------------------------------------------------------------- 1 | Ingeniería 2 | Psicología 3 | Derecho 4 | Química 5 | Arquitectura 6 | Medicina 7 | Hospitalidad 8 | Artes 9 | Agropecuaria 10 | Filosofía 11 | -------------------------------------------------------------------------------- /data/nlu.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## intent:greet 5 | - hey 6 | - hola 7 | - hola que tal 8 | - buenos dias 9 | - buenas tardes 10 | - buenas noches 11 | - Que hay 12 | - holas 13 | - saludos 14 | - hola hola 15 | - buenas 16 | - hola buenos dias 17 | 18 | ## intent:goodbye 19 | - chao 20 | - adios 21 | - nos vemos 22 | - nos vemos luego 23 | - chau 24 | - pues adios 25 | - hasta luego 26 | - hasta pronto 27 | - salir 28 | - finaliza sesion 29 | - chao chao 30 | - fin 31 | - terminar sesion 32 | 33 | ## intent:thank 34 | - gracias! 35 | - gracias 36 | - muchas gracias 37 | - lo agradezco 38 | - muy bien gracias 39 | - gracias por su ayuda 40 | - agradezco su ayuda 41 | - estoy agradecido 42 | 43 | ## intent:help 44 | - Necesito ayuda 45 | - Con que me puedes ayudar? 46 | - Puedes ayudarme? 47 | - Que puedes hacer? 48 | - Necesito algo de ayuda 49 | - Ayudame 50 | - Me puede ayudar? 51 | - Ayuda 52 | - Requiero su ayuda 53 | - Necesito asistencia 54 | - Ayuda con un problema 55 | 56 | ## intent:show_menu 57 | - opciones 58 | - ver opciones 59 | - menu 60 | - mostrar menu 61 | - ver menu 62 | - mostrar opciones disponibles 63 | 64 | ## intent:bot_challenge 65 | - eres un robot? 66 | - eres humano? 67 | - estoy hablando con un robot? 68 | - estoy hablando con un humano? 69 | - eres un robot verdad? 70 | - acaso eres un robot? 71 | - como te llamas? 72 | - cual es tu nombre? 73 | 74 | ## intent:confirm 75 | - si 76 | - bueno 77 | - esta bien 78 | - acepto 79 | - confirmar 80 | - aceptar 81 | - si si 82 | - bueno bueno 83 | - ok 84 | - si acepto 85 | - si confirmo 86 | - si confirma 87 | - okay 88 | - confirmar 89 | 90 | ## intent:deny 91 | - no 92 | - no continuar 93 | - cancelar 94 | - no es lo que quiero 95 | - cancela 96 | - negativo 97 | - no es lo que deseo 98 | - no gracias 99 | - no 100 | - denegar 101 | - nop 102 | - nada 103 | - no soluciona 104 | 105 | ## intent:open_incident 106 | - Necesito reportar una incidencia 107 | - Me puede ayudar abriendo una incidencia? 108 | - Tengo un problema y necesito reportar una incidencia 109 | - Abrir incidencia 110 | - Reportar incidencia 111 | - Por favor me puede ayudar a reportar una incidencia por favor? 112 | - Quiero reportar una nueva incidencia 113 | - Quiero abrir una incidencia 114 | - Tengo un problema muy extraño 115 | - Quiero reportar un problema 116 | - Tengo un problem y necesito reportar una incidecia 117 | - Tengo un inconveniente y necesito abrir una incidencia 118 | 119 | ## intent:get_incident_status 120 | - cual es el estado actual de mi ticket [0055](ticket_no) 121 | - estado de incidencia 122 | - ya fue solucionado mi inconveniente? 123 | - quiero saber el estado de mi incidencia 124 | - consultar el estado de incidencia 125 | - consulta ticket numero [64524](ticket_no) 126 | - estado de ticket [1234546](ticket_no) 127 | - solucionaron mi ticket? 128 | - cual fue la resolucion de mi incidencia? 129 | - estado de ticket [2356](ticket_no) 130 | - ver estado de ticket con id [653354](ticket_no) 131 | - que paso con la incidencia que reporte? 132 | - atendieron mi ticket? 133 | - cual es el progreso de la incidencia [0055](ticket_no) 134 | - cual es el estado de mi requerimiento 135 | - consultar el estado de mi requerimiento 136 | - quiero saber el estado de mi requerimiento 137 | - como va mi requerimiento 138 | 139 | ## intent:password_reset 140 | - necesito recuperar mi contraseña 141 | - necesito ayuda para recuperar mi contaseña 142 | - no puedo reestablecer mi contraseña 143 | - necesito ayuda con mi contraseña 144 | - tengo problemas para reestablecer mi contraseña 145 | - la contraseña no funciona 146 | - recuperar la contraseña 147 | - reestablecer contraseña 148 | - he olvidado mi contraseña y no se como reestablecerla 149 | - perdi mi contraseña 150 | - no me acuerdo de la contraseña 151 | - no recuerdo mi contraseña 152 | - ayuda no recuerdo mi clave 153 | - olvide mi clave de usuario 154 | - como puedo recuperar mi clave de usuario? 155 | 156 | ## intent:problem_email 157 | - no puedo acceder a mi cuenta de correo electrónico 158 | - tengo problemas con mi correo 159 | - problemas con gmail 160 | - existe un problema con mi correo electrónico 161 | - no puedo iniciar sesion con mi correo electronico 162 | - no puedo abrir mi correo 163 | - no puedo iniciar sesion en gmail 164 | - no puedo iniciar sesion con mi cuenta de correo 165 | - tengo inconvenientes con mi email 166 | - problema con mi email 167 | - problemas con el correo institucional 168 | - el correo institucional no funciona 169 | - no funciona mi correo 170 | 171 | ## intent:connect_wifi 172 | - necesito conectarme a la red [eduroam](wifi_network) 173 | - como puedo conectarme a la red wifi 174 | - necesito conectarme a la red de internet de la universidad 175 | - como puedo conectarme a la red [ucwifi](wifi_network) 176 | - quiero conectarme a la red wifi de del campus 177 | - ayuda con conexion a la red wifi 178 | - cual es la contraseña de la red wifi de la universidad 179 | - como conectarme a la red [guest](wifi_network) 180 | - quiero conectarme al wifi 181 | - no tengo acceso a la red wifi 182 | - como conectarme a la red de [invitado]{"entity":"wifi_network", "value":"guest"} 183 | 184 | ## intent:create_user 185 | - Ayuda a crear un usuario 186 | - Necesito registrarme como usuario 187 | - Necesito una cuenta de usuario 188 | - Como puedo crear mi cuenta de estudiante? 189 | - Quiero crear una cuenta institucional 190 | - Ayuda a registrarme en el sistema 191 | - Necesito un usuario para acceder al sistema 192 | - Como crear una cuenta de usuario de la u 193 | - crear cuenta de usuario 194 | - registar una nueva cuenta de sistema 195 | 196 | ## intent:request_biometrics_report 197 | - necesito un informe de marcación en el biométrico 198 | - reporte de entrada salida del sistema biométrico 199 | - solicitar un informe de marcación de este mes 200 | - necesito revisar mis marcaciones en el sistema biometrico del dia de hoy 201 | - informe de marcacion de la semana anterior 202 | - informe de intentos de marcacion del dia de hoy 203 | - solicito informe de intentos de marcacion del dia de ayer 204 | - ver mis intentos de marcacion de hoy 205 | - reporte diario de marcacion en sistema biometrico 206 | - requiero un informe de intentos de marcacion de esta semana 207 | 208 | ## intent:request_vm 209 | - necesito una maquina virtual 210 | - requiero acceso a una maquina virtual 211 | - requiero una maquina virtual 212 | - necesito un servidor de [desarrollo](vm_environment) 213 | - requiero una VM para [pruebas](vm_environment) 214 | - solicito una instancia para [producción](vm_environment) 215 | - pedir una maquina virtual de [16](vm_ram) GB en RAM y [128](vm_disk_space) GB de disco duro 216 | - solicito maquina virtual [16](vm_ram) GB de ram [8](vm_cpu_cores) nucleos de cpu 217 | - acceso a una maquina de [16](vm_ram) GB de ram [2](vm_cpu_cores) CPUs y [16](vm_disk_space) GB de disco 218 | - solicito un servidor para [desarrollo](vm_environment) 219 | 220 | ## intent:inform 221 | - mi correo es test@ucuenca.edu.ec 222 | - mi correo es abraham.lincoln@ucuenca.edu.ec 223 | - abraham.licoln@ucuenca.edu.ec 224 | - es abraham.licoln@ucuenca.edu.ec 225 | - abraham.lincolon@ucuenca.edu.ec 226 | - hoy 227 | - ayer 228 | - esta semana 229 | - este mes 230 | - el mes pasado 231 | - la semana anterior 232 | - [baja](priority) 233 | - [media](priority) 234 | - [alta](priority) 235 | - es de prioridad [baja](priority) 236 | - prioridad [media](priority) 237 | - prioridad [alta](priority) 238 | - [urgente]{"entity":"priority", "value": "alta"} 239 | - [muy urgente]{"entity":"priority", "value": "alta"} 240 | - [crucial]{"entity":"priority", "value": "alta"} 241 | - [eduroam](wifi_network) 242 | - [ucwifi](wifi_network) 243 | - [guest](wifi_network) 244 | - la red de [invitados]{"entity":"wifi_network", "value":"guest"} 245 | - [carrera](course_type) universitaria 246 | - [curso](course_type) de corta duración 247 | - [carrera](course_type) de [ingenieria](faculty) 248 | - [carrera](course_type) de [arquitectura](faculty) 249 | - [carrera](course_type) universitaria 250 | - [curso](course_type) de idiomas 251 | - [curso](course_type) de inglés 252 | - [curso](course_type) de aleman 253 | - [taller]{"entity":"course_type", "value":"curso"} de informática 254 | - un [seminario]{"entity":"course_type", "value":"curso"} de emprendimiento 255 | - una [charla]{"entity":"course_type", "value":"curso"} técnica 256 | - necesito [512](vm_disk_space) GB de disco duro 257 | - [8](vm_disk_space) GB de capacidad 258 | - escalabilidad [horizontal](vm_scalability) 259 | - necesito escalabilidad [vertical](vm_scalability) 260 | - [32](vm_ram) GB de ram 261 | - necesito un ambiente de [desarrollo](vm_environment) 262 | - [16](vm_disk_space) GB de HD 263 | - solicito [64](vm_ram) GB de ram 264 | - [8](vm_ram) GB de ram 265 | - [32](vm_cpu_cores) nucleos de cpu 266 | - [4](vm_cpu_cores) nucleos 267 | - necesito [8](vm_cpu_cores) procesadores 268 | - necesito un entorno de [pruebas](vm_environment) 269 | - [2](vm_cpu_cores) procesadores 270 | - necesito [16](vm_disk_space) GB de HD 271 | - necesito [3](vm_cpu_cores) procesadores 272 | - [512](vm_disk_space) GB de disco duro 273 | - ambiente de [producción](vm_environment) 274 | - ambiente de [pruebas](vm_environment) 275 | - ambiente de [desarrollo](vm_environment) 276 | - escalable [horizontalmente]{"entity": "vm_scalability", "value": "horizontal"} 277 | - para escalar [verticalmente]{"entity": "vm_scalability", "value": "vertical"} 278 | 279 | ## intent:out_of_scope 280 | - cual es la raiz cuadrada de 5 281 | - como esta el clima 282 | - cual es el significado de la vida 283 | - mi regrigerador no funciona 284 | - la TV no funciona 285 | - quiero pizza 286 | - mi lavadora esta dañada 287 | - que año es 288 | - odernar una pizza 289 | - quiero ordenar una pizza 290 | - como sera el clima el dia de hoy 291 | - que dia es hoy 292 | - que fecha es hoy 293 | - como te llamas 294 | - quiero comida 295 | 296 | ## lookup:software 297 | data/software-dtic.txt 298 | 299 | ## lookup:faculty 300 | data/faculties.txt 301 | 302 | ## lookup:department 303 | data/departments.txt 304 | -------------------------------------------------------------------------------- /data/software-dtic.txt: -------------------------------------------------------------------------------- 1 | Urkund 2 | Sistemas Institucionales 3 | Portafolio 4 | Quipux 5 | eVirtual 6 | OpenERP 7 | GLPI 8 | SIUC 9 | Koha 10 | SCGI 11 | Sistema Academico -------------------------------------------------------------------------------- /data/stories.md: -------------------------------------------------------------------------------- 1 | ## out of scope path 2 | * out_of_scope 3 | - utter_out_of_scope 4 | 5 | ## help 6 | * help 7 | - utter_help 8 | 9 | ## happy path 10 | * greet 11 | - utter_greet 12 | - utter_suggest 13 | 14 | ## login happy path 15 | * login{"auth_token": "a_token_auth"} 16 | - action_validate_auth 17 | - slot{"username": "normal", "email": "normal@ucuenca.edu.ec"} 18 | - utter_logged_in 19 | 20 | ## login failed to validate 21 | * login{"auth_token": "a_token_auth"} 22 | - action_validate_auth 23 | - slot{"username": null, "email": null} 24 | - utter_login_failed 25 | 26 | ## ask for options 27 | * show_menu 28 | - utter_help 29 | - utter_suggest 30 | 31 | ## say goodbye 32 | * goodbye 33 | - utter_goodbye 34 | 35 | ## bot challenge 36 | * bot_challenge 37 | - utter_iamabot 38 | 39 | ## ask more help + confirm 40 | * thank 41 | - utter_welcome 42 | - utter_more_help 43 | * confirm 44 | - utter_suggest 45 | 46 | ## ask more help + deny 47 | * thank 48 | - utter_welcome 49 | - utter_more_help 50 | * deny 51 | - utter_goodbye 52 | - action_restart 53 | 54 | ## incident form 55 | * open_incident OR password_reset OR problem_email 56 | - open_incident_form 57 | - form{"name": "open_incident_form"} 58 | - form{"name": null} 59 | - slot {"ticket_no": "0055"} 60 | 61 | ## incident form interrupted 62 | * open_incident OR password_reset OR problem_email 63 | - open_incident_form 64 | - form{"name":"open_incident_form"} 65 | * help 66 | - utter_help 67 | - open_incident_form 68 | - form{"name":null} 69 | - slot {"ticket_no": "0055"} 70 | 71 | ## incident form interrupted 72 | * open_incident OR password_reset OR problem_email 73 | - open_incident_form 74 | - form{"name":"open_incident_form"} 75 | * out_of_scope 76 | - utter_out_of_scope 77 | - open_incident_form 78 | - form{"name":null} 79 | - slot {"ticket_no": "0055"} 80 | 81 | ## incident form stop but continue 82 | * open_incident OR password_reset OR problem_email 83 | - open_incident_form 84 | - form{"name":"open_incident_form"} 85 | * deny 86 | - utter_continue 87 | * confirm 88 | - open_incident_form 89 | - form{"name":null} 90 | - slot {"ticket_no": "0055"} 91 | 92 | ## incident form stop and cancel 93 | * open_incident OR password_reset OR problem_email 94 | - open_incident_form 95 | - form{"name":"open_incident_form"} 96 | * deny 97 | - utter_continue 98 | * deny 99 | - action_deactivate_form 100 | - form{"name":null} 101 | - slot {"ticket_no": null} 102 | 103 | ## get incident status form 104 | * get_incident_status 105 | - incident_status_form 106 | - form{"name": "incident_status_form"} 107 | - form{"name": null} 108 | 109 | ## get incident status form interrupted 110 | * get_incident_status 111 | - incident_status_form 112 | - form{"name": "incident_status_form"} 113 | * help 114 | - utter_help 115 | - incident_status_form 116 | - form{"name":null} 117 | 118 | ## get incident status form interrupted 119 | * get_incident_status 120 | - incident_status_form 121 | - form{"name": "incident_status_form"} 122 | * out_of_scope 123 | - utter_out_of_scope 124 | - incident_status_form 125 | - form{"name":null} 126 | 127 | ## get incident status form stop but continue 128 | * get_incident_status 129 | - incident_status_form 130 | - form{"name": "incident_status_form"} 131 | * deny 132 | - utter_continue 133 | * confirm 134 | - incident_status_form 135 | - form{"name":null} 136 | 137 | ## get incident status form stop and cancel 138 | * get_incident_status 139 | - incident_status_form 140 | - form{"name": "incident_status_form"} 141 | * deny 142 | - utter_continue 143 | * deny 144 | - action_deactivate_form 145 | - form{"name":null} 146 | 147 | ## connect_wifi form happy_path success 148 | * connect_wifi 149 | - wifi_faq_form 150 | - form{"name": "wifi_faq_form"} 151 | - form{"name": null} 152 | * confirm 153 | - utter_welcome 154 | 155 | ## connect_wifi form happy_path fail 156 | * connect_wifi 157 | - wifi_faq_form 158 | - form{"name": "wifi_faq_form"} 159 | - form{"name": null} 160 | * deny{"incident_title":"Problema de conexion a la red WIFI", "itilcategory_id":"52"} 161 | - open_incident_form 162 | - form{"name": "open_incident_form"} 163 | - form{"name":null} 164 | - slot {"ticket_no": "0055"} 165 | 166 | ## connect_wifi form interrupted 167 | * connect_wifi 168 | - wifi_faq_form 169 | - form{"name":"wifi_faq_form"} 170 | * help 171 | - utter_help 172 | - wifi_faq_form 173 | - form{"name":null} 174 | 175 | ## connect_wifi form interrupted with chitchat 176 | * connect_wifi 177 | - wifi_faq_form 178 | - form{"name":"wifi_faq_form"} 179 | * out_of_scope 180 | - utter_out_of_scope 181 | - wifi_faq_form 182 | - form{"name":null} 183 | 184 | ## connect_wifi form cancelled 185 | * connect_wifi 186 | - wifi_faq_form 187 | - form{"name":"wifi_faq_form"} 188 | * deny 189 | - utter_continue 190 | * deny 191 | - action_deactivate_form 192 | - form{"name":null} 193 | - utter_process_cancelled 194 | 195 | ## connect_wifi form cancelled + resume 196 | * connect_wifi 197 | - wifi_faq_form 198 | - form{"name":"wifi_faq_form"} 199 | * deny 200 | - utter_continue 201 | * confirm 202 | - wifi_faq_form 203 | - form{"name":null} 204 | 205 | ## create_user form happy_path success 206 | * create_user 207 | - create_user_faq_form 208 | - form{"name": "create_user_faq_form"} 209 | - form{"name": null} 210 | * confirm 211 | - utter_welcome 212 | 213 | ## create_user form happy_path fail 214 | * create_user 215 | - create_user_faq_form 216 | - form{"name": "create_user_faq_form"} 217 | - form{"name": null} 218 | * deny{"incident_title":"Problema para crear un usuario", "itilcategory_id":"56"} 219 | - open_incident_form 220 | - form{"name": "open_incident_form"} 221 | - form{"name":null} 222 | - slot {"ticket_no": "0055"} 223 | 224 | ## create_user form interrupted 225 | * create_user 226 | - create_user_faq_form 227 | - form{"name":"create_user_faq_form"} 228 | * help 229 | - utter_help 230 | - create_user_faq_form 231 | - form{"name":null} 232 | 233 | ## create_user form interrupted with chitchat 234 | * create_user 235 | - create_user_faq_form 236 | - form{"name":"create_user_faq_form"} 237 | * out_of_scope 238 | - utter_out_of_scope 239 | - create_user_faq_form 240 | - form{"name":null} 241 | 242 | ## request_biometrics_report form 243 | * request_biometrics_report 244 | - biometrics_report_form 245 | - form{"name": "biometrics_report_form"} 246 | - form{"name": null} 247 | - slot {"ticket_no": "0055"} 248 | 249 | ## request_biometrics_report form interrupted 250 | * request_biometrics_report 251 | - biometrics_report_form 252 | - form{"name":"biometrics_report_form"} 253 | * help 254 | - utter_help 255 | - biometrics_report_form 256 | - form{"name":null} 257 | - slot {"ticket_no": "0055"} 258 | 259 | ## request_biometrics_report form interrupted with chitchat 260 | * request_biometrics_report 261 | - biometrics_report_form 262 | - form{"name":"biometrics_report_form"} 263 | * out_of_scope 264 | - utter_out_of_scope 265 | - biometrics_report_form 266 | - form{"name":null} 267 | - slot {"ticket_no": "0055"} 268 | 269 | ## request_vm form happy_path confirm 270 | * request_vm 271 | - compute_resource_form 272 | - form {"name": "compute_resource_form"} 273 | - form {"name": null} 274 | - slot {"ticket_no": "0055"} 275 | 276 | ## request_vm form interrupted 277 | * request_vm 278 | - compute_resource_form 279 | - form {"name": "compute_resource_form"} 280 | * out_of_scope 281 | - utter_out_of_scope 282 | - compute_resource_form 283 | - form {"name": null} 284 | - slot {"ticket_no": "0055"} 285 | 286 | ## request_vm form interrupted multiple 287 | * request_vm 288 | - compute_resource_form 289 | - form {"name": "compute_resource_form"} 290 | * out_of_scope 291 | - utter_out_of_scope 292 | - compute_resource_form 293 | * out_of_scope 294 | - utter_out_of_scope 295 | - compute_resource_form 296 | * out_of_scope 297 | - utter_out_of_scope 298 | - compute_resource_form 299 | - form {"name": null} 300 | - slot {"ticket_no": "0055"} 301 | 302 | ## request_vm form stop but continue 303 | * request_vm 304 | - compute_resource_form 305 | - form {"name": "compute_resource_form"} 306 | * deny 307 | - utter_continue 308 | * confirm 309 | - compute_resource_form 310 | - form {"name": null} 311 | - slot {"ticket_no": "0055"} 312 | 313 | ## request_vm form stop + cancel 314 | * request_vm 315 | - compute_resource_form 316 | - form {"name": "compute_resource_form"} 317 | * deny 318 | - utter_continue 319 | * deny 320 | - action_deactivate_form 321 | - form{"name":null} 322 | - slot {"ticket_no": null} 323 | -------------------------------------------------------------------------------- /data_bk/archive/test/stories_v1.md: -------------------------------------------------------------------------------- 1 | ## story_saludo 2 | * saludo 3 | - utter_intro 4 | * nombre{"sujeto": "Santiago Gonzalez"} 5 | - utter_saludo 6 | - utter_sugerencias 7 | 8 | ## story_despedida 9 | * despedida 10 | - utter_despedida 11 | 12 | ## story_agradecimiento 13 | * agradecimiento 14 | - utter_gracias 15 | 16 | ## story_nombre 17 | * nombre{"sujeto": "Santiago Gonzalez"} 18 | - utter_saludo 19 | - utter_sugerencias 20 | 21 | ## story_creacion_usuario 22 | * creacion_usuarios 23 | - action_joke 24 | - utter_mas_ayuda 25 | 26 | ## story_recuperar_contrasena 27 | * recuperar_contrsena 28 | - utter_email 29 | * correo_electronico 30 | - utter_contrasena 31 | - utter_confirmar_atencion 32 | * agradecimiento 33 | - utter_mas_ayuda 34 | * finaliza_sesion 35 | - utter_despedida 36 | - action_restart -------------------------------------------------------------------------------- /data_bk/archive/train/stories_v1.md: -------------------------------------------------------------------------------- 1 | ## story_saludo 2 | * saludo 3 | - utter_intro 4 | * nombre{"sujeto": "Santiago Gonzalez"} 5 | - utter_saludo 6 | - utter_sugerencias 7 | 8 | ## story_despedida 9 | * despedida 10 | - utter_despedida 11 | 12 | ## story_agradecimiento 13 | * agradecimiento 14 | - utter_gracias 15 | 16 | ## story_nombre 17 | * nombre{"sujeto": "Santiago Gonzalez"} 18 | - utter_saludo 19 | - utter_sugerencias 20 | 21 | ## story_creacion_usuario 22 | * creacion_usuarios 23 | - action_joke 24 | - utter_mas_ayuda 25 | 26 | ## story_recuperar_contrasena 27 | * recuperar_contrsena 28 | - utter_email 29 | * correo_electronico 30 | - utter_contrasena 31 | - utter_confirmar_atencion 32 | * agradecimiento 33 | - utter_mas_ayuda 34 | * finaliza_sesion 35 | - utter_despedida 36 | - action_restart -------------------------------------------------------------------------------- /data_bk/nlu.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## intent:greet 5 | - hey 6 | - hola 7 | - hola que tal 8 | - buenos dias 9 | - buenas tardes 10 | - buenas noches 11 | - Que hay 12 | 13 | ## intent:goodbye 14 | - chao 15 | - adios 16 | - nos vemos 17 | - nos vemos luego 18 | - chau 19 | - pues adios 20 | 21 | ## intent:thank 22 | - gracias! 23 | - gracias 24 | - muchas gracias 25 | - lo agradezco 26 | - que bien gracias 27 | 28 | ## intent:bot_challenge 29 | - eres un robot? 30 | - eres humano? 31 | - estoy hablando con un robot? 32 | - estoy hablando con un humano? 33 | - eres un robot verdad? 34 | - acaso eres un robot? 35 | 36 | ## intent:password_reset 37 | - necesito recuperar mi contraseña 38 | - necesito ayuda para recuperar mi contaseña 39 | - bo puedo reestablecer mi contraseña 40 | - necesito ayuda con mi contraseña 41 | - tengo problemas para reestablecer mi contraseña 42 | - la contraseña no funciona 43 | - recuperar la contraseña 44 | - reestablecer contraseña 45 | - he olvidado mi contraseña y no se como reestablecerla 46 | 47 | ## intent:open_incident 48 | - Necesito reportar una incidencia 49 | - Me puede ayudar abriendo una incidencia? 50 | - Tengo un problema y necesito reportar una incidencia 51 | - Abrir incidencia 52 | - Por favor me puede ayudar a reportar una incidencia por favor? 53 | - Quiero reportar una nueva incidencia 54 | - Quiero abrir una incidencia 55 | - Tengo un problema muy extraño 56 | - Tengo un problema 57 | - Tengo un problem y necesito reportar una incidecia 58 | - Tengo un inconveniente y necesito abrir una incidencia 59 | 60 | ## intent:help 61 | - Necesito ayuda 62 | - Con que me puedes ayudar? 63 | - Puedes ayudarme? 64 | - Que puedes hacer? 65 | - Necesito algo de ayuda 66 | - Ayudame 67 | - Me puede ayudar por favor? 68 | 69 | ## intent:problem_email 70 | - no puedo acceder a mi cuenta de correo gmail 71 | - tengo problemas con el correo de gmail 72 | - problemas con gmail 73 | - existe un problema con mi correo electrónico 74 | - no puedo iniciar sesion con mi correo electronico 75 | - no puedo iniciar sesion en gmail 76 | - no puedo iniciar sesion con mi cuenta de correo 77 | - tengo inconvenientes con mi email 78 | - problema con mi email 79 | 80 | ## intent:inform 81 | - mi correo es test@ucuenca.edu.ec 82 | - mi correo es abraham.lincoln@ucuenca.edu.ec 83 | - abraham.licoln@ucuenca.edu.ec 84 | - es abraham.licoln@ucuenca.edu.ec 85 | - abraham.lincolon@ucuenca.edu.ec 86 | - [baja](priority) 87 | - [media](priority) 88 | - [alta](priority) 89 | - es de prioridad [baja](priority) 90 | - prioridad [media](priority) 91 | - [alta](priority:high) 92 | - [urgente](priority:high) 93 | - [muy urgente](priority:high) 94 | 95 | ## intent:out_of_scope 96 | - cual es la raiz cuadrada de 5 97 | - como esta el clima 98 | - cual es el significado de la vida 99 | - mi regrigerador no funciona 100 | - la TV no funciona 101 | - quiero pizza 102 | - mi lavadora esta dañada 103 | - que año es 104 | - odernar una pizza 105 | - quiero ordenar una pizza 106 | - como sera el clima el dia de hoy 107 | - que dia es hoy 108 | - que fecha es hoy 109 | - como te llamas 110 | - quiero comida 111 | 112 | ## synonym:high 113 | - alta 114 | - urgente 115 | - importante 116 | - crucial 117 | -------------------------------------------------------------------------------- /data_bk/nlu_chatito/archive/glpiCommons_v1.chatito: -------------------------------------------------------------------------------- 1 | %[saludo]('training': '7', 'testing': '3') 2 | ~[saludos] 3 | 4 | %[despedida]('training': '7', 'testing': '3') 5 | ~[despedida] 6 | 7 | %[agradecimiento]('training': '3', 'testing': '2') 8 | ~[agradecimiento] 9 | 10 | %[nombre]('taining': '40', 'testing': '10') 11 | ~[presentacion?] @[sujeto] 12 | 13 | %[finaliza_sesion]('training': '50', 'testing': '10') 14 | ~[agradecimiento?] ~[despedida] 15 | 16 | %[confirmar]('training': '2', 'testing': '2') 17 | ~[afirmar] 18 | 19 | ~[presentacion] 20 | Mi nombre es 21 | Me llamo 22 | Yo me llamo 23 | Soy 24 | 25 | ~[saludos] 26 | saludos 27 | hola 28 | buenos dias 29 | buenas tardes 30 | hey 31 | hola hola 32 | saludos saludos 33 | buenas 34 | hola buenos dias 35 | hola buenas tardes 36 | 37 | ~[despedida] 38 | hasta luego 39 | adios 40 | chao 41 | finalizar 42 | salir 43 | finaliza sesion 44 | chao chao 45 | terminar 46 | acabar sesion 47 | termina 48 | 49 | ~[afirmar] 50 | si 51 | esta bien 52 | ok 53 | confirmado 54 | 55 | ~[agradecimiento] 56 | muchas gracias 57 | gracias 58 | gracias por su ayuda 59 | agradezco su su ayuda 60 | gracias gracias 61 | 62 | @[sujeto] 63 | Jenny Maricela Redrovan Macas 64 | Karina Sarmiento 65 | Juan Perez 66 | Joselito Juanete 67 | Cuenca Ciudad Universitaria 68 | Coordinador Vinculacion Sociedad 69 | Santiago 70 | Cecilia 71 | Oscar Malgiaritta 72 | Marcelo Dosantos -------------------------------------------------------------------------------- /data_bk/nlu_chatito/archive/glpiCommons_v2.chatito: -------------------------------------------------------------------------------- 1 | %[saludo]('training': '7', 'testing': '3') 2 | ~[saludos] 3 | 4 | %[despedida]('training': '7', 'testing': '3') 5 | ~[despedida] 6 | 7 | %[agradecimiento]('training': '7', 'testing': '3') 8 | ~[agradecimiento] 9 | 10 | %[nombre]('training': '40', 'testing': '10') 11 | ~[presentacion?] @[PER] 12 | 13 | %[solicitar_opciones]('training': '7', 'testing': '3') 14 | ~[necesito ayuda] 15 | ~[ayuda] 16 | ~[ayudame] 17 | ~[solicito ayuda] 18 | ~[opciones] 19 | ~[opciones disponibles] 20 | ~[seleccionar opciones] 21 | ~[mostrar opciones] 22 | ~[menu] 23 | ~[mostrar menu] 24 | 25 | %[confirmar]('training': '10', 'testing': '4') 26 | ~[afirmar] 27 | 28 | %[cancelar]('training': '11', 'testing': '5') 29 | ~[denegar] 30 | 31 | %[chitchat]('training': '9', 'testing': '5') 32 | ~[random] 33 | 34 | ~[presentacion] 35 | Mi nombre es 36 | Me llamo 37 | Yo me llamo 38 | Soy 39 | 40 | ~[saludos] 41 | saludos 42 | hola 43 | buenos dias 44 | buenas tardes 45 | hey 46 | hola hola 47 | saludos saludos 48 | buenas 49 | hola buenos dias 50 | hola buenas tardes 51 | 52 | ~[despedida] 53 | hasta luego 54 | adios 55 | chao 56 | finalizar 57 | salir 58 | finaliza sesion 59 | chao chao 60 | terminar 61 | acabar sesion 62 | termina 63 | 64 | ~[afirmar] 65 | si 66 | si si si 67 | esta bien 68 | ok 69 | confirmado 70 | de acuerdo 71 | afirmativo 72 | confirmar 73 | corroborar 74 | ratificar 75 | convalidar 76 | revalidar 77 | reafirmar 78 | aseverar 79 | 80 | ~[denegar] 81 | no 82 | negativo 83 | cancelar 84 | cancelado 85 | cancela 86 | parar 87 | no continuar 88 | salir 89 | denegar 90 | denegado 91 | no gracias 92 | oh no 93 | no es lo que deseo 94 | no eres util 95 | no me sirve 96 | no es lo que quiero 97 | 98 | ~[agradecimiento] 99 | muchas gracias 100 | gracias 101 | gracias por su ayuda 102 | agradezco su su ayuda 103 | gracias gracias 104 | gracias 105 | estoy agradecido 106 | muchas gracias 107 | gracias por su ayuda 108 | agradezco su su ayuda 109 | 110 | ~[random] 111 | quien eres? 112 | quien es tu creador? 113 | como estas? 114 | como te encuentras? 115 | que tal tu dia? 116 | estas bien? 117 | como has pasado? 118 | como es el clima de hoy? 119 | esta lloviendo? 120 | esta haciendo frio? 121 | esta haciendo frio? 122 | feliz dia 123 | como sera el clima de hoy? 124 | como te llamas? 125 | 126 | @[PER] 127 | Jenny Maricela Redrovan Macas 128 | Karina Sarmiento 129 | Juan Perez 130 | Joselito Juanete 131 | Cuenca Ciudad Universitaria 132 | Coordinador Vinculacion Sociedad 133 | Santiago 134 | Cecilia 135 | Oscar Malgiaritta 136 | Marcelo Dosantos -------------------------------------------------------------------------------- /data_bk/nlu_chatito/archive/glpiHeldesk_v1.chatito: -------------------------------------------------------------------------------- 1 | 2 | %[creacion_usuarios]('training': '100', 'testing': '20') 3 | ~[saludos?] ~[peticion?] ~[nuevo_usuario] @[sistema?] ~[para?] @[trato?] @[sujeto] @[facultad?] 4 | 5 | %[recuperar_contrsena]('training': '100', 'testing': '20') 6 | ~[saludos?] ~[peticion?] @[usuario?] ~[sin_acceso] @[sistema?] 7 | 8 | %[error_procesos]('training': '300', 'testing': '60') 9 | ~[saludos?] ~[peticion?] ~[problema] ~[proceso#matriculas] @[facultad?] 10 | ~[saludos?] ~[peticion?] ~[problema] ~[proceso#inscripcion] @[facultad?] 11 | ~[saludos?] ~[peticion?] ~[problema?] ~[proceso#equipos] @[ubicacion?] @[facultad?] 12 | 13 | %[asistencia_pregrado]('training': '200', 'testing': '40') 14 | ~[saludos?] ~[peticion?] ~[problema] ~[pregrado#materias] @[sujeto?] 15 | ~[saludos?] ~[peticion?] ~[problema] ~[pregrado#actas] @[sujeto?] 16 | 17 | %[correo_electronico]('training': '4', 'testing': '4') 18 | @[email] 19 | ~[mi?] ~[correo?] ~[electronico?] @[email] 20 | 21 | // alias 22 | ~[saludos] 23 | saludos 24 | hola 25 | buenos dias 26 | buenas tardes 27 | 28 | ~[peticion] 29 | necesito 30 | requiero 31 | necesito su ayuda 32 | ayuda 33 | solicito 34 | 35 | ~[problema] 36 | problema 37 | error 38 | inconveniente 39 | revision 40 | 41 | ~[nuevo_usuario] 42 | creacion de usuario 43 | creacion de cuenta de usuario 44 | creacion de cuenta 45 | registrar personal 46 | crear nuevo usuario 47 | crear usuario y asignar roles 48 | acceso al sistema 49 | acceso a 50 | 51 | ~[sin_acceso] 52 | No hay acceso 53 | Sin acceso 54 | no puedo acceder 55 | no recuerda contrasena 56 | olvide contrasena 57 | 58 | ~[proceso#matriculas] 59 | registro matricula 60 | registro ficha socioeconomica 61 | acceso a eSIUC 62 | ficha de matricula 63 | ficha socioeconomica 64 | 65 | ~[proceso#inscripcion] 66 | registro materia 67 | asignacion credito 68 | falta cupo 69 | no encuentra informacion estudiante 70 | 71 | ~[proceso#equipos] 72 | no enciende computador 73 | impresora no funciona 74 | no imprime 75 | conexion PC 76 | computador no inicia 77 | instalacion equipo 78 | instalacion impresora 79 | instalacion sistema 80 | mantenimiento computador 81 | configuracion de equipo 82 | conexion puntos de red 83 | proyector no enciende 84 | telefonos no funcionan 85 | respaldo de informacion 86 | revisar proyector 87 | no funciona impresora 88 | no funciona escaner 89 | 90 | ~[pregrado#materias] 91 | migracion de notas 92 | migracion de calificaciones 93 | revision malla 94 | configuracion malla 95 | revision registros estudiante 96 | 97 | ~[pregrado#actas] 98 | cambio numero acta de grado 99 | configuracion de actas 100 | no se genera acta de grado 101 | problema generacion de acta de grado 102 | registro titulos historicos 103 | correccion fecha acta de grado 104 | anulacion actas de grado 105 | problemas de numeración actas de grado 106 | 107 | @[sistema] 108 | Urkund 109 | Sistemas Institucionales 110 | Portafolio 111 | Quipux 112 | eVirtual 113 | OpenERP 114 | GLPI 115 | 116 | @[trato] 117 | Lcdo 118 | Lcda 119 | Sr 120 | Sra 121 | Ing 122 | Dr 123 | Secretaria Abogada 124 | Estudiante 125 | Director 126 | 127 | @[sujeto] 128 | Jenny Maricela Redrovan Macas 129 | Karina Sarmiento 130 | Juan Perez 131 | Joselito Juanete 132 | Cuenca Ciudad Universitaria 133 | Coordinador Vinculacion Sociedad 134 | 135 | @[usuario] 136 | adrian.narvaezp 137 | hernan.gonzalezt 138 | renan.freirez 139 | 140 | @[ubicacion] 141 | Aula 107 142 | Centro computo 118 A 143 | Consejo Universitario 144 | Rectorado 145 | 146 | @[facultad] 147 | ~[Facultad Hospitalidad] 148 | ~[Facultad Medicina] 149 | ~[Facultad Ingenieria] 150 | ~[Facultad Psicologia] 151 | ~[Facultad Ingenieria] 152 | 153 | ~[Facultad Ingenieria] 154 | Facultad Ingenieria 155 | Ingenieria 156 | Sistemas 157 | Civil 158 | Electronica 159 | Electrica 160 | Ing 161 | 162 | @[email] 163 | hernan.gonzalez@ucuenca.edu.ec 164 | victor.saquicela@ucuenca.edu.ec 165 | hernan.gonzalezt@ucuenca.ec 166 | ronald.gualan@ucuenca.ec -------------------------------------------------------------------------------- /data_bk/nlu_chatito/archive/glpiHelpdesk_v2.chatito: -------------------------------------------------------------------------------- 1 | %[creacion_usuarios]('training': '100', 'testing': '20') 2 | ~[saludos?] ~[peticion?] ~[nuevo_usuario] @[sistema?] ~[para?] @[trato?] @[PER] @[facultad?] 3 | 4 | %[recuperar_contrasena]('training': '100', 'testing': '20') 5 | ~[saludos?] ~[peticion?] @[usuario?] ~[sin_acceso] @[sistema?] 6 | 7 | %[especifica_sistema]('training': '6', 'testing': '4') 8 | @[sistema] 9 | 10 | %[correo_electronico]('training': '4', 'testing': '4') 11 | @[email] 12 | ~[mi?] ~[correo?] ~[electronico?] @[email] 13 | 14 | %[peticion_recurso_computacional]('training': '200', 'testing': '40') 15 | ~[peticion] ~[recurso_computacional] 16 | ~[saludos?] ~[peticion] ~[recurso_computacional] ~[ram_suffix?] ~[cpu_cores_suffix?] ~[disk_space_suffix?] 17 | 18 | %[informacion]('training': '200', 'testing': '40') 19 | ~[necesito un?] ~[ambiente de?] @[entorno] 20 | ~[peticion?] ~[ram_suffix] 21 | ~[peticion?] ~[cpu_cores_suffix] 22 | ~[peticion?] ~[disk_space_suffix] 23 | ~[peticion?] ~[escalabilidad] 24 | 25 | // alias 26 | ~[saludos] 27 | saludos 28 | hola 29 | buenos dias 30 | buenas tardes 31 | 32 | ~[peticion] 33 | necesito 34 | requiero 35 | necesito ayuda 36 | ayuda 37 | solicito 38 | 39 | ~[problema] 40 | problema 41 | error 42 | inconveniente 43 | revision 44 | 45 | ~[nuevo_usuario] 46 | creacion de usuario 47 | creacion de cuenta de usuario 48 | creacion de cuenta 49 | registrar personal 50 | crear nuevo usuario 51 | crear usuario y asignar roles 52 | acceso al sistema 53 | acceso a 54 | 55 | ~[sin_acceso] 56 | No hay acceso 57 | Sin acceso 58 | no puedo acceder 59 | no recuerda contrasena 60 | olvide contrasena 61 | 62 | ~[proceso#matriculas] 63 | registro matricula 64 | registro ficha socioeconomica 65 | acceso a eSIUC 66 | ficha de matricula 67 | ficha socioeconomica 68 | 69 | ~[proceso#inscripcion] 70 | registro materia 71 | asignacion credito 72 | falta cupo 73 | no encuentra informacion estudiante 74 | 75 | ~[proceso#equipos] 76 | no enciende computador 77 | impresora no funciona 78 | no imprime 79 | conexion PC 80 | computador no inicia 81 | instalacion equipo 82 | instalacion impresora 83 | instalacion sistema 84 | mantenimiento computador 85 | configuracion de equipo 86 | conexion puntos de red 87 | proyector no enciende 88 | telefonos no funcionan 89 | respaldo de informacion 90 | revisar proyector 91 | no funciona impresora 92 | no funciona escaner 93 | 94 | ~[pregrado#materias] 95 | migracion de notas 96 | migracion de calificaciones 97 | revision malla 98 | configuracion malla 99 | revision registros estudiante 100 | 101 | ~[pregrado#actas] 102 | cambio numero acta de grado 103 | configuracion de actas 104 | no se genera acta de grado 105 | problema generacion de acta de grado 106 | registro titulos historicos 107 | correccion fecha acta de grado 108 | anulacion actas de grado 109 | problemas de numeración actas de grado 110 | 111 | ~[recurso_computacional] 112 | maquina virtual 113 | una VM 114 | una instancia 115 | un servidor 116 | acceso a una maquina 117 | 118 | @[sistema] 119 | Urkund 120 | Portafolio 121 | Quipux 122 | eVirtual 123 | OpenERP 124 | GLPI 125 | 126 | @[trato] 127 | Lcdo 128 | Lcda 129 | Sr 130 | Sra 131 | Ing 132 | Dr 133 | Secretaria Abogada 134 | Estudiante 135 | Director 136 | 137 | @[PER] 138 | Jenny Maricela Redrovan Macas 139 | Karina Sarmiento 140 | Juan Perez 141 | Joselito Juanete 142 | Cuenca Ciudad Universitaria 143 | Coordinador Vinculacion Sociedad 144 | Santiago 145 | Cecilia 146 | Oscar Malgiaritta 147 | Marcelo Dosantos 148 | 149 | @[usuario] 150 | adrian.narvaezp 151 | hernan.gonzalezt 152 | renan.freirez 153 | 154 | @[ubicacion] 155 | Aula 107 156 | Centro computo 118 A 157 | Consejo Universitario 158 | Rectorado 159 | 160 | @[facultad] 161 | ~[Facultad Hospitalidad] 162 | ~[Facultad Medicina] 163 | ~[Facultad Ingenieria] 164 | ~[Facultad Psicologia] 165 | ~[Facultad Ingenieria] 166 | 167 | ~[Facultad Ingenieria] 168 | Facultad Ingenieria 169 | Ingenieria 170 | Sistemas 171 | Civil 172 | Electronica 173 | Electrica 174 | Ing 175 | 176 | @[email] 177 | hernan.gonzalez@ucuenca.edu.ec 178 | victor.saquicela@ucuenca.edu.ec 179 | hernan.gonzalezt@ucuenca.ec 180 | ronald.gualan@ucuenca.ec 181 | 182 | @[departamento] 183 | Redes 184 | Desarrollo 185 | Helpdesk 186 | Infraestructura 187 | 188 | @[entorno] 189 | desarrollo 190 | pruebas 191 | produccion 192 | 193 | @[ram] 194 | 8 195 | 16 196 | 32 197 | 64 198 | 128 199 | 200 | ~[ram_suffix] 201 | @[ram] GB de ram 202 | @[ram] GB en RAM 203 | @[ram] GB de capacidad en RAM 204 | 205 | @[cpu_cores] 206 | 1 207 | 2 208 | 3 209 | 4 210 | 8 211 | 212 | ~[cpu_cores_suffix] 213 | @[cpu_cores] nucleos 214 | @[cpu_cores] procesadores 215 | @[cpu_cores] nucleos de cpu 216 | 217 | @[disk_space] 218 | 8 219 | 16 220 | 128 221 | 256 222 | 512 223 | 1000 224 | 225 | ~[disk_space_suffix] 226 | @[disk_space] GB de disco duro 227 | @[disk_space] GB de capacidad 228 | @[disk_space] GB de HD 229 | 230 | ~[escalabilidad] 231 | escalabilidad horizontal 232 | escalabilidad vertical 233 | -------------------------------------------------------------------------------- /data_bk/nlu_chatito/glpiCommons.chatito: -------------------------------------------------------------------------------- 1 | %[saludo]('training': '7', 'testing': '3') 2 | ~[saludos] 3 | 4 | %[despedida]('training': '8', 'testing': '4') 5 | ~[despedida] 6 | 7 | %[agradecimiento]('training': '6', 'testing': '4') 8 | ~[agradecimiento] 9 | 10 | %[nombre]('training': '40', 'testing': '10') 11 | ~[presentacion?] @[PER] 12 | ~[soy?] @[ORG] 13 | 14 | %[solicitar_opciones]('training': '7', 'testing': '3') 15 | ~[ayuda] 16 | ~[ayudame] 17 | ~[solicito ayuda] 18 | ~[opciones] 19 | ~[opciones disponibles] 20 | ~[seleccionar opciones] 21 | ~[mostrar opciones] 22 | ~[menu] 23 | ~[mostrar menu] 24 | ~[ver menu] 25 | 26 | %[confirmar]('training': '16', 'testing': '8') 27 | ~[afirmar] 28 | ~[si si] 29 | ~[bueno bueno] 30 | ~[esta bien] 31 | ~[ok ok] 32 | ~[si acepto] 33 | ~[si confirmo] 34 | ~[si confirma] 35 | ~[si acepta] 36 | ~[confirmado] 37 | ~[okay okay] 38 | ~[confirmar] 39 | ~[aceptar] 40 | 41 | %[cancelar]('training': '16', 'testing': '8') 42 | ~[denegar] 43 | ~[no] 44 | ~[negativo] 45 | ~[cancelar] 46 | ~[cancelado] 47 | ~[cancela] 48 | ~[parar] 49 | ~[no continuar] 50 | ~[salir] 51 | ~[denegar] 52 | ~[denegado] 53 | ~[no gracias] 54 | ~[no no] 55 | ~[no es lo que deseo] 56 | ~[no es lo que quiero] 57 | 58 | %[chitchat]('training': '10', 'testing': '8') 59 | ~[random] 60 | 61 | ~[presentacion] 62 | Mi nombre es 63 | Me llamo 64 | Yo me llamo 65 | Soy 66 | 67 | ~[saludos] 68 | saludos 69 | hola 70 | buenos dias 71 | buenas tardes 72 | hey 73 | hola hola 74 | saludos saludos 75 | buenas 76 | hola buenos dias 77 | hola buenas tardes 78 | 79 | ~[despedida] 80 | hasta luego 81 | adios 82 | chao 83 | finalizar 84 | salir 85 | finaliza sesion 86 | chao chao 87 | termina 88 | fin 89 | terminar 90 | terminar sesion 91 | acabar sesion 92 | 93 | ~[afirmar] 94 | si 95 | bueno 96 | esta bien 97 | ok 98 | acepto 99 | confirmo 100 | confirma 101 | acepta 102 | confirmado 103 | okay 104 | confirmar 105 | aceptar 106 | 107 | ~[denegar] 108 | no 109 | negativo 110 | cancelar 111 | cancelado 112 | cancela 113 | parar 114 | no continuar 115 | salir 116 | denegar 117 | denegado 118 | no gracias 119 | no no 120 | no es lo que deseo 121 | no es lo que quiero 122 | 123 | ~[agradecimiento] 124 | muchas gracias 125 | gracias 126 | gracias por su ayuda 127 | agradezco su su ayuda 128 | gracias gracias 129 | gracias 130 | estoy agradecido 131 | muchas gracias 132 | gracias por su ayuda 133 | agradezco su su ayuda 134 | 135 | ~[random] 136 | quien eres? 137 | quien es tu creador? 138 | como estas? 139 | que tal tu dia? 140 | estas bien? 141 | como has pasado? 142 | como es el clima de hoy? 143 | esta lloviendo? 144 | esta haciendo frio? 145 | esta haciendo frio? 146 | feliz dia 147 | como sera el clima de hoy? 148 | como te llamas? 149 | eres inutil 150 | no sirves 151 | cuentame algo 152 | eres un robot? 153 | solo eres un robot 154 | 155 | @[PER] 156 | Jenny Maricela Redrovan Macas 157 | Karina Sarmiento 158 | Juan Perez 159 | Joselito Juanete 160 | Santiago 161 | Cecilia 162 | Oscar Malgiaritta 163 | Marcelo Dosantos 164 | 165 | @[ORG] 166 | Cuenca Ciudad Universitaria 167 | Coordinador Vinculacion Sociedad -------------------------------------------------------------------------------- /data_bk/nlu_chatito/glpiHeldesk.chatito: -------------------------------------------------------------------------------- 1 | %[creacion_usuarios]('training': '100', 'testing': '20') 2 | ~[nuevo_usuario] 3 | ~[saludos?] ~[peticion?] ~[nuevo_usuario] @[sistema?] ~[para?] @[trato?] @[PER] @[facultad?] 4 | 5 | %[recuperar_contrasena]('training': '100', 'testing': '20') 6 | ~[sin_acceso] 7 | ~[saludos?] ~[peticion?] ~[sin_acceso] @[sistema?] 8 | 9 | %[especifica_sistema]('training': '10', 'testing': '5') 10 | @[sistema] 11 | ~[el] @[sistema] 12 | 13 | %[correo_electronico]('training': '140', 'testing': '60') 14 | @[email] 15 | ~[mi correo?] ~[electronico?] @[email] 16 | 17 | %[peticion_recurso_computacional]('training': '100', 'testing': '20') 18 | ~[peticion] ~[recurso_computacional] 19 | ~[peticion?] ~[recurso_computacional] ~[ram_suffix?] ~[cpu_cores_suffix?] ~[disk_space_suffix?] 20 | 21 | %[informacion]('training': '100', 'testing': '20') 22 | ~[necesito un?] ~[ambiente de?] @[entorno] 23 | ~[ram_suffix] 24 | ~[peticion?] ~[ram_suffix] 25 | ~[cpu_cores_suffix] 26 | ~[peticion?] ~[cpu_cores_suffix] 27 | ~[disk_space_suffix] 28 | ~[peticion?] ~[disk_space_suffix] 29 | ~[escalabilidad] 30 | ~[peticion?] ~[escalabilidad] 31 | 32 | // alias 33 | ~[saludos] 34 | saludos 35 | hola 36 | buenos dias 37 | buenas tardes 38 | 39 | ~[peticion] 40 | necesito 41 | requiero 42 | solicito 43 | 44 | ~[problema] 45 | problema 46 | error 47 | inconveniente 48 | revision 49 | 50 | ~[nuevo_usuario] 51 | creacion de usuario 52 | creacion de cuenta de usuario 53 | creacion de cuenta 54 | registrar personal 55 | crear nuevo usuario 56 | crear usuario y asignar roles 57 | acceso al sistema 58 | acceso a 59 | 60 | ~[sin_acceso] 61 | No hay acceso 62 | Sin acceso 63 | no puedo acceder 64 | no recuerda contrasena 65 | olvide contrasena 66 | 67 | ~[proceso#matriculas] 68 | registro matricula 69 | registro ficha socioeconomica 70 | acceso a eSIUC 71 | ficha de matricula 72 | ficha socioeconomica 73 | 74 | ~[proceso#inscripcion] 75 | registro materia 76 | asignacion credito 77 | falta cupo 78 | no encuentra informacion estudiante 79 | 80 | ~[proceso#equipos] 81 | no enciende computador 82 | impresora no funciona 83 | no imprime 84 | conexion PC 85 | computador no inicia 86 | instalacion equipo 87 | instalacion impresora 88 | instalacion sistema 89 | mantenimiento computador 90 | configuracion de equipo 91 | conexion puntos de red 92 | proyector no enciende 93 | telefonos no funcionan 94 | respaldo de informacion 95 | revisar proyector 96 | no funciona impresora 97 | no funciona escaner 98 | 99 | ~[pregrado#materias] 100 | migracion de notas 101 | migracion de calificaciones 102 | revision malla 103 | configuracion malla 104 | revision registros estudiante 105 | 106 | ~[pregrado#actas] 107 | cambio numero acta de grado 108 | configuracion de actas 109 | no se genera acta de grado 110 | problema generacion de acta de grado 111 | registro titulos historicos 112 | correccion fecha acta de grado 113 | anulacion actas de grado 114 | problemas de numeración actas de grado 115 | 116 | ~[recurso_computacional] 117 | maquina virtual 118 | una VM 119 | una instancia 120 | un servidor 121 | acceso a una maquina 122 | 123 | @[sistema] 124 | Urkund 125 | Portafolio 126 | Quipux 127 | eVirtual 128 | OpenERP 129 | GLPI 130 | 131 | @[trato] 132 | Lcdo 133 | Lcda 134 | Sr 135 | Sra 136 | Ing 137 | Dr 138 | Secretaria Abogada 139 | Estudiante 140 | Director 141 | 142 | @[PER] 143 | Jenny Maricela Redrovan Macas 144 | Karina Sarmiento 145 | Juan Perez 146 | Joselito Juanete 147 | Cuenca Ciudad Universitaria 148 | Coordinador Vinculacion Sociedad 149 | Santiago 150 | Cecilia 151 | Oscar Malgiaritta 152 | Marcelo Dosantos 153 | 154 | @[usuario] 155 | adrian.narvaezp 156 | hernan.gonzalezt 157 | renan.freirez 158 | 159 | @[ubicacion] 160 | Aula 107 161 | Centro computo 118 A 162 | Consejo Universitario 163 | Rectorado 164 | 165 | @[facultad] 166 | ~[Facultad Hospitalidad] 167 | ~[Facultad Medicina] 168 | ~[Facultad Ingenieria] 169 | ~[Facultad Psicologia] 170 | ~[Facultad Ingenieria] 171 | 172 | ~[Facultad Ingenieria] 173 | Facultad Ingenieria 174 | Ingenieria 175 | Sistemas 176 | Civil 177 | Electronica 178 | Electrica 179 | Ing 180 | 181 | @[email] 182 | hernan.gonzalez@ucuenca.edu.ec 183 | victor.saquicela@ucuenca.edu.ec 184 | hernan.gonzalezt@ucuenca.ec 185 | ronald.gualan@ucuenca.ec 186 | victor.saquicela@ucuenca.edu.ec 187 | christopher.morochov@ucuenca.edu.ec 188 | daniela.barrera@ucuenca.edu.ec 189 | diego.paredes@ucuenca.edu.ec 190 | luis.espinoza@ucuenca.edu.ec 191 | mariajose.torres@ucuenca.edu.ec 192 | pablo.palacios@ucuenca.edu.ec 193 | juan.urgilesc@ucuenca.edu.ec 194 | patricio.juca@ucuenca.edu.ec 195 | mjose.zunigaz@ucuenca.edu.ec 196 | marlene.roblesg@ucuenca.edu.ec 197 | eduardo.bernala@ucuenca.edu.ec 198 | diana.espinozag@ucuenca.edu.ec 199 | cristian.montero@ucuenca.edu.ec 200 | christian.barrera@ucuenca.edu.ec 201 | catalina.morochoq@ucuenca.edu.ec 202 | sebastian.roman@ucuenca.edu.ec 203 | santiago.alvarado@ucuenca.edu.ec 204 | rodrigo.padilla@ucuenca.edu.ec 205 | santiago.ulloa@ucuenca.edu.ec 206 | pablo.garrido@ucuenca.edu.ec 207 | mauricio.brito@ucuenca.edu.ec 208 | mariaeugenia.fajardo@ucuenca.edu.ec 209 | marcelo.olivo@ucuenca.edu.ec 210 | luis.juradoc@ucuenca.edu.ec 211 | lenin.gonzalez@ucuenca.edu.ec 212 | julio.salinas@ucuenca.edu.ec 213 | juanc.gomezp@ucuenca.edu.ec 214 | jose.zumba@ucuenca.edu.ec 215 | jose.guerrerop@ucuenca.edu.ec 216 | jaime.perez@ucuenca.edu.ec 217 | jackeline.bermeo@ucuenca.edu.ec 218 | geovanny.campoverde@ucuenca.edu.ec 219 | gabriela.siguenzac@ucuenca.edu.ec 220 | elvia.alvarez@ucuenca.edu.ec 221 | elias.mora@ucuenca.edu.ec 222 | carmita.rojas@ucuenca.edu.ec 223 | andres.delosreyes@ucuenca.edu.ec 224 | alina.guerrero@ucuenca.edu.ec 225 | rosa.dominguez@ucuenca.edu.ec 226 | ricardo.merchan@ucuenca.edu.ec 227 | raul.cordero@ucuenca.edu.ec 228 | rafael.holguin@ucuenca.edu.ec 229 | patricio.hidalgo@ucuenca.edu.ec 230 | patricia.garces@ucuenca.edu.ec 231 | paola.jaramillov@ucuenca.edu.ec 232 | pablo.leon@ucuenca.edu.ec 233 | nube.mendez@ucuenca.edu.ec 234 | nelson.navarro@ucuenca.edu.ec 235 | natasha.cabrera@ucuenca.edu.ec 236 | natalia.pacurucu@ucuenca.edu.ec 237 | monica.mendieta@ucuenca.edu.ec 238 | monica.gonzalez@ucuenca.edu.ec 239 | marcelo.vazquez@ucuenca.edu.ec 240 | luis.crespo@ucuenca.edu.ec 241 | lorena.vivanco@ucuenca.edu.ec 242 | lorena.vazquez@ucuenca.edu.ec 243 | leonardo.ramos@ucuenca.edu.ec 244 | klever.mendez@ucuenca.edu.ec 245 | karina.sarmiento@ucuenca.edu.ec 246 | julia.tamayo@ucuenca.edu.ec 247 | juan.sola@ucuenca.edu.ec 248 | juan.carvallo@ucuenca.edu.ec 249 | juan.briones@ucuenca.edu.ec 250 | juan.aviles@ucuenca.edu.ec 251 | jose.sanchez@ucuenca.edu.ec 252 | jorge.tenesaca@ucuenca.edu.ec 253 | johana.avilad@ucuenca.edu.ec 254 | jenny.luna@ucuenca.edu.ec 255 | javier.saltos@ucuenca.edu.ec 256 | javier.duran@ucuenca.edu.ec 257 | jaime.guerra@ucuenca.edu.ec 258 | ivan.sinchi@ucuenca.edu.ec 259 | hernan.garcia@ucuenca.edu.ec 260 | gabriela.pinos@ucuenca.edu.ec 261 | fernando.pautac@ucuenca.edu.ec 262 | fernando.cordero@ucuenca.edu.ec 263 | felipe.quesada@ucuenca.edu.ec 264 | fausto.cardoso@ucuenca.edu.ec 265 | farah.alvarado@ucuenca.edu.ec 266 | fabian.cazar@ucuenca.edu.ec 267 | eugenio.reyesj@ucuenca.edu.ec 268 | esteban.zalamea@ucuenca.edu.ec 269 | enrique.luna@ucuenca.edu.ec 270 | enrique.flores@ucuenca.edu.ec 271 | edison.sinchit@ucuenca.edu.ec 272 | edison.castillo@ucuenca.edu.ec 273 | diego.jaramillo@ucuenca.edu.ec 274 | diana.sarmiento@ucuenca.edu.ec 275 | david.munoz@ucuenca.edu.ec 276 | daniel.samaniego@ucuenca.edu.ec 277 | daniel.idrovo@ucuenca.edu.ec 278 | christian.contreras@ucuenca.edu.ec 279 | cecilia.rodriguezt16@ucuenca.edu.ec 280 | cecilia.achig@ucuenca.edu.ec 281 | catalina.vintimilla@ucuenca.edu.ec 282 | catalina.rodas@ucuenca.edu.ec 283 | boris.orellana@ucuenca.edu.ec 284 | augusta.hermida@ucuenca.edu.ec 285 | santiago.velez@ucuenca.edu.ec 286 | sebastian.astudillo@ucuenca.edu.ec 287 | sebastian.mora@ucuenca.edu.ec 288 | soledad.moscoso@ucuenca.edu.ec 289 | vanessa.guillen@ucuenca.edu.ec 290 | veronica.heras@ucuenca.edu.ec 291 | veronica.luna@ucuenca.edu.ec 292 | xavier.cardenas@ucuenca.edu.ec 293 | ximena.salazar@ucuenca.edu.ec 294 | andrea.loja@ucuenca.edu.ec 295 | andrea.calle@ucuenca.edu.ec 296 | andrea.ariasv@ucuenca.edu.ec 297 | alfredo.ordonez@ucuenca.edu.ec 298 | alexandra.kennedy@ucuenca.edu.ec 299 | alex.serrano@ucuenca.edu.ec 300 | wilmer.jumbo@ucuenca.edu.ec 301 | william.vergara@ucuenca.edu.ec 302 | walter.novillo@ucuenca.edu.ec 303 | victor.gonzalez@ucuenca.edu.ec 304 | veronica.saulaf@ucuenca.edu.ec 305 | susanna.khachatryan@ucuenca.edu.ec 306 | sonia.pacheco@ucuenca.edu.ec 307 | sebastian.martinez@ucuenca.edu.ec 308 | santiago.vintimillac@ucuenca.ec 309 | santiago.ordonez@ucuenca.edu.ec 310 | santiago.calle87@ucuenca.edu.ec 311 | sandra.amorosor@ucuenca.edu.ec 312 | samia.gallardoh@ucuenca.edu.ec 313 | rocio.perez@ucuenca.edu.ec 314 | roberto.landivar@ucuenca.edu.ec 315 | reynel.alvarado@ucuenca.edu.ec 316 | rene.martinez@ucuenca.edu.ec 317 | priscila.urgiles@ucuenca.edu.ec 318 | pedro.andrade@ucuenca.edu.ec 319 | paulina.mejia@ucuenca.edu.ec 320 | paul.sanmartin@ucuenca.edu.ec 321 | pablo.ramos@ucuenca.edu.ec 322 | pablo.carrasco@ucuenca.edu.ec 323 | olmedo.alvarado@ucuenca.edu.ec 324 | nelson.ortegac11@ucuenca.edu.ec 325 | miriam.bojorque@ucuenca.edu.ec 326 | mercedes.crespo@ucuenca.edu.ec 327 | manuel.leon@ucuenca.edu.ec 328 | manuel.guzman@ucuenca.edu.ec 329 | manuel.escudero@ucuenca.edu.ec 330 | magali.criollo@ucuenca.edu.ec 331 | macarena.montes@ucuenca.edu.ec 332 | loreto.burgueno@ucuenca.edu.ec 333 | karla.ortega@ucuenca.edu.ec 334 | karla.leon@ucuenca.edu.ec 335 | julio.mosquera@ucuenca.edu.ec 336 | julio.alvarezp@ucuenca.edu.ec 337 | juan.panora@ucuenca.edu.ec 338 | juan.fajardo@ucuenca.edu.ec 339 | juan.davila@ucuenca.edu.ec 340 | jose.urgiles@ucuenca.edu.ec 341 | jose.carrion@ucuenca.edu.ec 342 | jorge.salinas@ucuenca.edu.ec 343 | jorge.ortega@ucuenca.edu.ec 344 | jonathan.ruiz@ucuenca.edu.ec 345 | jimena.penaherreraw@ucuenca.edu.ec 346 | jesus.rencurrell@ucuenca.edu.ec 347 | jannet.alvarado@ucuenca.edu.ec 348 | jaime.mora@ucuenca.edu.ec 349 | ismael.carpio@ucuenca.edu.ec 350 | gustavo.vimos@ucuenca.edu.ec 351 | gustavo.novillo@ucuenca.edu.ec 352 | grace.inga@ucuenca.edu.ec 353 | geovanny.sagbay@ucuenca.edu.ec 354 | geovanny.calle77@ucuenca.edu.ec 355 | galo.carrion@ucuenca.edu.ec 356 | gabriela.ruquey@ucuenca.ec 357 | gabriela.granda@ucuenca.edu.ec 358 | fausto.paccha@ucuenca.edu.ec 359 | fabiola.rodas@ucuenca.edu.ec 360 | esteban.torres@ucuenca.edu.ec 361 | esteban.orellana@ucuenca.edu.ec 362 | ernesto.santos@ucuenca.edu.ec 363 | ernesto.ortiz@ucuenca.edu.ec 364 | eliza.mosquera@ucuenca.edu.ec 365 | edwin.ramon@ucuenca.edu.ec 366 | eddie.jumbo@ucuenca.edu.ec 367 | diego.uyana@ucuenca.edu.ec 368 | diego.pacheco@ucuenca.edu.ec 369 | diego.larriva@ucuenca.edu.ec 370 | diego.carrasco@ucuenca.edu.ec 371 | david.jaramillo@ucuenca.edu.ec 372 | david.encalada@ucuenca.edu.ec 373 | dario.bueno@ucuenca.edu.ec 374 | danilo.saravia@ucuenca.edu.ec 375 | daniel.lopez@ucuenca.edu.ec 376 | daniel.collaguazo@ucuenca.edu.ec 377 | cristina.bustos@ucuenca.edu.ec 378 | cristian.vallejo@ucuenca.edu.ec 379 | consuelo.maldonado@ucuenca.edu.ec 380 | clarita.donoso@ucuenca.edu.ec 381 | cecilia.suarez@ucuenca.edu.ec 382 | carlos.pesantez@ucuenca.edu.ec 383 | carlos.freire@ucuenca.edu.ec 384 | blasco.moscoso@ucuenca.edu.ec 385 | bernardo.vega@ucuenca.edu.ec 386 | belen.pacheco@ucuenca.edu.ec 387 | 388 | @[departamento] 389 | Redes 390 | Desarrollo 391 | Helpdesk 392 | Infraestructura 393 | 394 | @[entorno] 395 | desarrollo 396 | pruebas 397 | produccion 398 | 399 | @[ram] 400 | 8 401 | 16 402 | 32 403 | 64 404 | 128 405 | 406 | ~[ram_suffix] 407 | @[ram] GB de ram 408 | @[ram] GB en RAM 409 | @[ram] GB de capacidad en RAM 410 | 411 | @[cpu_cores] 412 | 1 413 | 2 414 | 3 415 | 4 416 | 8 417 | 418 | ~[cpu_cores_suffix] 419 | @[cpu_cores] nucleos 420 | @[cpu_cores] procesadores 421 | @[cpu_cores] nucleos de cpu 422 | 423 | @[disk_space] 424 | 8 425 | 16 426 | 128 427 | 256 428 | 512 429 | 1000 430 | 431 | ~[disk_space_suffix] 432 | @[disk_space] GB de disco duro 433 | @[disk_space] GB de capacidad 434 | @[disk_space] GB de HD 435 | 436 | ~[escalabilidad] 437 | escalabilidad horizontal 438 | escalabilidad vertical 439 | -------------------------------------------------------------------------------- /data_bk/stories.md: -------------------------------------------------------------------------------- 1 | ## out of scope path 2 | * out_of_scope 3 | - utter_out_of_scope 4 | 5 | ## help 6 | * help 7 | - utter_help 8 | 9 | ## thank 10 | * thank 11 | - utter_welcome 12 | 13 | ## happy path 14 | * greet 15 | - utter_greet 16 | - utter_help 17 | 18 | ## say goodbye 19 | * goodbye 20 | - utter_goodbye 21 | 22 | ## bot challenge 23 | * bot_challenge 24 | - utter_iamabot 25 | 26 | 27 | ## incident form 28 | * open_incident OR password_reset OR problem_email 29 | - open_incident_form 30 | - form{"name": "open_incident_form"} 31 | - form{"name": null} 32 | 33 | ## incident form interrupted 34 | * open_incident OR password_reset OR problem_email 35 | - open_incident_form 36 | - form{"name":"open_incident_form"} 37 | * help 38 | - utter_help 39 | - open_incident_form 40 | - form{"name":null} 41 | 42 | ## incident form interrupted 43 | * open_incident OR password_reset OR problem_email 44 | - open_incident_form 45 | - form{"name":"open_incident_form"} 46 | * out_of_scope 47 | - utter_out_of_scope 48 | - open_incident_form 49 | - form{"name":null} -------------------------------------------------------------------------------- /data_bk/test/nlu.md: -------------------------------------------------------------------------------- 1 | ## intent:agradecimiento 2 | - muchas gracias 3 | - gracias 4 | - gracias gracias 5 | 6 | ## intent:cancelar 7 | - cancela 8 | - denegado 9 | - parar 10 | 11 | ## intent:chitchat 12 | - quien eres? 13 | - quien es tu creador? 14 | - estas bien? 15 | - esta haciendo frio? 16 | - feliz dia 17 | - eres inutil 18 | - no sirves 19 | - eres un robot? 20 | 21 | ## intent:confirmar 22 | - ok 23 | - confirma 24 | - acepta 25 | - confirmado 26 | - okay 27 | - confirmar 28 | 29 | ## intent:correo_electronico 30 | - mi correo [cecilia.achig@ucuenca.edu.ec](email) 31 | - electronico [eliza.mosquera@ucuenca.edu.ec](email) 32 | - [mariaeugenia.fajardo@ucuenca.edu.ec](email) 33 | - [mjose.zunigaz@ucuenca.edu.ec](email) 34 | - mi correo electronico [diego.jaramillo@ucuenca.edu.ec](email) 35 | - mi correo electronico [juan.panora@ucuenca.edu.ec](email) 36 | - mi correo electronico [jose.urgiles@ucuenca.edu.ec](email) 37 | - mi correo [mariajose.torres@ucuenca.edu.ec](email) 38 | - electronico [jose.urgiles@ucuenca.edu.ec](email) 39 | - electronico [edison.sinchit@ucuenca.edu.ec](email) 40 | - mi correo electronico [patricio.juca@ucuenca.edu.ec](email) 41 | - [julia.tamayo@ucuenca.edu.ec](email) 42 | - [farah.alvarado@ucuenca.edu.ec](email) 43 | - mi correo electronico [nelson.ortegac11@ucuenca.edu.ec](email) 44 | - mi correo electronico [luis.crespo@ucuenca.edu.ec](email) 45 | - [ricardo.merchan@ucuenca.edu.ec](email) 46 | - [javier.saltos@ucuenca.edu.ec](email) 47 | - mi correo electronico [patricia.garces@ucuenca.edu.ec](email) 48 | - electronico [monica.gonzalez@ucuenca.edu.ec](email) 49 | - [augusta.hermida@ucuenca.edu.ec](email) 50 | - mi correo [enrique.flores@ucuenca.edu.ec](email) 51 | - mi correo electronico [pablo.palacios@ucuenca.edu.ec](email) 52 | - [rosa.dominguez@ucuenca.edu.ec](email) 53 | - electronico [sebastian.martinez@ucuenca.edu.ec](email) 54 | - [victor.gonzalez@ucuenca.edu.ec](email) 55 | - mi correo electronico [karla.ortega@ucuenca.edu.ec](email) 56 | - mi correo electronico [hernan.gonzalez@ucuenca.edu.ec](email) 57 | - [ernesto.ortiz@ucuenca.edu.ec](email) 58 | - [danilo.saravia@ucuenca.edu.ec](email) 59 | - mi correo electronico [vanessa.guillen@ucuenca.edu.ec](email) 60 | - mi correo electronico [carlos.freire@ucuenca.edu.ec](email) 61 | - [galo.carrion@ucuenca.edu.ec](email) 62 | - electronico [bernardo.vega@ucuenca.edu.ec](email) 63 | - [jorge.tenesaca@ucuenca.edu.ec](email) 64 | - mi correo electronico [elias.mora@ucuenca.edu.ec](email) 65 | - electronico [andrea.ariasv@ucuenca.edu.ec](email) 66 | - mi correo electronico [andrea.loja@ucuenca.edu.ec](email) 67 | - [nube.mendez@ucuenca.edu.ec](email) 68 | - mi correo [juan.panora@ucuenca.edu.ec](email) 69 | - mi correo electronico [juan.fajardo@ucuenca.edu.ec](email) 70 | - [javier.duran@ucuenca.edu.ec](email) 71 | - mi correo [danilo.saravia@ucuenca.edu.ec](email) 72 | - [edwin.ramon@ucuenca.edu.ec](email) 73 | - mi correo [rene.martinez@ucuenca.edu.ec](email) 74 | - [daniel.collaguazo@ucuenca.edu.ec](email) 75 | - mi correo [nube.mendez@ucuenca.edu.ec](email) 76 | - [christopher.morochov@ucuenca.edu.ec](email) 77 | - mi correo electronico [jaime.mora@ucuenca.edu.ec](email) 78 | - [daniel.lopez@ucuenca.edu.ec](email) 79 | - [daniel.samaniego@ucuenca.edu.ec](email) 80 | - [diego.larriva@ucuenca.edu.ec](email) 81 | - [jose.urgiles@ucuenca.edu.ec](email) 82 | - mi correo [santiago.ulloa@ucuenca.edu.ec](email) 83 | - [hernan.gonzalez@ucuenca.edu.ec](email) 84 | - electronico [jorge.ortega@ucuenca.edu.ec](email) 85 | - mi correo [fausto.cardoso@ucuenca.edu.ec](email) 86 | - electronico [jackeline.bermeo@ucuenca.edu.ec](email) 87 | - electronico [jenny.luna@ucuenca.edu.ec](email) 88 | - mi correo electronico [gustavo.novillo@ucuenca.edu.ec](email) 89 | - mi correo electronico [jonathan.ruiz@ucuenca.edu.ec](email) 90 | 91 | ## intent:creacion_usuarios 92 | - hola solicito creacion de cuenta [Quipux](sistema) para [Director](trato) [Coordinador Vinculacion Sociedad](PER) 93 | - creacion de cuenta [GLPI](sistema) [Secretaria Abogada](trato) [Cuenca Ciudad Universitaria](PER) [Facultad Medicina](facultad) 94 | - hola solicito acceso al sistema [Quipux](sistema) para [Lcda](trato) [Juan Perez](PER) [Ingenieria](facultad) 95 | - crear usuario y asignar roles [GLPI](sistema) para [Dr](trato) [Juan Perez](PER) [Facultad Psicologia](facultad) 96 | - solicito acceso al sistema para [Estudiante](trato) [Juan Perez](PER) [Facultad Psicologia](facultad) 97 | - buenas tardes acceso a para [Sra](trato) [Marcelo Dosantos](PER) [Sistemas](facultad) 98 | - buenas tardes requiero crear nuevo usuario [Quipux](sistema) [Director](trato) [Marcelo Dosantos](PER) [Electrica](facultad) 99 | - hola requiero registrar personal para [Sr](trato) [Karina Sarmiento](PER) [Electronica](facultad) 100 | - hola creacion de cuenta de usuario para [Ing](trato) [Joselito Juanete](PER) [Ing](facultad) 101 | - buenos dias solicito creacion de cuenta [GLPI](sistema) [Dr](trato) [Cuenca Ciudad Universitaria](PER) [Facultad Hospitalidad](facultad) 102 | - saludos registrar personal [Urkund](sistema) para [Sra](trato) [Santiago](PER) [Facultad Ingenieria](facultad) 103 | - buenas tardes solicito creacion de cuenta de usuario para [Estudiante](trato) [Oscar Malgiaritta](PER) [Ing](facultad) 104 | - requiero registrar personal [Karina Sarmiento](PER) [Civil](facultad) 105 | - buenos dias necesito crear usuario y asignar roles [Sr](trato) [Juan Perez](PER) [Facultad Ingenieria](facultad) 106 | - buenas tardes acceso a [GLPI](sistema) para [Lcdo](trato) [Oscar Malgiaritta](PER) 107 | - buenas tardes solicito registrar personal [GLPI](sistema) [Ing](trato) [Jenny Maricela Redrovan Macas](PER) [Ing](facultad) 108 | - buenas tardes requiero creacion de usuario [Juan Perez](PER) [Facultad Medicina](facultad) 109 | - buenas tardes requiero registrar personal [eVirtual](sistema) [Secretaria Abogada](trato) [Karina Sarmiento](PER) [Facultad Hospitalidad](facultad) 110 | - buenos dias necesito registrar personal [Lcdo](trato) [Oscar Malgiaritta](PER) [Ing](facultad) 111 | - buenos dias registrar personal [Dr](trato) [Santiago](PER) [Facultad Ingenieria](facultad) 112 | 113 | ## intent:despedida 114 | - hasta luego 115 | - termina 116 | - terminar 117 | - acabar sesion 118 | 119 | ## intent:especifica_sistema 120 | - [OpenERP](sistema) 121 | - [GLPI](sistema) 122 | - el [GLPI](sistema) 123 | 124 | ## intent:informacion 125 | - [128](disk_space) GB de disco duro 126 | - requiero [3](cpu_cores) nucleos 127 | - necesito [4](cpu_cores) nucleos de cpu 128 | - necesito [1](cpu_cores) nucleos 129 | - [1](cpu_cores) nucleos de cpu 130 | - solicito [1](cpu_cores) nucleos de cpu 131 | - [8](ram) GB de capacidad en RAM 132 | - ambiente de [produccion](entorno) 133 | - necesito [128](disk_space) GB de capacidad 134 | - [2](cpu_cores) procesadores 135 | - solicito [3](cpu_cores) procesadores 136 | - [4](cpu_cores) procesadores 137 | - requiero escalabilidad horizontal 138 | - [1000](disk_space) GB de HD 139 | - [8](ram) GB en RAM 140 | - [1](cpu_cores) procesadores 141 | - necesito [8](cpu_cores) nucleos 142 | - requiero [512](disk_space) GB de HD 143 | - necesito [8](ram) GB de ram 144 | - requiero [32](ram) GB de capacidad en RAM 145 | 146 | ## intent:nombre 147 | - [Jenny Maricela Redrovan Macas](PER) 148 | - Soy [Jenny Maricela Redrovan Macas](PER) 149 | - Mi nombre es [Karina Sarmiento](PER) 150 | - Me llamo [Karina Sarmiento](PER) 151 | - Mi nombre es [Juan Perez](PER) 152 | - Mi nombre es [Joselito Juanete](PER) 153 | - Me llamo [Santiago](PER) 154 | - [Cecilia](PER) 155 | 156 | ## intent:peticion_recurso_computacional 157 | - necesito acceso a una maquina [2](cpu_cores) nucleos de cpu [256](disk_space) GB de HD 158 | - solicito una VM [8](ram) GB de capacidad en RAM [8](cpu_cores) nucleos [128](disk_space) GB de HD 159 | - una VM [4](cpu_cores) nucleos de cpu [8](disk_space) GB de capacidad 160 | - necesito maquina virtual [1](cpu_cores) procesadores 161 | - solicito una VM [16](ram) GB en RAM [3](cpu_cores) procesadores 162 | - necesito un servidor [32](ram) GB de ram [8](cpu_cores) procesadores [128](disk_space) GB de disco duro 163 | - solicito una VM [8](ram) GB de capacidad en RAM [1](cpu_cores) nucleos [256](disk_space) GB de disco duro 164 | - necesito una VM [4](cpu_cores) nucleos de cpu [256](disk_space) GB de HD 165 | - necesito acceso a una maquina [128](ram) GB de ram [2](cpu_cores) nucleos [128](disk_space) GB de capacidad 166 | - maquina virtual [8](ram) GB en RAM [3](cpu_cores) nucleos de cpu [16](disk_space) GB de HD 167 | - acceso a una maquina [3](cpu_cores) procesadores [1000](disk_space) GB de HD 168 | - una instancia [1](cpu_cores) nucleos [512](disk_space) GB de capacidad 169 | - acceso a una maquina [128](ram) GB de capacidad en RAM [4](cpu_cores) procesadores [16](disk_space) GB de disco duro 170 | - requiero un servidor [8](ram) GB de capacidad en RAM [3](cpu_cores) nucleos [8](disk_space) GB de disco duro 171 | - una VM [8](cpu_cores) nucleos de cpu [1000](disk_space) GB de capacidad 172 | - una VM [8](cpu_cores) procesadores [16](disk_space) GB de disco duro 173 | - una VM [128](ram) GB en RAM [3](cpu_cores) nucleos [16](disk_space) GB de HD 174 | - maquina virtual [128](ram) GB en RAM [256](disk_space) GB de disco duro 175 | - necesito acceso a una maquina [64](ram) GB de ram [3](cpu_cores) procesadores 176 | - solicito acceso a una maquina [32](ram) GB en RAM [3](cpu_cores) procesadores [128](disk_space) GB de capacidad 177 | 178 | ## intent:recuperar_contrasena 179 | - saludos requiero no puedo acceder [Portafolio](sistema) 180 | - buenas tardes olvide contrasena [Portafolio](sistema) 181 | - saludos solicito No hay acceso [eVirtual](sistema) 182 | - buenos dias no recuerda contrasena [Portafolio](sistema) 183 | - hola no recuerda contrasena [eVirtual](sistema) 184 | - buenos dias solicito Sin acceso [Portafolio](sistema) 185 | - buenas tardes requiero no puedo acceder [Portafolio](sistema) 186 | - buenos dias necesito No hay acceso [Urkund](sistema) 187 | - buenas tardes necesito no recuerda contrasena [Portafolio](sistema) 188 | - buenas tardes requiero olvide contrasena [Urkund](sistema) 189 | - buenos dias solicito no recuerda contrasena [Portafolio](sistema) 190 | - necesito Sin acceso [Portafolio](sistema) 191 | - requiero no puedo acceder [Portafolio](sistema) 192 | - hola solicito Sin acceso [GLPI](sistema) 193 | - hola necesito no recuerda contrasena [Portafolio](sistema) 194 | - requiero Sin acceso [OpenERP](sistema) 195 | - solicito no puedo acceder [OpenERP](sistema) 196 | - hola solicito olvide contrasena [Portafolio](sistema) 197 | - saludos solicito Sin acceso [Quipux](sistema) 198 | - buenos dias no puedo acceder [Portafolio](sistema) 199 | 200 | ## intent:saludo 201 | - hola 202 | - buenos dias 203 | - hola buenas tardes 204 | 205 | ## intent:solicitar_opciones 206 | - ayuda 207 | - opciones disponibles 208 | - mostrar opciones 209 | -------------------------------------------------------------------------------- /data_bk/test/nlu_extras.md: -------------------------------------------------------------------------------- 1 | ## lookup:sistema 2 | data/train/sistemas-dtic.txt -------------------------------------------------------------------------------- /data_bk/test/stories.md: -------------------------------------------------------------------------------- 1 | ## story_saludo 2 | * saludo 3 | - utter_intro 4 | * nombre{"sujeto": "Santiago Gonzalez"} 5 | - utter_saludo 6 | - utter_sugerencias 7 | 8 | ## story_opciones 9 | * solicitar_opciones 10 | - utter_sugerencias 11 | 12 | ## story_despedida 13 | * despedida 14 | - utter_despedida 15 | 16 | ## story_agradecimiento 17 | * agradecimiento 18 | - utter_gracias 19 | - utter_mas_ayuda 20 | 21 | ## story_finaliza_sesion 22 | * agradecimiento 23 | - utter_gracias 24 | - utter_mas_ayuda 25 | * despedida 26 | - utter_despedida 27 | - action_restart 28 | 29 | ## story_nombre 30 | * nombre{"sujeto": "Santiago Gonzalez"} 31 | - utter_saludo 32 | - utter_sugerencias 33 | 34 | ## story_chitchat 35 | * chitchat 36 | - utter_chitchat 37 | - utter_sugerencias 38 | 39 | ## story_creacion_usuario 40 | * creacion_usuarios 41 | - action_joke 42 | - utter_mas_ayuda 43 | 44 | ## story_recuperar_contrasena 45 | * recuperar_contrasena 46 | - utter_email 47 | * correo_electronico 48 | - utter_sistema 49 | * especifica_sistema 50 | - utter_confirma_sistema 51 | * confirmar 52 | - utter_contrasena 53 | - utter_confirmar_atencion 54 | - slot {"email": null} 55 | - slot {"sistema": null} 56 | - utter_mas_ayuda 57 | 58 | ## story_recuperar_contrasena_unhappy_path_cancel_and_confirm 59 | * recuperar_contrasena 60 | - utter_email 61 | * correo_electronico 62 | - utter_sistema 63 | * especifica_sistema 64 | - utter_confirma_sistema 65 | * cancelar 66 | - utter_continuar 67 | * cancelar 68 | - utter_cancelado 69 | - slot {"email": null} 70 | - slot {"sistema": null} 71 | - utter_mas_ayuda 72 | 73 | ## story_recuperar_contrasena_unhappy_path_cancel_but_continue 74 | * recuperar_contrasena 75 | - utter_email 76 | * correo_electronico 77 | - utter_sistema 78 | * especifica_sistema 79 | - utter_confirma_sistema 80 | * cancelar 81 | - utter_continuar 82 | * confirmar 83 | - utter_contrasena 84 | - utter_confirmar_atencion 85 | - slot {"email": null} 86 | - slot {"sistema": null} 87 | - utter_mas_ayuda 88 | 89 | ## story_requerimiento_recurso_computacional_happy_path 90 | * peticion_recurso_computacional 91 | - compute_resource_form 92 | - form {"name": "compute_resource_form"} 93 | - form {"name": null} 94 | - utter_compute_form_values 95 | * confirmar 96 | - utter_enviar_ticket_no 97 | - slot {"ticket_no": "0055"} 98 | - utter_confirmar_solicitud 99 | - utter_mas_ayuda 100 | 101 | ## story_requerimiento_recurso_computacional_unhappy_path_1 102 | * peticion_recurso_computacional 103 | - compute_resource_form 104 | - form {"name": "compute_resource_form"} 105 | * chitchat 106 | - utter_chitchat 107 | - compute_resource_form 108 | - form {"name": null} 109 | - utter_compute_form_values 110 | * confirmar 111 | - utter_enviar_ticket_no 112 | - slot {"ticket_no": "0055"} 113 | - utter_confirmar_solicitud 114 | - utter_mas_ayuda 115 | 116 | ## story_requerimiento_recurso_computacional_unhappy_path_2 117 | * peticion_recurso_computacional 118 | - compute_resource_form 119 | - form {"name": "compute_resource_form"} 120 | * chitchat 121 | - utter_chitchat 122 | - compute_resource_form 123 | * chitchat 124 | - utter_chitchat 125 | - compute_resource_form 126 | * chitchat 127 | - utter_chitchat 128 | - compute_resource_form 129 | - form {"name": null} 130 | - utter_compute_form_values 131 | * confirmar 132 | - utter_enviar_ticket_no 133 | - slot {"ticket_no": "0055"} 134 | - utter_confirmar_solicitud 135 | - utter_mas_ayuda 136 | 137 | ## story_requerimiento_recurso_computacional_stop_but_continue 138 | * peticion_recurso_computacional 139 | - compute_resource_form 140 | - form {"name": "compute_resource_form"} 141 | * cancelar 142 | - utter_continuar 143 | * confirmar 144 | - compute_resource_form 145 | - form {"name": null} 146 | - utter_compute_form_values 147 | * confirmar 148 | - utter_enviar_ticket_no 149 | - slot {"ticket_no": "0055"} 150 | - utter_confirmar_solicitud 151 | - utter_mas_ayuda 152 | 153 | ## story_requerimiento_recurso_computacional_stop_and_confirm 154 | * peticion_recurso_computacional 155 | - compute_resource_form 156 | - form {"name": "compute_resource_form"} 157 | * cancelar 158 | - utter_continuar 159 | * cancelar 160 | - action_deactivate_form 161 | - form {"name": null} 162 | - utter_cancelado 163 | - utter_mas_ayuda -------------------------------------------------------------------------------- /data_bk/train/nlu_extras.md: -------------------------------------------------------------------------------- 1 | ## lookup:sistema 2 | data/train/sistemas-dtic.txt -------------------------------------------------------------------------------- /data_bk/train/sistemas-dtic.txt: -------------------------------------------------------------------------------- 1 | Urkund 2 | Sistemas Institucionales 3 | Portafolio 4 | Quipux 5 | eVirtual 6 | OpenERP 7 | GLPI 8 | SIUC 9 | Koha 10 | SCGI -------------------------------------------------------------------------------- /data_bk/train/stories.md: -------------------------------------------------------------------------------- 1 | ## story_saludo_inicial 2 | * saludo 3 | - action_validate_auth 4 | - slot{"logged_in": false} 5 | 6 | ## story_saludo 7 | * saludo 8 | - action_validate_auth 9 | - slot{"logged_in": true} 10 | - utter_intro 11 | * nombre{"sujeto": "Santiago Gonzalez"} 12 | - utter_saludo 13 | - utter_sugerencias 14 | 15 | ## story_finaliza_sesion 16 | > check_mas_ayuda 17 | * despedida 18 | - utter_despedida 19 | - action_restart 20 | 21 | ## story_opciones 22 | > check_mas_ayuda 23 | * solicitar_opciones 24 | - utter_sugerencias 25 | 26 | ## story_despedida 27 | * despedida 28 | - utter_despedida 29 | 30 | ## story_agradecimiento 31 | * agradecimiento 32 | - utter_gracias 33 | - utter_mas_ayuda 34 | > check_mas_ayuda 35 | 36 | ## story_nombre 37 | * nombre{"sujeto": "Santiago Gonzalez"} 38 | - utter_saludo 39 | - utter_sugerencias 40 | 41 | ## story_chitchat 42 | * chitchat 43 | - utter_chitchat 44 | - utter_sugerencias 45 | 46 | ## story_creacion_usuario 47 | >check_ask_sugerencias 48 | * creacion_usuarios 49 | - action_joke 50 | - utter_mas_ayuda 51 | > check_mas_ayuda 52 | 53 | ## story_recuperar_contrasena 54 | * recuperar_contrasena 55 | - utter_email 56 | * correo_electronico 57 | - utter_sistema 58 | * especifica_sistema 59 | - utter_confirma_sistema 60 | * confirmar 61 | - utter_contrasena 62 | - utter_confirmar_atencion 63 | - slot {"email": null} 64 | - slot {"sistema": null} 65 | - utter_mas_ayuda 66 | > check_mas_ayuda 67 | 68 | ## story_recuperar_contrasena_unhappy_path_cancel_and_confirm 69 | * recuperar_contrasena 70 | - utter_email 71 | * correo_electronico 72 | - utter_sistema 73 | * especifica_sistema 74 | - utter_confirma_sistema 75 | * cancelar 76 | - utter_continuar 77 | * cancelar 78 | - utter_cancelado 79 | - slot {"email": null} 80 | - slot {"sistema": null} 81 | - utter_mas_ayuda 82 | > check_mas_ayuda 83 | 84 | ## story_recuperar_contrasena_unhappy_path_cancel_but_continue 85 | * recuperar_contrasena 86 | - utter_email 87 | * correo_electronico 88 | - utter_sistema 89 | * especifica_sistema 90 | - utter_confirma_sistema 91 | * cancelar 92 | - utter_continuar 93 | * confirmar 94 | - utter_contrasena 95 | - utter_confirmar_atencion 96 | - slot {"email": null} 97 | - slot {"sistema": null} 98 | - utter_mas_ayuda 99 | > check_mas_ayuda 100 | 101 | ## story_requerimiento_recurso_computacional_happy_path 102 | * peticion_recurso_computacional 103 | - compute_resource_form 104 | - form {"name": "compute_resource_form"} 105 | - form {"name": null} 106 | - utter_compute_form_values 107 | * confirmar 108 | - utter_enviar_ticket_no 109 | - slot {"ticket_no": "0055"} 110 | - utter_confirmar_solicitud 111 | - utter_mas_ayuda 112 | > check_mas_ayuda 113 | 114 | ## story_requerimiento_recurso_computacional_unhappy_path_1 115 | * peticion_recurso_computacional 116 | - compute_resource_form 117 | - form {"name": "compute_resource_form"} 118 | * chitchat 119 | - utter_chitchat 120 | - compute_resource_form 121 | - form {"name": null} 122 | - utter_compute_form_values 123 | * confirmar 124 | - utter_enviar_ticket_no 125 | - slot {"ticket_no": "0055"} 126 | - utter_confirmar_solicitud 127 | - utter_mas_ayuda 128 | > check_mas_ayuda 129 | 130 | ## story_requerimiento_recurso_computacional_unhappy_path_2 131 | * peticion_recurso_computacional 132 | - compute_resource_form 133 | - form {"name": "compute_resource_form"} 134 | * chitchat 135 | - utter_chitchat 136 | - compute_resource_form 137 | * chitchat 138 | - utter_chitchat 139 | - compute_resource_form 140 | * chitchat 141 | - utter_chitchat 142 | - compute_resource_form 143 | - form {"name": null} 144 | - utter_compute_form_values 145 | * confirmar 146 | - utter_enviar_ticket_no 147 | - slot {"ticket_no": "0055"} 148 | - utter_confirmar_solicitud 149 | - utter_mas_ayuda 150 | > check_mas_ayuda 151 | 152 | ## story_requerimiento_recurso_computacional_stop_but_continue 153 | * peticion_recurso_computacional 154 | - compute_resource_form 155 | - form {"name": "compute_resource_form"} 156 | * cancelar 157 | - utter_continuar 158 | * confirmar 159 | - compute_resource_form 160 | - form {"name": null} 161 | - utter_compute_form_values 162 | * confirmar 163 | - utter_enviar_ticket_no 164 | - slot {"ticket_no": "0055"} 165 | - utter_confirmar_solicitud 166 | - utter_mas_ayuda 167 | > check_mas_ayuda 168 | 169 | ## story_requerimiento_recurso_computacional_stop_and_confirm 170 | * peticion_recurso_computacional 171 | - compute_resource_form 172 | - form {"name": "compute_resource_form"} 173 | * cancelar 174 | - utter_continuar 175 | * cancelar 176 | - action_deactivate_form 177 | - form {"name": null} 178 | - utter_cancelado 179 | - utter_mas_ayuda 180 | > check_mas_ayuda 181 | -------------------------------------------------------------------------------- /docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | app: 5 | image: 'santteegt/glpi-chatbot-actions:latest' 6 | expose: 7 | - '5055' 8 | environment: 9 | GLPI_API_URI: "${GLPI_API_URI}" 10 | GLPI_APP_TOKEN: "${GLPI_APP_TOKEN}" 11 | GLPI_AUTH_TOKEN: "${GLPI_AUTH_TOKEN}" 12 | GLPI_LOCALMODE: "${GLPI_LOCALMODE}" 13 | depends_on: 14 | - rasa-production 15 | extra_hosts: 16 | - "srvpruebas.ucuenca.edu.ec:172.16.0.44" -------------------------------------------------------------------------------- /endpoints.yml: -------------------------------------------------------------------------------- 1 | # This file contains the different endpoints your bot can use. 2 | 3 | # Server where the models are pulled from. 4 | # https://rasa.com/docs/rasa/user-guide/running-the-server/#fetching-models-from-a-server/ 5 | 6 | #models: 7 | # url: http://my-server.com/models/default_core@latest 8 | # wait_time_between_pulls: 10 # [optional](default: 100) 9 | 10 | # Server which runs your custom actions. 11 | # https://rasa.com/docs/rasa/core/actions/#custom-actions/ 12 | 13 | action_endpoint: 14 | url: "http://localhost:5055/webhook" 15 | 16 | # Tracker store which is used to store the conversations. 17 | # By default the conversations are stored in memory. 18 | # https://rasa.com/docs/rasa/api/tracker-stores/ 19 | 20 | #tracker_store: 21 | # type: redis 22 | # url: 23 | # port: 24 | # db: 25 | # password: 26 | # use_ssl: 27 | 28 | #tracker_store: 29 | # type: mongod 30 | # url: 31 | # db: 32 | # username: 33 | # password: 34 | 35 | # Event broker which all conversation events should be streamed to. 36 | # https://rasa.com/docs/rasa/api/event-brokers/ 37 | 38 | #event_broker: 39 | # url: localhost 40 | # username: username 41 | # password: password 42 | # queue: queue -------------------------------------------------------------------------------- /format_results.py: -------------------------------------------------------------------------------- 1 | from pytablewriter import MarkdownTableWriter 2 | import json 3 | 4 | 5 | def intent_table(): 6 | writer = MarkdownTableWriter() 7 | writer.table_name = "Intent Cross-Validation Results (5 folds)" 8 | 9 | with open('results/intent_report.json', 'r') as f: 10 | data = json.loads(f.read()) 11 | 12 | cols = ["support", "f1-score", "confused_with"] 13 | writer.headers = ["class"] + cols 14 | 15 | classes = list(data.keys()) 16 | classes.remove('accuracy') 17 | classes.sort(key = lambda x: data[x]['support'], reverse=True) 18 | 19 | def format_cell(data, c, k): 20 | if not data[c].get(k): 21 | return "N/A" 22 | if k == "confused_with": 23 | return ", ".join([f"{k}({v})" for k,v in data[c][k].items()]) 24 | else: 25 | return data[c][k] 26 | 27 | writer.value_matrix = [ 28 | [c] + [format_cell(data, c, k) for k in cols] 29 | for c in classes 30 | ] 31 | 32 | return writer.dumps() 33 | 34 | 35 | def entity_table(): 36 | 37 | writer = MarkdownTableWriter() 38 | writer.table_name = "Entity Cross-Validation Results (5 folds)" 39 | 40 | with open('results/DIETClassifier_report.json', 'r') as f: 41 | data = json.loads(f.read()) 42 | 43 | cols = ["support", "f1-score", "precision", "recall"] 44 | writer.headers = ["entity"] + cols 45 | 46 | classes = list(data.keys()) 47 | classes.sort(key = lambda x: data[x]['support'], reverse=True) 48 | 49 | def format_cell(data, c, k): 50 | if not data[c].get(k): 51 | return "N/A" 52 | else: 53 | return data[c][k] 54 | 55 | writer.value_matrix = [ 56 | [c] + [format_cell(data, c, k) for k in cols] 57 | for c in classes 58 | ] 59 | 60 | return writer.dumps() 61 | 62 | 63 | intents = intent_table() 64 | entities = entity_table() 65 | 66 | with open('results.md', 'w') as f: 67 | f.write(intents) 68 | f.write("\n\n\n") 69 | f.write(entities) 70 | -------------------------------------------------------------------------------- /glpi_credentials.yml: -------------------------------------------------------------------------------- 1 | uri: http://localhost:9000/apirest.php 2 | auth_token: LY6Q3x8GRrGvcqLgJs9Onzipjn5FZghFVKNsoKYU 3 | app_token: jH8hfBdtpFCpraY6xZQAz9XaXO3G04XXGCTImWX9 4 | localmode: false -------------------------------------------------------------------------------- /rasa-stack-mockup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santteegt/glpi_chatbot/5685d12216fa4c0f790ca9b85c7320a66d5ba8be/rasa-stack-mockup.gif -------------------------------------------------------------------------------- /requirements-actions.txt: -------------------------------------------------------------------------------- 1 | pytablewriter 2 | requests 3 | ruamel.yaml 4 | glpi==0.4.0 5 | future 6 | typing-extensions -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | 3 | # lint/format/types 4 | black==19.10b0 5 | flake8==3.7.8 6 | pytype==2019.7.11 -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | rasa[spacy]~=1.10.0 2 | rasa-sdk~=1.10.0 3 | -r requirements-actions.txt 4 | -------------------------------------------------------------------------------- /results.md: -------------------------------------------------------------------------------- 1 | # Intent Cross-Validation Results (5 folds) 2 | | class |support|f1-score| confused_with | 3 | |-------------------------|------:|-------:|---------------------------------------| 4 | |macro avg | 253| 0.8023|N/A | 5 | |weighted avg | 253| 0.8019|N/A | 6 | |inform | 56| 0.8155|request_vm(4), connect_wifi(4) | 7 | |get_incident_status | 18| 0.8500|open_incident(1) | 8 | |password_reset | 15| 0.9677|N/A | 9 | |out_of_scope | 15| 0.6875|problem_email(2), password_reset(1) | 10 | |problem_email | 13| 0.8966|N/A | 11 | |goodbye | 13| 0.7500|help(1), confirm(1) | 12 | |confirm | 13| 0.7586|thank(1), out_of_scope(1) | 13 | |open_incident | 12| 0.8800|help(1) | 14 | |deny | 12| 0.6000|thank(1), confirm(1) | 15 | |greet | 12| 0.7368|confirm(2), help(1) | 16 | |help | 11| 0.6667|out_of_scope(1), confirm(1) | 17 | |connect_wifi | 11| 0.8462|N/A | 18 | |request_vm | 10| 0.5263|inform(4), request_biometrics_report(1)| 19 | |create_user | 10| 0.9474|get_incident_status(1) | 20 | |request_biometrics_report| 10| 0.8696|N/A | 21 | |thank | 8| 0.8421|N/A | 22 | |bot_challenge | 8| 0.8000|out_of_scope(2) | 23 | |show_menu | 6| 1.0000|N/A | 24 | 25 | 26 | 27 | # Entity Cross-Validation Results (5 folds) 28 | | entity |support|f1-score|precision|recall| 29 | |--------------|------:|--------|---------|------| 30 | |micro avg | 69| 0.7692| 0.8197|0.7246| 31 | |macro avg | 69| 0.6927| 0.7587|0.6538| 32 | |weighted avg | 69| 0.7658| 0.8291|0.7246| 33 | |course_type | 10| 0.8421| 0.8889|0.8000| 34 | |priority | 10| 0.8889| 1|0.8000| 35 | |vm_environment| 9| 0.8750| 1|0.7778| 36 | |wifi_network | 8| 0.9333| 1|0.8750| 37 | |vm_cpu_cores | 7| 0.5714| 0.5714|0.5714| 38 | |vm_disk_space | 7| 0.6250| 0.5556|0.7143| 39 | |vm_ram | 6| 0.6154| 0.5714|0.6667| 40 | |ticket_no | 6| 0.9091| 1|0.8333| 41 | |vm_scalability| 4| 0.6667| 1|0.5000| 42 | |faculty | 2|N/A |N/A |N/A | 43 | -------------------------------------------------------------------------------- /results/DIETClassifier_errors.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "text": "un seminario de emprendimiento", 4 | "entities": [ 5 | { 6 | "start": 3, 7 | "end": 12, 8 | "value": "curso", 9 | "entity": "course_type" 10 | } 11 | ], 12 | "predicted_entities": [] 13 | }, 14 | { 15 | "text": "4 nucleos", 16 | "entities": [ 17 | { 18 | "start": 0, 19 | "end": 1, 20 | "value": "4", 21 | "entity": "vm_cpu_cores" 22 | } 23 | ], 24 | "predicted_entities": [ 25 | { 26 | "entity": "vm_disk_space", 27 | "start": 0, 28 | "end": 1, 29 | "value": "4", 30 | "extractor": "DIETClassifier" 31 | } 32 | ] 33 | }, 34 | { 35 | "text": "muy urgente", 36 | "entities": [ 37 | { 38 | "start": 0, 39 | "end": 11, 40 | "value": "alta", 41 | "entity": "priority" 42 | } 43 | ], 44 | "predicted_entities": [ 45 | { 46 | "entity": "priority", 47 | "start": 4, 48 | "end": 11, 49 | "value": "alta", 50 | "extractor": "DIETClassifier", 51 | "processors": [ 52 | "EntitySynonymMapper" 53 | ] 54 | } 55 | ] 56 | }, 57 | { 58 | "text": "carrera universitaria", 59 | "entities": [ 60 | { 61 | "start": 0, 62 | "end": 7, 63 | "value": "carrera", 64 | "entity": "course_type" 65 | } 66 | ], 67 | "predicted_entities": [ 68 | { 69 | "entity": "course_type", 70 | "start": 0, 71 | "end": 21, 72 | "value": "carrera universitaria", 73 | "extractor": "DIETClassifier" 74 | } 75 | ] 76 | }, 77 | { 78 | "text": "una charla técnica", 79 | "entities": [ 80 | { 81 | "start": 4, 82 | "end": 10, 83 | "value": "curso", 84 | "entity": "course_type" 85 | } 86 | ], 87 | "predicted_entities": [] 88 | }, 89 | { 90 | "text": "como puedo conectarme a la red ucwifi", 91 | "entities": [ 92 | { 93 | "start": 31, 94 | "end": 37, 95 | "value": "ucwifi", 96 | "entity": "wifi_network" 97 | } 98 | ], 99 | "predicted_entities": [] 100 | }, 101 | { 102 | "text": "acceso a una maquina de 16 GB de ram 2 CPUs y 16 GB de disco", 103 | "entities": [ 104 | { 105 | "start": 24, 106 | "end": 26, 107 | "value": "16", 108 | "entity": "vm_ram" 109 | }, 110 | { 111 | "start": 37, 112 | "end": 38, 113 | "value": "2", 114 | "entity": "vm_cpu_cores" 115 | }, 116 | { 117 | "start": 46, 118 | "end": 48, 119 | "value": "16", 120 | "entity": "vm_disk_space" 121 | } 122 | ], 123 | "predicted_entities": [ 124 | { 125 | "entity": "vm_ram", 126 | "start": 24, 127 | "end": 26, 128 | "value": "16", 129 | "extractor": "DIETClassifier" 130 | }, 131 | { 132 | "entity": "vm_disk_space", 133 | "start": 37, 134 | "end": 38, 135 | "value": "2", 136 | "extractor": "DIETClassifier" 137 | }, 138 | { 139 | "entity": "vm_disk_space", 140 | "start": 46, 141 | "end": 48, 142 | "value": "16", 143 | "extractor": "DIETClassifier" 144 | } 145 | ] 146 | }, 147 | { 148 | "text": "8 GB de capacidad", 149 | "entities": [ 150 | { 151 | "start": 0, 152 | "end": 1, 153 | "value": "8", 154 | "entity": "vm_disk_space" 155 | } 156 | ], 157 | "predicted_entities": [ 158 | { 159 | "entity": "vm_ram", 160 | "start": 0, 161 | "end": 1, 162 | "value": "8", 163 | "extractor": "DIETClassifier" 164 | } 165 | ] 166 | }, 167 | { 168 | "text": "necesito escalabilidad vertical", 169 | "entities": [ 170 | { 171 | "start": 23, 172 | "end": 31, 173 | "value": "vertical", 174 | "entity": "vm_scalability" 175 | } 176 | ], 177 | "predicted_entities": [] 178 | }, 179 | { 180 | "text": "16 GB de HD", 181 | "entities": [ 182 | { 183 | "start": 0, 184 | "end": 2, 185 | "value": "16", 186 | "entity": "vm_disk_space" 187 | } 188 | ], 189 | "predicted_entities": [ 190 | { 191 | "entity": "vm_ram", 192 | "start": 0, 193 | "end": 2, 194 | "value": "16", 195 | "extractor": "DIETClassifier" 196 | } 197 | ] 198 | }, 199 | { 200 | "text": "para escalar verticalmente", 201 | "entities": [ 202 | { 203 | "start": 13, 204 | "end": 26, 205 | "value": "vertical", 206 | "entity": "vm_scalability" 207 | } 208 | ], 209 | "predicted_entities": [] 210 | }, 211 | { 212 | "text": "cual es el progreso de la incidencia 0055", 213 | "entities": [ 214 | { 215 | "start": 37, 216 | "end": 41, 217 | "value": "0055", 218 | "entity": "ticket_no" 219 | } 220 | ], 221 | "predicted_entities": [ 222 | { 223 | "entity": "vm_cpu_cores", 224 | "start": 37, 225 | "end": 41, 226 | "value": "0055", 227 | "extractor": "DIETClassifier" 228 | } 229 | ] 230 | }, 231 | { 232 | "text": "solicito una instancia para producción", 233 | "entities": [ 234 | { 235 | "start": 28, 236 | "end": 38, 237 | "value": "producción", 238 | "entity": "vm_environment" 239 | } 240 | ], 241 | "predicted_entities": [] 242 | }, 243 | { 244 | "text": "crucial", 245 | "entities": [ 246 | { 247 | "start": 0, 248 | "end": 7, 249 | "value": "alta", 250 | "entity": "priority" 251 | } 252 | ], 253 | "predicted_entities": [] 254 | }, 255 | { 256 | "text": "carrera de ingenieria", 257 | "entities": [ 258 | { 259 | "start": 0, 260 | "end": 7, 261 | "value": "carrera", 262 | "entity": "course_type" 263 | }, 264 | { 265 | "start": 11, 266 | "end": 21, 267 | "value": "ingenieria", 268 | "entity": "faculty" 269 | } 270 | ], 271 | "predicted_entities": [ 272 | { 273 | "entity": "course_type", 274 | "start": 0, 275 | "end": 7, 276 | "value": "carrera", 277 | "extractor": "DIETClassifier" 278 | } 279 | ] 280 | }, 281 | { 282 | "text": "carrera de arquitectura", 283 | "entities": [ 284 | { 285 | "start": 0, 286 | "end": 7, 287 | "value": "carrera", 288 | "entity": "course_type" 289 | }, 290 | { 291 | "start": 11, 292 | "end": 23, 293 | "value": "arquitectura", 294 | "entity": "faculty" 295 | } 296 | ], 297 | "predicted_entities": [ 298 | { 299 | "entity": "course_type", 300 | "start": 0, 301 | "end": 7, 302 | "value": "carrera", 303 | "extractor": "DIETClassifier" 304 | } 305 | ] 306 | }, 307 | { 308 | "text": "32 GB de ram", 309 | "entities": [ 310 | { 311 | "start": 0, 312 | "end": 2, 313 | "value": "32", 314 | "entity": "vm_ram" 315 | } 316 | ], 317 | "predicted_entities": [ 318 | { 319 | "entity": "vm_disk_space", 320 | "start": 0, 321 | "end": 2, 322 | "value": "32", 323 | "extractor": "DIETClassifier" 324 | } 325 | ] 326 | }, 327 | { 328 | "text": "8 GB de ram", 329 | "entities": [ 330 | { 331 | "start": 0, 332 | "end": 1, 333 | "value": "8", 334 | "entity": "vm_ram" 335 | } 336 | ], 337 | "predicted_entities": [ 338 | { 339 | "entity": "vm_disk_space", 340 | "start": 0, 341 | "end": 1, 342 | "value": "8", 343 | "extractor": "DIETClassifier" 344 | } 345 | ] 346 | }, 347 | { 348 | "text": "ambiente de producción", 349 | "entities": [ 350 | { 351 | "start": 12, 352 | "end": 22, 353 | "value": "producción", 354 | "entity": "vm_environment" 355 | } 356 | ], 357 | "predicted_entities": [] 358 | }, 359 | { 360 | "text": "cual es la raiz cuadrada de 5", 361 | "entities": [], 362 | "predicted_entities": [ 363 | { 364 | "entity": "vm_cpu_cores", 365 | "start": 28, 366 | "end": 29, 367 | "value": "5", 368 | "extractor": "DIETClassifier" 369 | } 370 | ] 371 | }, 372 | { 373 | "text": "nop", 374 | "entities": [], 375 | "predicted_entities": [ 376 | { 377 | "entity": "vm_cpu_cores", 378 | "start": 0, 379 | "end": 3, 380 | "value": "nop", 381 | "extractor": "DIETClassifier" 382 | } 383 | ] 384 | }, 385 | { 386 | "text": "solicito maquina virtual 16 GB de ram 8 nucleos de cpu", 387 | "entities": [ 388 | { 389 | "start": 25, 390 | "end": 27, 391 | "value": "16", 392 | "entity": "vm_ram" 393 | }, 394 | { 395 | "start": 38, 396 | "end": 39, 397 | "value": "8", 398 | "entity": "vm_cpu_cores" 399 | } 400 | ], 401 | "predicted_entities": [ 402 | { 403 | "entity": "vm_ram", 404 | "start": 25, 405 | "end": 27, 406 | "value": "16", 407 | "extractor": "DIETClassifier" 408 | }, 409 | { 410 | "entity": "vm_ram", 411 | "start": 38, 412 | "end": 39, 413 | "value": "8", 414 | "extractor": "DIETClassifier" 415 | } 416 | ] 417 | } 418 | ] -------------------------------------------------------------------------------- /results/DIETClassifier_report.json: -------------------------------------------------------------------------------- 1 | { 2 | "vm_environment": { 3 | "precision": 1.0, 4 | "recall": 0.7777777777777778, 5 | "f1-score": 0.8750000000000001, 6 | "support": 9 7 | }, 8 | "course_type": { 9 | "precision": 0.8888888888888888, 10 | "recall": 0.8, 11 | "f1-score": 0.8421052631578948, 12 | "support": 10 13 | }, 14 | "vm_cpu_cores": { 15 | "precision": 0.5714285714285714, 16 | "recall": 0.5714285714285714, 17 | "f1-score": 0.5714285714285714, 18 | "support": 7 19 | }, 20 | "vm_scalability": { 21 | "precision": 1.0, 22 | "recall": 0.5, 23 | "f1-score": 0.6666666666666666, 24 | "support": 4 25 | }, 26 | "wifi_network": { 27 | "precision": 1.0, 28 | "recall": 0.875, 29 | "f1-score": 0.9333333333333333, 30 | "support": 8 31 | }, 32 | "vm_disk_space": { 33 | "precision": 0.5555555555555556, 34 | "recall": 0.7142857142857143, 35 | "f1-score": 0.6250000000000001, 36 | "support": 7 37 | }, 38 | "priority": { 39 | "precision": 1.0, 40 | "recall": 0.8, 41 | "f1-score": 0.888888888888889, 42 | "support": 10 43 | }, 44 | "faculty": { 45 | "precision": 0.0, 46 | "recall": 0.0, 47 | "f1-score": 0.0, 48 | "support": 2 49 | }, 50 | "vm_ram": { 51 | "precision": 0.5714285714285714, 52 | "recall": 0.6666666666666666, 53 | "f1-score": 0.6153846153846153, 54 | "support": 6 55 | }, 56 | "ticket_no": { 57 | "precision": 1.0, 58 | "recall": 0.8333333333333334, 59 | "f1-score": 0.9090909090909091, 60 | "support": 6 61 | }, 62 | "micro avg": { 63 | "precision": 0.819672131147541, 64 | "recall": 0.7246376811594203, 65 | "f1-score": 0.7692307692307692, 66 | "support": 69 67 | }, 68 | "macro avg": { 69 | "precision": 0.7587301587301587, 70 | "recall": 0.6538492063492064, 71 | "f1-score": 0.692689824795088, 72 | "support": 69 73 | }, 74 | "weighted avg": { 75 | "precision": 0.8290775247296986, 76 | "recall": 0.7246376811594203, 77 | "f1-score": 0.765798956531222, 78 | "support": 69 79 | } 80 | } -------------------------------------------------------------------------------- /results/confmat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santteegt/glpi_chatbot/5685d12216fa4c0f790ca9b85c7320a66d5ba8be/results/confmat.png -------------------------------------------------------------------------------- /results/hist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santteegt/glpi_chatbot/5685d12216fa4c0f790ca9b85c7320a66d5ba8be/results/hist.png -------------------------------------------------------------------------------- /results/intent_errors.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "text": "buenas noches", 4 | "intent": "greet", 5 | "intent_prediction": { 6 | "name": "confirm", 7 | "confidence": 0.6752866506576538 8 | } 9 | }, 10 | { 11 | "text": "buenas", 12 | "intent": "greet", 13 | "intent_prediction": { 14 | "name": "confirm", 15 | "confidence": 0.7526236176490784 16 | } 17 | }, 18 | { 19 | "text": "Requiero su ayuda", 20 | "intent": "help", 21 | "intent_prediction": { 22 | "name": "thank", 23 | "confidence": 0.5240159630775452 24 | } 25 | }, 26 | { 27 | "text": "cual es tu nombre?", 28 | "intent": "bot_challenge", 29 | "intent_prediction": { 30 | "name": "out_of_scope", 31 | "confidence": 0.512293815612793 32 | } 33 | }, 34 | { 35 | "text": "esta bien", 36 | "intent": "confirm", 37 | "intent_prediction": { 38 | "name": "thank", 39 | "confidence": 0.38035157322883606 40 | } 41 | }, 42 | { 43 | "text": "Tengo un problema muy extraño", 44 | "intent": "open_incident", 45 | "intent_prediction": { 46 | "name": "help", 47 | "confidence": 0.28790247440338135 48 | } 49 | }, 50 | { 51 | "text": "que paso con la incidencia que reporte?", 52 | "intent": "get_incident_status", 53 | "intent_prediction": { 54 | "name": "open_incident", 55 | "confidence": 0.9825001955032349 56 | } 57 | }, 58 | { 59 | "text": "Ayuda a registrarme en el sistema", 60 | "intent": "create_user", 61 | "intent_prediction": { 62 | "name": "get_incident_status", 63 | "confidence": 0.3313119411468506 64 | } 65 | }, 66 | { 67 | "text": "requiero una VM para pruebas", 68 | "intent": "request_vm", 69 | "intent_prediction": { 70 | "name": "inform", 71 | "confidence": 0.9994385242462158 72 | } 73 | }, 74 | { 75 | "text": "mi correo es test@ucuenca.edu.ec", 76 | "intent": "inform", 77 | "intent_prediction": { 78 | "name": "problem_email", 79 | "confidence": 0.8395318984985352 80 | } 81 | }, 82 | { 83 | "text": "eduroam", 84 | "intent": "inform", 85 | "intent_prediction": { 86 | "name": "connect_wifi", 87 | "confidence": 0.35580745339393616 88 | } 89 | }, 90 | { 91 | "text": "ucwifi", 92 | "intent": "inform", 93 | "intent_prediction": { 94 | "name": "connect_wifi", 95 | "confidence": 0.7968162894248962 96 | } 97 | }, 98 | { 99 | "text": "guest", 100 | "intent": "inform", 101 | "intent_prediction": { 102 | "name": "connect_wifi", 103 | "confidence": 0.6755748391151428 104 | } 105 | }, 106 | { 107 | "text": "un seminario de emprendimiento", 108 | "intent": "inform", 109 | "intent_prediction": { 110 | "name": "get_incident_status", 111 | "confidence": 0.5126621127128601 112 | } 113 | }, 114 | { 115 | "text": "mi lavadora esta dañada", 116 | "intent": "out_of_scope", 117 | "intent_prediction": { 118 | "name": "password_reset", 119 | "confidence": 0.7873979806900024 120 | } 121 | }, 122 | { 123 | "text": "Que hay", 124 | "intent": "greet", 125 | "intent_prediction": { 126 | "name": "help", 127 | "confidence": 0.40957894921302795 128 | } 129 | }, 130 | { 131 | "text": "Necesito asistencia", 132 | "intent": "help", 133 | "intent_prediction": { 134 | "name": "get_incident_status", 135 | "confidence": 0.2421044558286667 136 | } 137 | }, 138 | { 139 | "text": "Ayuda con un problema", 140 | "intent": "help", 141 | "intent_prediction": { 142 | "name": "out_of_scope", 143 | "confidence": 0.28621774911880493 144 | } 145 | }, 146 | { 147 | "text": "no es lo que quiero", 148 | "intent": "deny", 149 | "intent_prediction": { 150 | "name": "out_of_scope", 151 | "confidence": 0.45834070444107056 152 | } 153 | }, 154 | { 155 | "text": "no soluciona", 156 | "intent": "deny", 157 | "intent_prediction": { 158 | "name": "get_incident_status", 159 | "confidence": 0.8876388669013977 160 | } 161 | }, 162 | { 163 | "text": "necesito un servidor de desarrollo", 164 | "intent": "request_vm", 165 | "intent_prediction": { 166 | "name": "inform", 167 | "confidence": 0.9999298453330994 168 | } 169 | }, 170 | { 171 | "text": "solicito 64 GB de ram", 172 | "intent": "inform", 173 | "intent_prediction": { 174 | "name": "request_vm", 175 | "confidence": 0.8683494925498962 176 | } 177 | }, 178 | { 179 | "text": "la TV no funciona", 180 | "intent": "out_of_scope", 181 | "intent_prediction": { 182 | "name": "problem_email", 183 | "confidence": 0.515669584274292 184 | } 185 | }, 186 | { 187 | "text": "saludos", 188 | "intent": "greet", 189 | "intent_prediction": { 190 | "name": "goodbye", 191 | "confidence": 0.8387770652770996 192 | } 193 | }, 194 | { 195 | "text": "fin", 196 | "intent": "goodbye", 197 | "intent_prediction": { 198 | "name": "help", 199 | "confidence": 0.3570980131626129 200 | } 201 | }, 202 | { 203 | "text": "como te llamas?", 204 | "intent": "bot_challenge", 205 | "intent_prediction": { 206 | "name": "out_of_scope", 207 | "confidence": 0.7293880581855774 208 | } 209 | }, 210 | { 211 | "text": "nada", 212 | "intent": "deny", 213 | "intent_prediction": { 214 | "name": "confirm", 215 | "confidence": 0.4764827787876129 216 | } 217 | }, 218 | { 219 | "text": "pedir una maquina virtual de 16 GB en RAM y 128 GB de disco duro", 220 | "intent": "request_vm", 221 | "intent_prediction": { 222 | "name": "inform", 223 | "confidence": 0.8640156388282776 224 | } 225 | }, 226 | { 227 | "text": "acceso a una maquina de 16 GB de ram 2 CPUs y 16 GB de disco", 228 | "intent": "request_vm", 229 | "intent_prediction": { 230 | "name": "inform", 231 | "confidence": 0.728003740310669 232 | } 233 | }, 234 | { 235 | "text": "la red de invitados", 236 | "intent": "inform", 237 | "intent_prediction": { 238 | "name": "connect_wifi", 239 | "confidence": 0.9898200631141663 240 | } 241 | }, 242 | { 243 | "text": "taller de informática", 244 | "intent": "inform", 245 | "intent_prediction": { 246 | "name": "request_biometrics_report", 247 | "confidence": 0.7526675462722778 248 | } 249 | }, 250 | { 251 | "text": "32 nucleos de cpu", 252 | "intent": "inform", 253 | "intent_prediction": { 254 | "name": "request_vm", 255 | "confidence": 0.3660873472690582 256 | } 257 | }, 258 | { 259 | "text": "para escalar verticalmente", 260 | "intent": "inform", 261 | "intent_prediction": { 262 | "name": "request_vm", 263 | "confidence": 0.7156234979629517 264 | } 265 | }, 266 | { 267 | "text": "cual es el significado de la vida", 268 | "intent": "out_of_scope", 269 | "intent_prediction": { 270 | "name": "get_incident_status", 271 | "confidence": 0.5191627740859985 272 | } 273 | }, 274 | { 275 | "text": "mi regrigerador no funciona", 276 | "intent": "out_of_scope", 277 | "intent_prediction": { 278 | "name": "problem_email", 279 | "confidence": 0.7983772158622742 280 | } 281 | }, 282 | { 283 | "text": "nos vemos", 284 | "intent": "goodbye", 285 | "intent_prediction": { 286 | "name": "deny", 287 | "confidence": 0.49834197759628296 288 | } 289 | }, 290 | { 291 | "text": "chau", 292 | "intent": "goodbye", 293 | "intent_prediction": { 294 | "name": "confirm", 295 | "confidence": 0.9128454923629761 296 | } 297 | }, 298 | { 299 | "text": "salir", 300 | "intent": "goodbye", 301 | "intent_prediction": { 302 | "name": "bot_challenge", 303 | "confidence": 0.28498736023902893 304 | } 305 | }, 306 | { 307 | "text": "Ayudame", 308 | "intent": "help", 309 | "intent_prediction": { 310 | "name": "confirm", 311 | "confidence": 0.4934218227863312 312 | } 313 | }, 314 | { 315 | "text": "negativo", 316 | "intent": "deny", 317 | "intent_prediction": { 318 | "name": "open_incident", 319 | "confidence": 0.21671311557292938 320 | } 321 | }, 322 | { 323 | "text": "no gracias", 324 | "intent": "deny", 325 | "intent_prediction": { 326 | "name": "thank", 327 | "confidence": 0.8174386620521545 328 | } 329 | }, 330 | { 331 | "text": "solicito una instancia para producción", 332 | "intent": "request_vm", 333 | "intent_prediction": { 334 | "name": "request_biometrics_report", 335 | "confidence": 0.500799298286438 336 | } 337 | }, 338 | { 339 | "text": "hoy", 340 | "intent": "inform", 341 | "intent_prediction": { 342 | "name": "out_of_scope", 343 | "confidence": 0.7836118936538696 344 | } 345 | }, 346 | { 347 | "text": "ayer", 348 | "intent": "inform", 349 | "intent_prediction": { 350 | "name": "goodbye", 351 | "confidence": 0.6908778548240662 352 | } 353 | }, 354 | { 355 | "text": "hola que tal", 356 | "intent": "greet", 357 | "intent_prediction": { 358 | "name": "deny", 359 | "confidence": 0.3745102882385254 360 | } 361 | }, 362 | { 363 | "text": "ok", 364 | "intent": "confirm", 365 | "intent_prediction": { 366 | "name": "out_of_scope", 367 | "confidence": 0.3947899341583252 368 | } 369 | }, 370 | { 371 | "text": "nop", 372 | "intent": "deny", 373 | "intent_prediction": { 374 | "name": "inform", 375 | "confidence": 0.9752727150917053 376 | } 377 | }, 378 | { 379 | "text": "la semana anterior", 380 | "intent": "inform", 381 | "intent_prediction": { 382 | "name": "request_biometrics_report", 383 | "confidence": 0.4715787172317505 384 | } 385 | }, 386 | { 387 | "text": "necesito un entorno de pruebas", 388 | "intent": "inform", 389 | "intent_prediction": { 390 | "name": "request_vm", 391 | "confidence": 0.7425248622894287 392 | } 393 | } 394 | ] -------------------------------------------------------------------------------- /results/intent_report.json: -------------------------------------------------------------------------------- 1 | { 2 | "show_menu": { 3 | "precision": 1.0, 4 | "recall": 1.0, 5 | "f1-score": 1.0, 6 | "support": 6, 7 | "confused_with": {} 8 | }, 9 | "problem_email": { 10 | "precision": 0.8125, 11 | "recall": 1.0, 12 | "f1-score": 0.896551724137931, 13 | "support": 13, 14 | "confused_with": {} 15 | }, 16 | "request_vm": { 17 | "precision": 0.5555555555555556, 18 | "recall": 0.5, 19 | "f1-score": 0.5263157894736842, 20 | "support": 10, 21 | "confused_with": { 22 | "inform": 4, 23 | "request_biometrics_report": 1 24 | } 25 | }, 26 | "password_reset": { 27 | "precision": 0.9375, 28 | "recall": 1.0, 29 | "f1-score": 0.967741935483871, 30 | "support": 15, 31 | "confused_with": {} 32 | }, 33 | "help": { 34 | "precision": 0.7, 35 | "recall": 0.6363636363636364, 36 | "f1-score": 0.6666666666666666, 37 | "support": 11, 38 | "confused_with": { 39 | "out_of_scope": 1, 40 | "confirm": 1 41 | } 42 | }, 43 | "goodbye": { 44 | "precision": 0.8181818181818182, 45 | "recall": 0.6923076923076923, 46 | "f1-score": 0.7500000000000001, 47 | "support": 13, 48 | "confused_with": { 49 | "help": 1, 50 | "confirm": 1 51 | } 52 | }, 53 | "thank": { 54 | "precision": 0.7272727272727273, 55 | "recall": 1.0, 56 | "f1-score": 0.8421052631578948, 57 | "support": 8, 58 | "confused_with": {} 59 | }, 60 | "open_incident": { 61 | "precision": 0.8461538461538461, 62 | "recall": 0.9166666666666666, 63 | "f1-score": 0.8799999999999999, 64 | "support": 12, 65 | "confused_with": { 66 | "help": 1 67 | } 68 | }, 69 | "connect_wifi": { 70 | "precision": 0.7333333333333333, 71 | "recall": 1.0, 72 | "f1-score": 0.846153846153846, 73 | "support": 11, 74 | "confused_with": {} 75 | }, 76 | "bot_challenge": { 77 | "precision": 0.8571428571428571, 78 | "recall": 0.75, 79 | "f1-score": 0.7999999999999999, 80 | "support": 8, 81 | "confused_with": { 82 | "out_of_scope": 2 83 | } 84 | }, 85 | "inform": { 86 | "precision": 0.8936170212765957, 87 | "recall": 0.75, 88 | "f1-score": 0.8155339805825244, 89 | "support": 56, 90 | "confused_with": { 91 | "request_vm": 4, 92 | "connect_wifi": 4 93 | } 94 | }, 95 | "out_of_scope": { 96 | "precision": 0.6470588235294118, 97 | "recall": 0.7333333333333333, 98 | "f1-score": 0.6875, 99 | "support": 15, 100 | "confused_with": { 101 | "problem_email": 2, 102 | "password_reset": 1 103 | } 104 | }, 105 | "deny": { 106 | "precision": 0.75, 107 | "recall": 0.5, 108 | "f1-score": 0.6, 109 | "support": 12, 110 | "confused_with": { 111 | "thank": 1, 112 | "confirm": 1 113 | } 114 | }, 115 | "create_user": { 116 | "precision": 1.0, 117 | "recall": 0.9, 118 | "f1-score": 0.9473684210526316, 119 | "support": 10, 120 | "confused_with": { 121 | "get_incident_status": 1 122 | } 123 | }, 124 | "greet": { 125 | "precision": 1.0, 126 | "recall": 0.5833333333333334, 127 | "f1-score": 0.7368421052631579, 128 | "support": 12, 129 | "confused_with": { 130 | "confirm": 2, 131 | "help": 1 132 | } 133 | }, 134 | "request_biometrics_report": { 135 | "precision": 0.7692307692307693, 136 | "recall": 1.0, 137 | "f1-score": 0.8695652173913044, 138 | "support": 10, 139 | "confused_with": {} 140 | }, 141 | "confirm": { 142 | "precision": 0.6875, 143 | "recall": 0.8461538461538461, 144 | "f1-score": 0.7586206896551724, 145 | "support": 13, 146 | "confused_with": { 147 | "thank": 1, 148 | "out_of_scope": 1 149 | } 150 | }, 151 | "get_incident_status": { 152 | "precision": 0.7727272727272727, 153 | "recall": 0.9444444444444444, 154 | "f1-score": 0.85, 155 | "support": 18, 156 | "confused_with": { 157 | "open_incident": 1 158 | } 159 | }, 160 | "accuracy": 0.8063241106719368, 161 | "macro avg": { 162 | "precision": 0.8059874458002327, 163 | "recall": 0.8195890529223864, 164 | "f1-score": 0.8022758688343714, 165 | "support": 253 166 | }, 167 | "weighted avg": { 168 | "precision": 0.8169964064568609, 169 | "recall": 0.8063241106719368, 170 | "f1-score": 0.8018902791020264, 171 | "support": 253 172 | } 173 | } -------------------------------------------------------------------------------- /scripts/manage_user.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | from rasax.community import config 4 | from rasax.community.database.utils import session_scope 5 | from rasax.community.initialise import create_project_and_settings 6 | from rasax.community.services.domain_service import DomainService 7 | from rasax.community.services.role_service import RoleService 8 | from rasax.community.services.settings_service import SettingsService 9 | from rasax.community.services.user_service import ( 10 | UserService, 11 | UserException, 12 | AuthMechanisms, 13 | RoleException, 14 | ADMIN, 15 | TESTER, 16 | ANNOTATOR, 17 | ) 18 | 19 | 20 | def create_argparser(): 21 | parser = argparse.ArgumentParser( 22 | description="Create a new user or change a user's password, " 23 | "list users or delete a user" 24 | ) 25 | 26 | subparsers = parser.add_subparsers(dest="mode", description="create, delete, list") 27 | 28 | subparser_create(subparsers) 29 | subparser_delete(subparsers) 30 | subparser_list(subparsers) 31 | 32 | return parser 33 | 34 | 35 | def subparser_create(subparsers): 36 | parser_create = subparsers.add_parser("create", description="create a new user") 37 | parser_create.add_argument("username", help="username") 38 | parser_create.add_argument("password", help="password") 39 | parser_create.add_argument( 40 | "role", choices=[ADMIN, ANNOTATOR, TESTER], help="account role" 41 | ) 42 | parser_create.add_argument( 43 | "--update", action="store_true", help="update the password of an existing user" 44 | ) 45 | 46 | 47 | def subparser_delete(subparsers): 48 | parser_delete = subparsers.add_parser("delete", description="delete a user") 49 | parser_delete.add_argument("username", help="username") 50 | 51 | 52 | def subparser_list(subparsers): 53 | subparsers.add_parser("list", description="list all users") 54 | 55 | 56 | def initialise_services(_session): 57 | return ( 58 | UserService(_session), 59 | SettingsService(_session), 60 | DomainService(_session), 61 | RoleService(_session), 62 | ) 63 | 64 | 65 | def change_password(userservice, username, password): 66 | try: 67 | userservice.admin_change_password(username, password) 68 | except UserException as e: 69 | print( 70 | "User {} does not exist. To create a new user please run " 71 | "`sudo python rasa_x_commands.py create {} " 72 | " admin`".format(e, e) 73 | ) 74 | 75 | 76 | def create_user(userservice, username, password, role, team): 77 | try: 78 | userservice.create_user( 79 | username, password, team, role, AuthMechanisms.username_password 80 | ) 81 | except UserException as e: 82 | print( 83 | "User '{}' already exists. You can update the password by " 84 | "running `sudo python rasa_x_commands.py create --update " 85 | "{} admin `".format(e, e) 86 | ) 87 | except RoleException as e: 88 | print("Role '{}' does not exist. Please select a valid role.".format(role)) 89 | 90 | 91 | def delete_user(userservice, username): 92 | try: 93 | userservice.delete_user(username) 94 | except UserException as e: 95 | print( 96 | "User {} does not exist. To create a new user please run " 97 | "`sudo python rasa_x_commands.py create --update admin {} " 98 | "`".format(e, e) 99 | ) 100 | 101 | 102 | def print_user_table(users, format_template): 103 | print(format_template.format("#", "username", "role", "created at")) 104 | print("-" * 42) 105 | 106 | for i, u in enumerate(users): 107 | _id = u.get("_id") 108 | if _id: 109 | created_at = _id.generation_time.strftime("%Y-%m-%d %H:%M:%S") 110 | else: 111 | created_at = "ObjectID not found" 112 | 113 | print( 114 | format_template.format(i + 1, u.get("username"), u.get("role"), created_at) 115 | ) 116 | 117 | print("-" * 42) 118 | 119 | 120 | def list_users(userservice, team_name): 121 | users = userservice.fetch_all_users(team_name) 122 | format_template = "{:<3}{:12}{:8}{:20}" 123 | print("Found {} user{}".format(len(users), "" if len(users) == 1 else "s")) 124 | 125 | if len(users): 126 | print_user_table(sorted(users), format_template) 127 | 128 | 129 | if __name__ == "__main__": 130 | parser = create_argparser() 131 | args = parser.parse_args() 132 | 133 | with session_scope() as session: 134 | 135 | user_service, settings_service, domain_service, role_service = initialise_services( 136 | session 137 | ) 138 | 139 | team_name = config.team_name 140 | 141 | if args.mode == "create": 142 | create_project_and_settings(settings_service, role_service, team_name) 143 | 144 | if args.update: 145 | change_password(user_service, args.username, args.password) 146 | else: 147 | create_user( 148 | user_service, args.username, args.password, args.role, team_name 149 | ) 150 | elif args.mode == "delete": 151 | delete_user(user_service, args.username) 152 | elif args.mode == "list": 153 | list_users(user_service, team_name) -------------------------------------------------------------------------------- /scripts/startActions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rasa run actions --actions actions -p 5055 > actions.out.logs 2>&1 & 4 | -------------------------------------------------------------------------------- /scripts/startClient.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd client && npm start > client.out.logs 2>&1 & 4 | -------------------------------------------------------------------------------- /scripts/startRasaX.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #rasa x --data data/train/ --endpoints endpoints.yml --cors '*' --enable-api --port 5005 --rasa-x-port 5002 > rasax.out.logs 2>&1 & 4 | 5 | rasa x --data data/train/ --endpoints endpoints.yml --cors '*' --enable-api --port 5005 --rasa-x-port 5002 -vv >> rasax.out.logs 2>&1 & 6 | -------------------------------------------------------------------------------- /tests/conversation_tests.md: -------------------------------------------------------------------------------- 1 | ## bot challenge 2 | * bot_challenge: Eres un robot? 3 | - utter_iamabot 4 | 5 | ## ask for options 6 | * show_menu: ver opciones disponibles 7 | - utter_help 8 | - utter_suggest 9 | 10 | ## out of scope 11 | * out_of_scope: Quiero una pizza 12 | - utter_out_of_scope 13 | 14 | ## ask for more help 15 | * thank: muchas gracias 16 | - utter_welcome 17 | - utter_more_help 18 | * confirm: si 19 | - utter_suggest 20 | 21 | ## open incident 22 | * greet: hola 23 | - utter_greet 24 | - utter_help 25 | - utter_suggest 26 | * open_incident: quiero reportar un problema 27 | - open_incident_form 28 | - form{"name": "open_incident_form"} 29 | - form{"name": null} 30 | - slot {"ticket_no": "0055"} 31 | 32 | ## password reset incident 33 | * password_reset: no recuerdo mi contraseña 34 | - open_incident_form 35 | - form{"name": "open_incident_form"} 36 | - form{"name": null} 37 | - slot {"ticket_no": "0055"} 38 | 39 | ## problem email incident 40 | * greet: hello 41 | - utter_greet 42 | - utter_help 43 | - utter_suggest 44 | * problem_email: no puedo acceder a mi correo electronico 45 | - open_incident_form 46 | - form{"name": "open_incident_form"} 47 | - form{"name": null} 48 | 49 | ## problem with email interrupted 50 | * problem_email: Tengo un problema con mi correo 51 | - open_incident_form 52 | - form{"name": "open_incident_form"} 53 | * help: help 54 | - utter_help 55 | - open_incident_form 56 | - form{"name": null} 57 | - slot {"ticket_no": "0055"} 58 | 59 | ## connect to wifi 60 | * connect_wifi: quiero conectarme a la red de wifi de la u 61 | - wifi_faq_form 62 | - form{"name": "wifi_faq_form"} 63 | - form{"name": null} 64 | * confirm: si 65 | - utter_welcome 66 | 67 | ## unable to connect to wifi 68 | * connect_wifi: como conectarme a la red wifi 69 | - wifi_faq_form 70 | - form{"name": "wifi_faq_form"} 71 | - form{"name": null} 72 | * deny {"incident_title":"Problema de conexion a la red WIFI", "itilcategory_id":"52"}: no 73 | - open_incident_form 74 | - form{"name": "open_incident_form"} 75 | - form{"name":null} 76 | - slot {"ticket_no": "0055"} 77 | 78 | ## create a user 79 | * create_user: necesito crear un usuario 80 | - create_user_faq_form 81 | - form{"name": "create_user_faq_form"} 82 | - form{"name": null} 83 | * confirm: si 84 | - utter_welcome 85 | 86 | ## unable to create a user 87 | * create_user: necesito registrarme como usuario 88 | - create_user_faq_form 89 | - form{"name": "create_user_faq_form"} 90 | - form{"name": null} 91 | * deny{"incident_title":"Problema para crear un usuario", "itilcategory_id":"56"}: no pude 92 | - open_incident_form 93 | - form{"name": "open_incident_form"} 94 | - form{"name":null} 95 | - slot {"ticket_no": "0055"} 96 | 97 | ## request biometrics report 98 | * request_biometrics_report: solicito un reporte de intentos de marcacion 99 | - biometrics_report_form 100 | - form{"name": "biometrics_report_form"} 101 | - form{"name": null} 102 | - slot {"ticket_no": "0055"} 103 | 104 | ## request biometrics report interrupted 105 | * request_biometrics_report: necesito un reporte de mis intentos de marcacion 106 | - biometrics_report_form 107 | - form{"name":"biometrics_report_form"} 108 | * help 109 | - utter_help 110 | - biometrics_report_form 111 | - form{"name":null} 112 | - slot {"ticket_no": "0055"} --------------------------------------------------------------------------------