├── actions
├── __init__.py
├── actions_mock.py
├── constants.py
├── actions_base.py
├── parsing.py
├── actions_internal.py
├── actions_faqs.py
└── actions.py
├── data
├── departments.txt
├── faculties.txt
├── software-dtic.txt
├── stories.md
└── nlu.md
├── data_bk
├── test
│ ├── nlu_extras.md
│ ├── stories.md
│ └── nlu.md
├── train
│ ├── nlu_extras.md
│ ├── sistemas-dtic.txt
│ └── stories.md
├── archive
│ ├── test
│ │ └── stories_v1.md
│ └── train
│ │ └── stories_v1.md
├── stories.md
├── nlu_chatito
│ ├── archive
│ │ ├── glpiCommons_v1.chatito
│ │ ├── glpiCommons_v2.chatito
│ │ ├── glpiHeldesk_v1.chatito
│ │ └── glpiHelpdesk_v2.chatito
│ ├── glpiCommons.chatito
│ └── glpiHeldesk.chatito
└── nlu.md
├── alt_requirements
├── conda-requirements.txt
├── requirements_pretrained_embeddings_spacy.txt
├── requirements_bare.txt
├── requirements_dev.txt
├── requirements_docs.txt
├── requirements_pretrained_embeddings_mitie.txt
└── requirements_full.txt
├── requirements.txt
├── results
├── hist.png
├── confmat.png
├── DIETClassifier_report.json
├── intent_report.json
├── DIETClassifier_errors.json
└── intent_errors.json
├── scripts
├── startClient.sh
├── startActions.sh
├── startRasaX.sh
└── manage_user.py
├── rasa-stack-mockup.gif
├── client
├── public
│ ├── favicon.ico
│ ├── profile.png
│ ├── chatlogo.png
│ ├── manifest.json
│ └── index.html
├── src
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── App.css
│ ├── App.js
│ ├── logo.svg
│ └── serviceWorker.js
├── .gitignore
├── package.json
├── JOOMLA.md
└── README.md
├── requirements-actions.txt
├── requirements-dev.txt
├── glpi_credentials.yml
├── .gitignore
├── Dockerfile
├── docker-compose.override.yml
├── credentials.yml
├── .github
└── workflows
│ ├── action-server-ci.yml
│ └── model-ci.yml
├── Makefile
├── endpoints.yml
├── format_results.py
├── results.md
├── tests
└── conversation_tests.md
├── config.yml
├── README.md
└── LICENSE
/actions/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/departments.txt:
--------------------------------------------------------------------------------
1 | DTIC
2 | DIUC
3 | Recursos Humanos
4 | Idiomas
--------------------------------------------------------------------------------
/data_bk/test/nlu_extras.md:
--------------------------------------------------------------------------------
1 | ## lookup:sistema
2 | data/train/sistemas-dtic.txt
--------------------------------------------------------------------------------
/data_bk/train/nlu_extras.md:
--------------------------------------------------------------------------------
1 | ## lookup:sistema
2 | data/train/sistemas-dtic.txt
--------------------------------------------------------------------------------
/alt_requirements/conda-requirements.txt:
--------------------------------------------------------------------------------
1 | scipy==1.2.1
2 | scikit-learn==0.20.2
3 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | rasa[spacy]~=1.10.0
2 | rasa-sdk~=1.10.0
3 | -r requirements-actions.txt
4 |
--------------------------------------------------------------------------------
/results/hist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/santteegt/glpi_chatbot/HEAD/results/hist.png
--------------------------------------------------------------------------------
/results/confmat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/santteegt/glpi_chatbot/HEAD/results/confmat.png
--------------------------------------------------------------------------------
/scripts/startClient.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd client && npm start > client.out.logs 2>&1 &
4 |
--------------------------------------------------------------------------------
/rasa-stack-mockup.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/santteegt/glpi_chatbot/HEAD/rasa-stack-mockup.gif
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/santteegt/glpi_chatbot/HEAD/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/santteegt/glpi_chatbot/HEAD/client/public/profile.png
--------------------------------------------------------------------------------
/client/public/chatlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/santteegt/glpi_chatbot/HEAD/client/public/chatlogo.png
--------------------------------------------------------------------------------
/requirements-actions.txt:
--------------------------------------------------------------------------------
1 | pytablewriter
2 | requests
3 | ruamel.yaml
4 | glpi==0.4.0
5 | future
6 | typing-extensions
--------------------------------------------------------------------------------
/scripts/startActions.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rasa run actions --actions actions -p 5055 > actions.out.logs 2>&1 &
4 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/alt_requirements/requirements_pretrained_embeddings_spacy.txt:
--------------------------------------------------------------------------------
1 | # Minimum Install Requirements
2 | -r ../requirements.txt
3 |
4 | spacy==2.1.4
5 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/glpi_credentials.yml:
--------------------------------------------------------------------------------
1 | uri: http://localhost:9000/apirest.php
2 | auth_token: LY6Q3x8GRrGvcqLgJs9Onzipjn5FZghFVKNsoKYU
3 | app_token: jH8hfBdtpFCpraY6xZQAz9XaXO3G04XXGCTImWX9
4 | localmode: false
--------------------------------------------------------------------------------
/.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/
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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"]
--------------------------------------------------------------------------------
/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/.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/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 |
--------------------------------------------------------------------------------
/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"
--------------------------------------------------------------------------------
/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/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/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 |
--------------------------------------------------------------------------------
/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_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/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}
--------------------------------------------------------------------------------
/.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
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/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 | ```
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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.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 |
--------------------------------------------------------------------------------
/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"}
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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 | }
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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)
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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_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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | ```
--------------------------------------------------------------------------------
/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 | ]
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | ]
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------