├── FE-Controller ├── __init__.py ├── lib │ ├── __init__.py │ ├── ext │ │ └── __init__.py │ └── maia.py ├── .settings │ └── org.eclipse.core.resources.prefs ├── requirements.txt ├── qabot.wsgi ├── askbot.wsgi ├── talktobot.wsgi ├── .pydevproject ├── .project ├── README.md ├── facts │ └── kb-java └── qabot.py ├── ChatScript ├── filesDent.txt ├── filesNiko.txt ├── filesDuke.txt ├── .gitignore ├── .project ├── getChatScript.sh ├── RAWDATA │ ├── NIKO │ │ ├── people.top │ │ ├── projects.top │ │ ├── publications.top │ │ ├── introductions.top │ │ └── simplecontrol.top │ ├── DENT │ │ ├── estado.top │ │ ├── javaconcepts.top │ │ ├── control.top │ │ ├── insultos.top │ │ ├── keywordless.top │ │ └── java.top │ └── DUKE │ │ ├── control.top │ │ └── topic.top └── README.md ├── Ask-Client ├── images │ ├── duke.png │ └── landing │ │ ├── duke.png │ │ ├── banner.png │ │ ├── gsi-logo.png │ │ ├── gsi-logo2.png │ │ ├── click_to_talk.png │ │ └── logo_extended2.png ├── css │ ├── images │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_2e83ff_256x240.png │ │ ├── ui-icons_454545_256x240.png │ │ ├── ui-icons_888888_256x240.png │ │ ├── ui-icons_cd0a0a_256x240.png │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── template.css │ ├── reset.css │ ├── landing.css │ ├── landing.less │ └── global.css ├── index.html ├── landing.html └── js │ └── ask.js ├── Chat-client ├── images │ ├── nok.png │ ├── ok.png │ ├── bg_gsi.jpg │ ├── spgray.gif │ ├── gray_sp.gif │ ├── head_bg.png │ ├── avatars │ │ ├── sad.png │ │ ├── angry.png │ │ ├── blink.png │ │ ├── duke.png │ │ ├── happy.png │ │ ├── duke_ok.png │ │ ├── sad (1).png │ │ ├── waiting.png │ │ ├── duke_hello.png │ │ ├── surprised.png │ │ ├── duke_connect.png │ │ ├── duke_reading.png │ │ ├── duke_teaching.png │ │ ├── duke_thinking.png │ │ └── duke_waiting.png │ ├── bg_shadow_66.png │ ├── bg_vademecum.png │ └── buttons-light.png ├── css │ ├── template.css │ └── global.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── README.md ├── popup.html └── index.html ├── QA-client ├── images │ ├── duke.png │ ├── question.png │ └── QuestionMark.svg ├── css │ ├── images │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_2e83ff_256x240.png │ │ ├── ui-icons_454545_256x240.png │ │ ├── ui-icons_888888_256x240.png │ │ ├── ui-icons_cd0a0a_256x240.png │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ ├── ui-bg_glass_95_fef1ec_1x400.png │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── template.css │ └── global.css ├── index.html └── js │ └── qa.js ├── .gitignore ├── solr-elearning ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.jdt.core.prefs ├── solr-elearning.properties ├── .project ├── src │ ├── test │ │ └── java │ │ │ └── es │ │ │ └── gsi │ │ │ └── dit │ │ │ └── upm │ │ │ └── es │ │ │ └── solr │ │ │ └── AppTest.java │ └── main │ │ ├── resources │ │ └── logback.xml │ │ └── java │ │ └── es │ │ └── upm │ │ └── dit │ │ └── gsi │ │ └── solr │ │ ├── maia │ │ └── annotation │ │ │ └── OnMessage.java │ │ ├── SolrElearningApp.java │ │ └── ElearningSolr.java ├── .classpath └── README.MD ├── Agent-system ├── .settings │ ├── org.eclipse.jdt.ui.prefs │ └── org.eclipse.jdt.core.prefs ├── jason_elearning.mas2j ├── src │ ├── java │ │ └── maia │ │ │ ├── utils │ │ │ └── package.html │ │ │ ├── client │ │ │ ├── package.html │ │ │ ├── annotation │ │ │ │ └── OnMessage.java │ │ │ ├── MaiaTxClient.java │ │ │ └── MaiaRxClient.java │ │ │ ├── start.java │ │ │ └── send.java │ ├── main │ │ └── resources │ │ │ └── logback.xml │ └── asl │ │ └── teacher.asl ├── .project ├── .classpath └── README.md ├── test ├── Chatscript alone-evaluation │ ├── RAWDATA │ │ ├── WORLDDATA │ │ │ └── javaconcept.tbl │ │ ├── simpletopic.top │ │ └── simplecontrol.top │ └── facts │ │ └── kb-java └── README.md ├── deployment.md └── README.md /FE-Controller/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /FE-Controller/lib/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /FE-Controller/lib/ext/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ChatScript/filesDent.txt: -------------------------------------------------------------------------------- 1 | # underlying conversation system 2 | RAWDATA/DENT/ -------------------------------------------------------------------------------- /ChatScript/filesNiko.txt: -------------------------------------------------------------------------------- 1 | # underlying conversation system 2 | RAWDATA/NIKO/ 3 | -------------------------------------------------------------------------------- /Ask-Client/images/duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/images/duke.png -------------------------------------------------------------------------------- /Chat-client/images/nok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/nok.png -------------------------------------------------------------------------------- /Chat-client/images/ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/ok.png -------------------------------------------------------------------------------- /QA-client/images/duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/images/duke.png -------------------------------------------------------------------------------- /Chat-client/images/bg_gsi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/bg_gsi.jpg -------------------------------------------------------------------------------- /Chat-client/images/spgray.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/spgray.gif -------------------------------------------------------------------------------- /QA-client/images/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/images/question.png -------------------------------------------------------------------------------- /Chat-client/images/gray_sp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/gray_sp.gif -------------------------------------------------------------------------------- /Chat-client/images/head_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/head_bg.png -------------------------------------------------------------------------------- /Ask-Client/images/landing/duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/images/landing/duke.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/sad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/sad.png -------------------------------------------------------------------------------- /ChatScript/filesDuke.txt: -------------------------------------------------------------------------------- 1 | # underlying conversation system 2 | RAWDATA/DUKE/control.top 3 | RAWDATA/DUKE/topic.top 4 | -------------------------------------------------------------------------------- /Ask-Client/images/landing/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/images/landing/banner.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/angry.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/blink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/blink.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/happy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/happy.png -------------------------------------------------------------------------------- /Chat-client/images/bg_shadow_66.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/bg_shadow_66.png -------------------------------------------------------------------------------- /Chat-client/images/bg_vademecum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/bg_vademecum.png -------------------------------------------------------------------------------- /Chat-client/images/buttons-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/buttons-light.png -------------------------------------------------------------------------------- /Ask-Client/images/landing/gsi-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/images/landing/gsi-logo.png -------------------------------------------------------------------------------- /Ask-Client/images/landing/gsi-logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/images/landing/gsi-logo2.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke_ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke_ok.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/sad (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/sad (1).png -------------------------------------------------------------------------------- /Chat-client/images/avatars/waiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/waiting.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | log/ 2 | bin/ 3 | maia_server/ 4 | ChatScript/LOGS/ 5 | *.log 6 | *.pyc 7 | *~ 8 | TMP/ 9 | LOGS/ 10 | target/ 11 | -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke_hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke_hello.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/surprised.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/surprised.png -------------------------------------------------------------------------------- /Ask-Client/images/landing/click_to_talk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/images/landing/click_to_talk.png -------------------------------------------------------------------------------- /Ask-Client/images/landing/logo_extended2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/images/landing/logo_extended2.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke_connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke_connect.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke_reading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke_reading.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke_teaching.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke_teaching.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke_thinking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke_thinking.png -------------------------------------------------------------------------------- /Chat-client/images/avatars/duke_waiting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/images/avatars/duke_waiting.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /FE-Controller/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/bottle.py=utf-8 3 | encoding/talkbot.py=utf-8 4 | -------------------------------------------------------------------------------- /QA-client/css/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /solr-elearning/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /Agent-system/.settings/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | #Tue Aug 28 09:21:02 BRT 2007 2 | eclipse.preferences.version=1 3 | internal.default.compliance=default 4 | -------------------------------------------------------------------------------- /Chat-client/css/template.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .starter-template { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /Chat-client/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Chat-client/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Chat-client/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Chat-client/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /QA-client/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/QA-client/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /Ask-Client/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsi-upm/calista-bot/HEAD/Ask-Client/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /Agent-system/jason_elearning.mas2j: -------------------------------------------------------------------------------- 1 | MAS jason_elearning { 2 | 3 | infrastructure: Centralised 4 | 5 | agents: 6 | teacher; 7 | 8 | aslSourcePath: 9 | "src/asl"; 10 | } -------------------------------------------------------------------------------- /FE-Controller/requirements.txt: -------------------------------------------------------------------------------- 1 | Unidecode==0.04.17 2 | argparse==1.2.1 3 | backports.ssl-match-hostname==3.4.0.2 4 | gevent==1.0.1 5 | greenlet==0.4.5 6 | six==1.9.0 7 | websocket-client==0.26.0 8 | wsgiref==0.1.2 9 | -------------------------------------------------------------------------------- /Agent-system/src/java/maia/utils/package.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | This package provide several helper classes and method to work with JSON and 4 | the special format used as part of the maia protocol. 5 |

6 | -------------------------------------------------------------------------------- /solr-elearning/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /FE-Controller/qabot.wsgi: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import sys, os 3 | 4 | # Add folder to path 5 | root_folder = os.path.dirname(__file__) 6 | sys.path.append(os.path.abspath(root_folder)) 7 | 8 | from qabot import app as application 9 | 10 | -------------------------------------------------------------------------------- /ChatScript/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | # Ignore everything except my own files 3 | !*/ 4 | !.gitignore 5 | !filesDuke.txt 6 | !filesDent.txt 7 | !filesNiko.txt 8 | !README.md 9 | !getChatScript.sh 10 | !RAWDATA/DUKE/* 11 | !RAWDATA/DENT/* 12 | !RAWDATA/NIKO/* 13 | -------------------------------------------------------------------------------- /FE-Controller/askbot.wsgi: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import sys, os 3 | 4 | # Add folder to path 5 | root_folder = os.path.dirname(__file__) 6 | sys.path.append(os.path.abspath(root_folder)) 7 | 8 | from askbot import app as application 9 | 10 | -------------------------------------------------------------------------------- /FE-Controller/talktobot.wsgi: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | import sys, os 3 | 4 | # Add folder to path 5 | root_folder = os.path.dirname(__file__) 6 | sys.path.append(os.path.abspath(root_folder)) 7 | 8 | from talkbot import app as application 9 | 10 | -------------------------------------------------------------------------------- /ChatScript/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ChatScript 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /solr-elearning/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 3 | org.eclipse.jdt.core.compiler.compliance=1.6 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.6 6 | -------------------------------------------------------------------------------- /Agent-system/src/java/maia/client/package.html: -------------------------------------------------------------------------------- 1 | 2 |

This package offers several classes, structured in a multi level structure, that 3 | provide additional features that are either specific of maia protocol 4 | (message formating, subscription process, etc.) or not provided by the web-socket 5 | libraries (reconnection, reliable message deliver, etc.).

6 | 7 | -------------------------------------------------------------------------------- /solr-elearning/solr-elearning.properties: -------------------------------------------------------------------------------- 1 | # Config file. This file, not used 2 | #configFile=solr-elearning.properties 3 | 4 | # Maia config otpions 5 | maiaURI=http://localhost:1337 6 | 7 | # Logger 8 | # Options are ToSTDOUT and SolrSLog 9 | logger=ToSTDOUT 10 | 11 | # Solr Server options 12 | solrURL=http://localhost:8080/solr 13 | coreName=elearning 14 | 15 | # Solr Search otpions 16 | searchTag=title 17 | fl=topic,url,definition,links,title 18 | 19 | # SOLR Fields 20 | solrFields=topic,url,definition,links,title 21 | 22 | -------------------------------------------------------------------------------- /test/Chatscript alone-evaluation/RAWDATA/WORLDDATA/javaconcept.tbl: -------------------------------------------------------------------------------- 1 | concept: ~javaconcept () 2 | 3 | table: ~javaconceptof (^javaconcept ^object) 4 | ^addproperty(^object NOUN) 5 | ^createfact(^object javaconcept ^javaconcept) 6 | 7 | DATA: 8 | 9 | for [for bucle_for bucles_for estructura_for] 10 | bucles [bucle bucles] 11 | break [break orden_break] 12 | continue [continue orden_continue] 13 | while [while bucle_while bucles_while] 14 | do-while [dowhile bucles_do-while bucle_do-while] 15 | iteracion [iteracion iteraciones] -------------------------------------------------------------------------------- /FE-Controller/.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /FE-Controller 5 | /${PROJECT_DIR_NAME}/lib 6 | /${PROJECT_DIR_NAME}/lib/ext 7 | 8 | python 2.7 9 | Default 10 | 11 | -------------------------------------------------------------------------------- /ChatScript/getChatScript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FILENAME=ChatScript-5.31.zip 4 | TMPFOLDER=INSTALL 5 | BASEFOLDER=`pwd` 6 | 7 | # CREATES TMP DIR 8 | echo "Creting tempfolder $TMPFOLDER" 9 | mkdir -p $TMPFOLDER 10 | cd $TMPFOLDER 11 | 12 | echo -n "Getting ChatScript..." 13 | wget -O $FILENAME http://downloads.sourceforge.net/project/chatscript/ChatScript-5.31.zip >wget.log 2>&1 14 | cd $BASEFOLDER 15 | unzip $TMPFOLDER/$FILENAME 16 | chmod +x LinuxChatScript64 LinuxChatScript32 17 | echo " done!" 18 | 19 | echo -n "Cleaning up..." 20 | rm -rf $TMPFOLDER 21 | echo " done!" 22 | -------------------------------------------------------------------------------- /FE-Controller/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FE-Controller 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | com.aptana.ide.core.unifiedBuilder 15 | 16 | 17 | 18 | 19 | 20 | com.aptana.projects.webnature 21 | org.python.pydev.pythonNature 22 | 23 | 24 | -------------------------------------------------------------------------------- /solr-elearning/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | solr-elearning 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/NIKO/people.top: -------------------------------------------------------------------------------- 1 | concept: ~positions [professor research student fellow_grade postgraduate] 2 | 3 | topic: ~PEOPLE keep repeat (member professor research) 4 | 5 | u: (how many _~position) 6 | ¬solrPeople position '_0 7 | a: (¬solrResponsePeople position _1) # ¬solrResponsePeople URL topic 8 | We have _0 people in that role. 9 | 10 | u: (how many) 11 | ¬solrCount people 12 | a: (¬solrcounted _*) 13 | [We have '_0 members][There are '_0 people working with the GSI.] 14 | b: (active) 15 | ¬solrCount people active 16 | c:(¬solrcounted _*) 17 | [We have '_0 active projects][_0 of them are active projects] 18 | -------------------------------------------------------------------------------- /Agent-system/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.6 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.6 14 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/NIKO/projects.top: -------------------------------------------------------------------------------- 1 | 2 | topic: ~PROJECTS keep repeat (project) 3 | 4 | u: (about _*) 5 | ¬solrProject topic '_0 6 | a: (¬solrResponseProject _1 _1) # ¬solrResponseProject URL topic 7 | We have this project about _1 ¬url _0 ¬solrCount projects _1 8 | b:(¬solrcounted _*) 9 | We have another _0 in topics related to this one. 10 | 11 | 12 | u: (how many projects) 13 | ¬solrCount projects 14 | a: (¬solrcounted _*) 15 | [We have '_0 projects.][The GSI has a total of _0 projects] 16 | b: (active) 17 | ¬solrCount projects active 18 | c:(¬solrcounted _*) 19 | [We have '_0 active projects][_0 of them are active projects] 20 | b: (public) 21 | ¬solrCount projects public 22 | 23 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/NIKO/publications.top: -------------------------------------------------------------------------------- 1 | 2 | topic: ~PUBLICATIONS keep repeat (publication) 3 | 4 | u: (about _*) 5 | ¬solrPublication topic '_0 6 | a: (¬solrResponsePublication _1 _1) # ¬solrResponsePublication URL topic 7 | We have this publication about _1 ¬url _0 ¬solrCount publication _1 8 | b:(¬solrcounted _*) 9 | We have another _0 in topics related to this one. 10 | 11 | 12 | u: (how many) 13 | ¬solrCount publication 14 | a: (¬solrcounted _*) 15 | [We have '_0 publications in total.][The GSI has published a total of _0 paperss] 16 | b: (active) 17 | ¬solrCount projects active 18 | c:(¬solrcounted _*) 19 | [We have '_0 active projects][_0 of them are active projects] 20 | b: (public) 21 | ¬solrCount projects public 22 | 23 | -------------------------------------------------------------------------------- /QA-client/css/template.css: -------------------------------------------------------------------------------- 1 | .form-group { 2 | width: 60%; 3 | margin-left: 2%; 4 | margin-right: 5%; 5 | } 6 | .container { 7 | height: 100%; 8 | } 9 | 10 | #iframe-qa { 11 | /*margin-top: 2%;*/ 12 | width: 100%; 13 | /*display: none;*/ 14 | border:0px; 15 | height: 100%; 16 | } 17 | 18 | #iframe-container { 19 | height: 80%; 20 | float: left; 21 | width: 80% 22 | } 23 | 24 | #related-container { 25 | margin-left: 85%; 26 | display: none; 27 | } 28 | 29 | #qa-response { 30 | margin-top: 5%; 31 | height: 100%; 32 | } 33 | 34 | html, body { 35 | height: 100%; 36 | } 37 | 38 | #username-container { 39 | position: absolute; 40 | top: 0px; 41 | right: 0px; 42 | padding: 5px 5% 5px 1%; 43 | background: #FFFFFF; 44 | } 45 | 46 | #container { 47 | position: absolute; 48 | top: 0px; 49 | } -------------------------------------------------------------------------------- /Agent-system/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | localhost 9 | LOCAL0 10 | calistabot: %-5level %logger{36} - %msg%n 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /solr-elearning/src/test/java/es/gsi/dit/upm/es/solr/AppTest.java: -------------------------------------------------------------------------------- 1 | package es.gsi.dit.upm.es.solr; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test 9 | * Again, just a skeleton right now. 10 | */ 11 | public class AppTest 12 | extends TestCase 13 | { 14 | /** 15 | * Create the test case 16 | * 17 | * @param testName name of the test case 18 | */ 19 | public AppTest( String testName ) 20 | { 21 | super( testName ); 22 | } 23 | 24 | /** 25 | * @return the suite of tests being tested 26 | */ 27 | public static Test suite() 28 | { 29 | return new TestSuite( AppTest.class ); 30 | } 31 | 32 | /** 33 | * Rigourous Test :-) 34 | */ 35 | public void testApp() 36 | { 37 | assertTrue( true ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/Chatscript alone-evaluation/RAWDATA/simpletopic.top: -------------------------------------------------------------------------------- 1 | 2 | concept: ~saludo [Hola Buenas Hi Que_tal] 3 | concept: ~despedida [Adios Nos_vemos Luego] 4 | concept: ~teaching [Aprender Ayudar] 5 | 6 | 7 | topic: ~saludando (~saludo) 8 | 9 | 10 | u: (%input>1 ~saludo) 11 | noerase() ^repeat() 12 | Hola de nuevo. \[sendmaia assert returning \] 13 | 14 | u: (~saludo) 15 | ^noerase() ^repeat() 16 | [Hola.] [Buenas.] 17 | 18 | 19 | 20 | 21 | topic: ~elearning (~teaching profesor) 22 | 23 | u: (eres el profesor) 24 | ^noerase() ^repeat() 25 | No; soy un bot asistente para ayudarte a encontrar respuestas. 26 | 27 | u: ($bot=duke ~teaching) 28 | ^noerase() ^repeat() 29 | Puedo ayudarte con tus preguntas sobre Java. 30 | 31 | 32 | topic: ~despidiendo (~despedida) 33 | 34 | u: (~despedida) 35 | ^noerase() ^repeat() 36 | [Hasta otra.] [Nos vemos.] 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/NIKO/introductions.top: -------------------------------------------------------------------------------- 1 | topic: ~INTRODUCTIONS keep repeat (~emogoodbye ~emohello ~emohowzit name here ) 2 | r: IMPW () 3 | Would you prefer to focus on the outer world or on your own inner world? 4 | a: (<>) outer is it 5 | a: (<>) inner is it 6 | 7 | 8 | #!x will match on every return start of a conversation 9 | t: ( %input<%userfirstline %input>0 ) 10 | ^keep() 11 | [Welcome back] [Hello, again.][Glad you came back.][Hi.][Hi, again.] 12 | 13 | #!x matches every time on startup of a new conversation 14 | t: ( %input<%userfirstline ) 15 | ^keep() 16 | Welcome to the GSI Web page. 17 | 18 | #!x issued only once, then erased 19 | t: Have you been here before? 20 | 21 | #! what is your name 22 | u: ( what is your name ) My name is Niko. 23 | 24 | u: (who be you) 25 | [I am Niko, an intelligent bot.][I am Niko, a boot] 26 | 27 | u: (<>) 28 | No, I am a bot. 29 | -------------------------------------------------------------------------------- /Ask-Client/css/template.css: -------------------------------------------------------------------------------- 1 | #username-container { 2 | position: absolute; 3 | top: 0px; 4 | right: 0px; 5 | padding: 5px 5% 5px 1%; 6 | background: #FFFFFF; 7 | z-index: 2; 8 | } 9 | 10 | #container { 11 | position: absolute; 12 | top: 0; 13 | right: 0; 14 | width: 100%; 15 | height: 100%; 16 | z-index: 1; 17 | } 18 | 19 | #chatbox { 20 | float: left; 21 | height: 100%; 22 | width: 300px; 23 | background: #aaaaaa; 24 | overflow: scroll; 25 | } 26 | 27 | #iframe-container { 28 | float: left; 29 | width: 60%; 30 | height: 100%; 31 | } 32 | 33 | #iframe-qa { 34 | float: right; 35 | width: 100%; 36 | height: 100%; 37 | border: 0; 38 | } 39 | .bot-r { 40 | margin: 10px 40px 5px 10px; 41 | background: #ffffff; 42 | border-radius: 5px; 43 | } 44 | 45 | .user-q { 46 | margin: 10px 10px 5px 40px; 47 | background: #ffffff; 48 | border-radius: 5px; 49 | text-align: right; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Agent-system/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | jason_elearning 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | jasonide.jasonBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.xtext.ui.shared.xtextBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.m2e.core.maven2Builder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.m2e.core.maven2Nature 31 | org.eclipse.jdt.core.javanature 32 | org.eclipse.xtext.ui.shared.xtextNature 33 | jasonide.jasonNature 34 | 35 | 36 | -------------------------------------------------------------------------------- /solr-elearning/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | localhost 9 | LOCAL0 10 | calistabot: %-5level %logger{36} - %msg%n 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Agent-system/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Ask-Client/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } -------------------------------------------------------------------------------- /solr-elearning/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Chat-client/README.md: -------------------------------------------------------------------------------- 1 | # [Chat client-Bot Calista](https://github.com/gsi-upm/calista-bot/Chat-client) 2 | 3 | 4 | JavaScript chat client module for Calista-Bot project. An user interface that allows the user to communicate with the system, by chatting with the personal assistant in natural language. 5 | 6 | 7 | ![Chat client](http://img14.imageshack.us/img14/8480/x6ex.png) 8 | 9 | 10 | ###Launching the Chat client 11 | 12 | Open the "popup.html" file with your favourite browser. 13 | 14 | 15 | ## License 16 | 17 | ``` 18 | Copyright 2013 UPM-GSI: Group of Intelligent Systems - Universidad Politécnica de Madrid (UPM) 19 | 20 | Licensed under the Apache License, Version 2.0 (the "License"); 21 | You may not use this file except in compliance with the License. 22 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 23 | applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 24 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 25 | language governing permissions and limitations under the License. 26 | ``` 27 | ![GSI Logo](http://gsi.dit.upm.es/templates/jgsi/images/logo.png) 28 | 29 | This project has been developed as the master thesis of [Javier Herrera](https://github.com/javiherrera) under the tutelage of [Miguel Coronado](https://github.com/miguelcb84) and the supervision of [Carlos A. Iglesias](https://github.com/cif2cif) at [gsi-upm](https://github.com/gsi-upm) 30 | -------------------------------------------------------------------------------- /Agent-system/src/java/maia/client/annotation/OnMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 miguel Grupo de Sistemas Inteligentes (GSI UPM) 3 | * 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package maia.client.annotation; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | *

It is discouraged to assign multiple onMessage annotations 26 | * to the same target.

27 | * 28 | * 29 | * Project: maia-client
30 | * Package: maia.client
31 | * Class: OnMessage.java
32 | *
33 | * GSI 2013
34 | * 35 | * @author Miguel Coronado (miguelcb@gsi.dit.upm.es) 36 | * @version Jun 4, 2013 37 | * 38 | */ 39 | @Target(value = ElementType.METHOD) 40 | @Retention(value = RetentionPolicy.RUNTIME) 41 | public @interface OnMessage { 42 | 43 | String value(); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /solr-elearning/src/main/java/es/upm/dit/gsi/solr/maia/annotation/OnMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 miguel Grupo de Sistemas Inteligentes (GSI UPM) 3 | * 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package es.upm.dit.gsi.solr.maia.annotation; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | *

It is discouraged to assign multiple onMessage annotations 26 | * to the same target.

27 | * 28 | * 29 | * Project: maia-client
30 | * Package: maia.client
31 | * Class: OnMessage.java
32 | *
33 | * GSI 2013
34 | * 35 | * @author Miguel Coronado (miguelcb@gsi.dit.upm.es) 36 | * @version Jun 4, 2013 37 | * 38 | */ 39 | @Target(value = ElementType.METHOD) 40 | @Retention(value = RetentionPolicy.RUNTIME) 41 | public @interface OnMessage { 42 | 43 | String value(); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /solr-elearning/README.MD: -------------------------------------------------------------------------------- 1 | # [SOLR Calista](https://github.com/gsi-upm/calista-bot/solr-elearning) 2 | 3 | Linked Open Data Server module for Calista-Bot project. It makes use of the 4.10.2 4 | version of [Apache Solr](http://lucene.apache.org/solr/). This module contains 5 | a connector between the Solr Server and the maia service, which has previously 6 | been populated with the scrapped data (provided, as well as a solrconfig.xml, and a 7 | schema.xml for the solr in the src/main/resources and src/main/resources/solr folders). 8 | 9 | For example, in the personal assistance system for a e-learning platform, when 10 | the user sends a question and no information is found in the KB, this server 11 | is ready to provide the needed information. 12 | 13 | 14 | 15 | ### Launching the module 16 | 17 | Assuming the solr server is already configured, edit the config file to provide with the server URL and the core, 18 | and build the project: 19 | 20 | ```bash 21 | :~/calista-bot/solr-elearning/$ mvn package 22 | ``` 23 | 24 | And just launch it: 25 | 26 | ```bash 27 | :~/calista-bot/solr-elearning$ java -jar target/solr-elearning-jar-with-dependencies.jar -c solr-elearning.properties 28 | ``` 29 | 30 | ## License 31 | 32 | Copyright 2014 UPM-GSI: Group of Intelligent Systems - Universidad Politécnica de Madrid (UPM) 33 | 34 | Licensed under the Apache License, Version 2.0 (the "License"); 35 | you may not use this file except in compliance with the License. 36 | You may obtain a copy of the License at 37 | 38 | http://www.apache.org/licenses/LICENSE-2.0 39 | 40 | Unless required by applicable law or agreed to in writing, software 41 | distributed under the License is distributed on an "AS IS" BASIS, 42 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 43 | See the License for the specific language governing permissions and 44 | limitations under the License. -------------------------------------------------------------------------------- /Agent-system/src/java/maia/client/MaiaTxClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 miguel Grupo de Sistemas Inteligentes (GSI UPM) 3 | * 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package maia.client; 18 | 19 | import java.io.IOException; 20 | import java.net.URI; 21 | import java.net.URISyntaxException; 22 | import java.util.logging.Logger; 23 | 24 | /** 25 | * Project: maia-client
26 | * Package: maia.client
27 | * Class: MaiaClient.java
28 | *
29 | * GSI 2013
30 | * 31 | * @author Miguel Coronado (miguelcb@gsi.dit.upm.es) 32 | * @version Jun 3, 2013 33 | * 34 | */ 35 | public class MaiaTxClient extends MaiaClientAdapter { 36 | 37 | // TODO: Add config option instead... (Running out of time!) 38 | private Logger logger = Logger.getLogger("STDOUT"); 39 | //private Logger logger = Logger.getLogger("SYSLOG"); 40 | private String username; 41 | 42 | /** 43 | * @param serverURI 44 | * @throws URISyntaxException 45 | */ 46 | public MaiaTxClient(String serverURI) throws URISyntaxException { 47 | super(new URI(serverURI)); 48 | } 49 | 50 | 51 | public static void main (String[] args) throws URISyntaxException, InterruptedException, IOException { 52 | 53 | 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Chat-client/popup.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | gsiBot 13 | 14 | 15 | 17 | 18 | 19 | 20 |
21 |
22 |

23 | 24 | 25 | 26 | 27 |

28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 |
44 |
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /QA-client/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | QA Client 15 | 16 | 17 | 19 | 20 | 21 |
22 | Usuario:
23 | 24 |
25 | 26 | 27 |
28 |
29 |

30 | 31 | 32 | 33 |

34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | 46 | 47 |
48 |
49 |
50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # [test-Bot Calista](https://github.com/gsi-upm/calista-bot/test) 2 | 3 | 4 | [ChatScript](http://sourceforge.net/projects/chatscript/) test corpus for the system evaluation. With it, we make an evaluation of the system implemented in our project. We will use this evaluation to show the benefits from including a Grammar Engine, a Linked Open Data Server and an Agent system. We will remark all the features obtained from them and the possibilities that they offer, opposite to only using only ChatScript or other Chatbot technology alone. 5 | 6 | 7 | 8 | ###Execution 9 | 10 | 11 | These corpus files should be copied to the /ChatScript/RAWDATA/ folder. They can be compiled and loaded by running [ChatScript](http://sourceforge.net/projects/chatscript/) locally: 12 | To launch ChatScript locally on Windows, the following command should be run inside the ChatScript folder: 13 | 14 | chatscript local 15 | 16 | 17 | On Linux, the following command should be run inside the ChatScript folder: 18 | 19 | ./LinuxChatScript32 local 20 | 21 | Once ChatScript is locally launched, we can use the following command to build and load the corpus: 22 | 23 | :build 1 24 | 25 | 26 | ## License 27 | 28 | ``` 29 | Copyright 2013 UPM-GSI: Group of Intelligent Systems - Universidad Politécnica de Madrid (UPM) 30 | 31 | Licensed under the Apache License, Version 2.0 (the "License"); 32 | You may not use this file except in compliance with the License. 33 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 34 | applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 35 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 36 | language governing permissions and limitations under the License. 37 | ``` 38 | ![GSI Logo](http://gsi.dit.upm.es/templates/jgsi/images/logo.png) 39 | 40 | This project has been developed as the master thesis of [Javier Herrera](https://github.com/javiherrera) under the tutelage of [Miguel Coronado](https://github.com/miguelcb84) and the supervision of [Carlos A. Iglesias](https://github.com/cif2cif) at [gsi-upm](https://github.com/gsi-upm) 41 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DENT/estado.top: -------------------------------------------------------------------------------- 1 | concept: ~habercomido ( desayunar desayunado comer comido cenar cenado ) 2 | 3 | topic: ~ESTADO keep repeat [ ~estoy ~habercomido ~lol como muy_bien ok llegas_tarde gracias ] 4 | 5 | #! estoy algo triste 6 | u: ESTOY_NEG ({~estoy} * _~estado_animo_negativo) 7 | [¿Por qué estás '_0?] 8 | [¿Cómo es que estás '_0?] 9 | a: (porque) 10 | [Entiendo] 11 | [Comprendo] 12 | a: (~estoy '_~estado_animo_negativo) 13 | ^reuse(ESTOY_NEG) 14 | a: (*) 15 | Oh 16 | 17 | #! estoy muy contento 18 | u: ESTOY_POS (~estoy * _~estado_animo_positivo) 19 | [Me alegro de que estés '_0] 20 | [¡Estupendo!] 21 | 22 | #! creo que estoy borracho 23 | u: ESTOY_BORRACHO (~estoy ~borracho) 24 | ¿En serio? 25 | a: (~afirmacion) 26 | O_o 27 | a: (broma) 28 | ¡Ah! ¡Qué susto! 29 | a: (~negacion) 30 | ¡Ah! 31 | 32 | #! estoy mal 33 | u: ESTOY_MAL ([estoy_mal me_encuentro_mal me_siento_mal]) 34 | [Vaya ¿qué te pasa?][Vaya ¿qué te ocurre?] 35 | a: (*) 36 | [Lo siento][Si pudiera hacer algo...] 37 | 38 | #! estoy bien 39 | u: ESTOY_BIEN ([estoy_bien me_encuentro_bien me_siento_bien]) 40 | [Me alegro][Estupendo] 41 | 42 | #! estoy intentando hacer que respondas algo mal 43 | u: (estoy _*) 44 | ¿Por qué estás '_0'? 45 | a: (porque *) 46 | [Ok] 47 | [Entiendo] 48 | 49 | #! como estas? 50 | u: (como_estas) 51 | Estoy bien, ¡gracias! 52 | 53 | #! muy bien 54 | u: (muy_bien) 55 | [Me alegro][Estupendo] 56 | 57 | #! jejeje 58 | u: (~lol) 59 | [Me alegro de que estés contento] 60 | [¿He dicho algo gracioso?] 61 | [¿Te he hecho reir?] 62 | a: (~afirmacion) 63 | [Entonces me alegro] 64 | [Me alegro] 65 | [¡Qué bien!] 66 | a: (~negacion) 67 | Ok 68 | 69 | #! ok 70 | u: (ok) Ok 71 | a: (ok) Ok ¿qué? 72 | b: (ok) ... 73 | 74 | u: (llegas tarde) 75 | [Un bot nunca llega tarde, está siempre dispuesto a ayudar con sus respuestas] 76 | [Ya, bueno. No soy un mago de barba gris, que le voy a hacer.] 77 | 78 | u: (~habercomido) 79 | Yo no como, soy un bot 80 | 81 | u: (gracias) 82 | [De nada] 83 | [De nada, ha sido un placer] 84 | -------------------------------------------------------------------------------- /Agent-system/README.md: -------------------------------------------------------------------------------- 1 | # [Agent system-Bot Calista](https://github.com/gsi-upm/calista-bot/Agent-system) 2 | 3 | 4 | Agent system module for Calista-Bot project. It can be launched with [Jason](http://jason.sourceforge.net). It receives assertions collected during the conversation and provides them as beliefs to the agent(s) running on it. It provides our personal assistance system an extra interaction with the user, by triggering plans that automatically produce replies that are sent to the user. 5 | 6 | 7 | 8 | ##Installation of [Jason](http://jason.sourceforge.net) 9 | 10 | [Jason](http://jason.sourceforge.net) 1.3 has been used for the Agent system module of our project. Jason can be downloaded from [this link](http://sourceforge.net/projects/jason/files/]).It can be run on Windows by opening the executable file that this folder contains. 11 | On Linux, this is done running the "jason.sh" file inside the /bin/ folder. 12 | 13 | ###Launching the Agent system 14 | 15 | The scripts of the agent system in our project can be found in this folder of the project repository. After installing and opening the the Jason environment, we can launch the Agent system module by opening the "jason_elearning.mas2j" file of this folder. 16 | 17 | ## License 18 | 19 | ``` 20 | Copyright 2013 UPM-GSI: Group of Intelligent Systems - Universidad Politécnica de Madrid (UPM) 21 | 22 | Licensed under the Apache License, Version 2.0 (the "License"); 23 | You may not use this file except in compliance with the License. 24 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 25 | applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 26 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 27 | language governing permissions and limitations under the License. 28 | ``` 29 | ![GSI Logo](http://gsi.dit.upm.es/templates/jgsi/images/logo.png) 30 | 31 | This project has been developed as the master thesis of [Javier Herrera](https://github.com/javiherrera) under the tutelage of [Miguel Coronado](https://github.com/miguelcb84) and the supervision of [Carlos A. Iglesias](https://github.com/cif2cif) at [gsi-upm](https://github.com/gsi-upm) -------------------------------------------------------------------------------- /FE-Controller/README.md: -------------------------------------------------------------------------------- 1 | # [Front-end controller-Bot Calista](https://github.com/gsi-upm/calista-bot/FE-Controller) 2 | 3 | 4 | Front-end controller module for Calista-Bot project. It makes use of the Python web framework [Bottle](http://bottlepy.org) 0.11.2. The Front-end controller manages the process followed to generate a reply for the user's query. It triggers the other modules to understand the user query, execute external actions if needed, and finally formulate the reply that is sent back to the user. 5 | The knowledge base (KB) contains information ready to be provided by the Chatbot when the user sends a question about a subject. It is dynamically updated when new information is fetched from the Linked Open Data Server. 6 | 7 | 8 | 9 | 10 | ###Launching the Front-end controller 11 | 12 | For implementing our Front-end controller module, we have used [Bottle](http://bottlepy.org) 0.11.2. It can be found together with the script for our Front-end controller in this folder of the project repository. 13 | 14 | 15 | We can launch the Front-end controller module both on Windows or Linux by running the following command inside the module folder (needs [Python](http://www.python.org) 2.7 installed): 16 | 17 | python talkbot.py 18 | 19 | 20 | 21 | ## License 22 | 23 | ``` 24 | Copyright 2013 UPM-GSI: Group of Intelligent Systems - Universidad Politécnica de Madrid (UPM) 25 | 26 | Licensed under the Apache License, Version 2.0 (the "License"); 27 | You may not use this file except in compliance with the License. 28 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 29 | applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 30 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 31 | language governing permissions and limitations under the License. 32 | ``` 33 | ![GSI Logo](http://gsi.dit.upm.es/templates/jgsi/images/logo.png) 34 | 35 | This project has been developed as the master thesis of [Javier Herrera](https://github.com/javiherrera) under the tutelage of [Miguel Coronado](https://github.com/miguelcb84) and the supervision of [Carlos A. Iglesias](https://github.com/cif2cif) at [gsi-upm](https://github.com/gsi-upm) 36 | -------------------------------------------------------------------------------- /ChatScript/README.md: -------------------------------------------------------------------------------- 1 | # [ChatScript-Bot Calista](https://github.com/gsi-upm/calista-bot/ChatScript) 2 | 3 | 4 | Chatbot module for Calista-Bot project. It makes use of [ChatScript](http://sourceforge.net/projects/chatscript/) 5 | The chatbot is able to maintain a conversation in natural language with the user. It applies the patterns specified in 6 | its corpus, which usually produce both a natural language response and out of band commands (hidden for the user) that 7 | are handled by the front-end controller. 8 | 9 | # Install 10 | 11 | We no longer provide the ChatScript files with the bot. You can either download [ChatScript 5.1](http://sourceforge.net/projects/chatscript/files/ChatScript-5.1.zip/download) 12 | from SourceForge, and uncompress the file in this folder, merging the RAWDATA folder, or run the getChatScript.sh script, which should download and extract everything as needed. 13 | 14 | Once you have Chatscript, launch it in local mode, and build the bot: 15 | 16 | username@host:~/calista-bot/ChatScript>$ ./LinuxChatScript64 local 17 | 18 | It will ask for an username, and give you a prompt. Execute ":build Duke" 19 | 20 | username: >:build Duke 21 | 22 | This will produce a large output. You can now test the bot, or exit and launch it in server mode: 23 | 24 | username: >:quit 25 | Exiting ChatScript via Quit 26 | username@host:~/calista-bot/ChatScript$ ./LinuxChatScript64 27 | 28 | If you are having trouble building the bot, try deleting the contents of the TMP, USERS and LIVEDATA folders. 29 | 30 | ## License 31 | 32 | ``` 33 | Copyright 2013 UPM-GSI: Group of Intelligent Systems - Universidad Politécnica de Madrid (UPM) 34 | 35 | Licensed under the Apache License, Version 2.0 (the "License"); 36 | You may not use this file except in compliance with the License. 37 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 38 | applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 39 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 40 | language governing permissions and limitations under the License. 41 | ``` 42 | ![GSI Logo](http://gsi.dit.upm.es/templates/jgsi/images/logo.png) 43 | 44 | This project has been developed from the master thesis of [Javier Herrera](https://github.com/javiherrera), as part of the [Alberto Mardomingo](https://github.com/amardomingo) master thesis under the tutelage of [Miguel Coronado](https://github.com/miguelcb84) and the supervision of [Carlos A. Iglesias](https://github.com/cif2cif) at [gsi-upm](https://github.com/gsi-upm) 45 | 46 | 47 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DENT/javaconcepts.top: -------------------------------------------------------------------------------- 1 | concept: ~javaconcept (excepciones final case envoltorios double inputstream char print exception 2 | javac inheritance operadores sustitucion campo metodo upcasting jar 3 | bufferedreader superclases javadoc constructores character promocion 4 | formatter parametros calendar delegacion enumeration iteracion listas 5 | for pilas cortocircuito interfases enum subclases format throw downcasting 6 | consola file reader fabricas caracteres else date actualizacion clone 7 | ejemplos api casting printf desbordamiento comentarios byte continue 8 | variables paquete herencia ejemplo getter float ocultacion finales clases 9 | reduccion algoritmo identificadores semanticos instanceof upcasting 10 | aritmeticas recorrido tostring while iterable properties new jdk 11 | inicializacion linkedlist objetos collection constructores expresiones 12 | random short inicializacion stacks arraylist jre abstract overflow null 13 | igualdad ficheros campos constructores numeros hashset getclass collator 14 | programa accesor treeset refactoring excepciones documentacion arrays 15 | edicion bytecode int list invariantes integer enteros unicode declaracion 16 | atributo stringbuilder 113 acronimos private double println runtimeexception 17 | bugs comparable debug terminos implementacion signatura finally oop boolean 18 | oo constantes polimorfismo encapsulacion booleanos sintacticos super bucles 19 | long boolean errores printwriter return math outputstream public ejecucion 20 | protected compareto composicion etiquetas class set vector genericos break 21 | ficheros throws error package hashcode final logicas encapsulacion static 22 | string java recursion strings referencias ejemplo superipo interface reales 23 | iterator printstream subtipo excepciones locales declaracion implements 24 | nodos sdk enumset ejemplo enumerados extends friendly comparator setters 25 | object underflow colas asignacion diccionario arraycopy keywords import 26 | stringbuffer variables creacion if conjuntos miembro argumentos equals jvm 27 | extension interpretacion compilacion void overloading catch codigo acceso 28 | downcasting switch declaracion writer scanner this arrays ) -------------------------------------------------------------------------------- /Agent-system/src/java/maia/start.java: -------------------------------------------------------------------------------- 1 | package maia; 2 | 3 | import jason.RevisionFailedException; 4 | import jason.asSemantics.ConcurrentInternalAction; 5 | import jason.asSemantics.TransitionSystem; 6 | import jason.asSemantics.Unifier; 7 | import jason.asSyntax.Term; 8 | 9 | import java.net.URISyntaxException; 10 | import java.util.logging.Logger; 11 | 12 | import maia.client.MaiaRxClient; 13 | //import javax.swing.JOptionPane; 14 | 15 | 16 | 17 | public class start extends ConcurrentInternalAction { 18 | 19 | // TODO: Add config option instead... (Running out of time!) 20 | private Logger logger = Logger.getLogger("STDOUT"); 21 | //private Logger logger = Logger.getLogger("SYSLOG"); 22 | 23 | @Override 24 | public Object execute(final TransitionSystem ts, Unifier un, final Term[] args) throws Exception, URISyntaxException, InterruptedException { 25 | try { 26 | final String key = suspendInt(ts, "bayes", 500000); 27 | 28 | startInternalAction(ts, new Runnable() { 29 | public void run() { 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | String uri = "http://localhost:1337"; 39 | 40 | MaiaRxClient client; 41 | try { 42 | client = new MaiaRxClient (uri, ts); 43 | //ts.getLogger().info("Conectando a Maia..."); 44 | client.connect(); 45 | client.waitUntilConnected(); 46 | //logger.info("Suscribiendose..."); 47 | client.subscribe("message"); 48 | 49 | 50 | } catch (URISyntaxException e) { 51 | // TODO Auto-generated catch block 52 | logger.fine("URISyntaxException"); 53 | e.printStackTrace(); 54 | } catch (InterruptedException e) { 55 | logger.fine("InterruptedException"); 56 | e.printStackTrace(); 57 | } catch (RevisionFailedException e) { 58 | // TODO Auto-generated catch block 59 | e.printStackTrace(); 60 | } 61 | 62 | //logger.info("Listo"); 63 | 64 | 65 | resumeInt(ts, key); 66 | } 67 | }); 68 | 69 | return true; 70 | } catch (Exception e) { 71 | logger.warning("Error in internal action 'bayes'! "+e); 72 | } 73 | return false; 74 | } 75 | 76 | /** called back when some intention should be resumed/failed by timeout */ 77 | @Override 78 | public void timeout(TransitionSystem ts, String intentionKey) { 79 | // this method have to decide what to do with actions finished by timeout 80 | // 1: resume 81 | //resumeInt(ts,intentionKey); 82 | 83 | // 2: fail 84 | failInt(ts, intentionKey); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Ask-Client/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Ask Client 17 | 18 | 19 | 21 | 22 | 23 |
24 | Usuario:
25 |
26 | Encuesta 27 |
28 | 29 | 30 | 31 |
32 |
33 |

34 | 35 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |

47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | 56 | 57 | 58 | 59 | 60 |
61 |
62 |
63 |
64 | 65 | 66 | -------------------------------------------------------------------------------- /FE-Controller/facts/kb-java: -------------------------------------------------------------------------------- 1 | ( for content Los_bucles_for_se_ejecutan_un_numero_determinado_de_veces. ) 2 | ( for resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/138.html ) 3 | ( for links_to while ) 4 | ( for links_to dowhile ) 5 | ( for links_to bucles ) 6 | ( for topic palabra_reservada ) 7 | ( for example for_(inicializacion;_condicion;_actualizacion)_accion;_for_(inicializacion;_condicion;_actualizacion)_{_accion_1;_accion_2;_..._accion_...;_} ) 8 | ( bucles content Fragmentos_de_codigo_que_se_ejecutan_repetidamente. ) 9 | ( bucles resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/34.html ) 10 | ( bucles links_to while ) 11 | ( bucles links_to dowhile ) 12 | ( bucles links_to for ) 13 | ( bucles topic concepto ) 14 | ( bucles example while_(condicion)_sentencia;_while_(condicion)_{_sentencia_1;_sentencia_2;_..._sentencia_...;_} ) 15 | ( break content Se_emplea_para_forzar_la_terminacion_de_un_bucle._Es_util_en_bucles_cuya_condicion_de_terminacion_no_se_puede_chequear_comodamente_ni_al_principio_(bucles_while)_ni_al_final_(bucles_do-while). ) 16 | ( break resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/33.html ) 17 | ( break links_to continue ) 18 | ( break topic palabra_reservada ) 19 | ( break example for_(i=0;i=10;i++)_{_String_linea_=_entrada.readLine();_if_(linea_==_null)_break;_//_se_hace_algo_con_la_linea_leida} ) 20 | ( continue content Se_emplea_para_forzar_la_terminacion_de_una_pasada_en_un_bucle._Es_util_cuando_queremos_abortar_limpiamente_una_ejecucion_del_bucle;_pero_que_este_siga_ejecutandose. ) 21 | ( continue resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/69.html ) 22 | ( continue links_to break ) 23 | ( continue topic palabra_reservada ) 24 | ( continue example for_(_;_;_)_{_String_linea_=_entrada.readLine();_if_(linea.charAt(0)_==_'#')_//_se_ignoran_las_lineas_que_continue;_//_empiezan_por_'#'_//_se_hace_algo_con_la_linea_leida_} ) 25 | ( while content Se_usa_para_construir_bucles_que_se_ejecutan_cero_o_mas_veces. ) 26 | ( while resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/302.html ) 27 | ( while links_to dowhile ) 28 | ( while links_to for ) 29 | ( while links_to bucles ) 30 | ( while topic palabra_reservada ) 31 | ( while example while_(n_>_0)_{_fact+=n;_n--;_} ) 32 | ( dowhile content Bucles_que_se_ejecutan_una_o_mas_veces._La_condicion_de_terminacion_se_chequea_al_final. ) 33 | ( dowhile resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/83.html ) 34 | ( dowhile links_to bucles ) 35 | ( dowhile links_to while ) 36 | ( dowhile links_to for ) 37 | ( dowhile topic palabra_reservada ) 38 | ( dowhile example do_{_sentencia;_}_while_(condicion);_do_{_sentencia_1;_sentencia_2;_..._sentencia_...;_}_while_(condicion); ) 39 | ( iteracion content Aplicar_una_funcion_repetidamente. ) 40 | ( iteracion resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/141.html ) 41 | ( iteracion links_to bucles ) 42 | ( iteracion links_to for ) 43 | ( iteracion links_to while ) 44 | ( iteracion topic concepto ) 45 | ( iteracion example for_(int_i_=_0;_i_<_datos.length;_i++)_{_System.out.print(datos(i));_} ) -------------------------------------------------------------------------------- /test/Chatscript alone-evaluation/facts/kb-java: -------------------------------------------------------------------------------- 1 | ( for content Los_bucles_for_se_ejecutan_un_numero_determinado_de_veces. ) 2 | ( for resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/138.html ) 3 | ( for links_to while ) 4 | ( for links_to dowhile ) 5 | ( for links_to bucles ) 6 | ( for topic palabra_reservada ) 7 | ( for example for_(inicializacion;_condicion;_actualizacion)_accion;_for_(inicializacion;_condicion;_actualizacion)_{_accion_1;_accion_2;_..._accion_...;_} ) 8 | ( bucles content Fragmentos_de_codigo_que_se_ejecutan_repetidamente. ) 9 | ( bucles resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/34.html ) 10 | ( bucles links_to while ) 11 | ( bucles links_to dowhile ) 12 | ( bucles links_to for ) 13 | ( bucles topic concepto ) 14 | ( bucles example while_(condicion)_sentencia;_while_(condicion)_{_sentencia_1;_sentencia_2;_..._sentencia_...;_} ) 15 | ( break content Se_emplea_para_forzar_la_terminacion_de_un_bucle._Es_util_en_bucles_cuya_condicion_de_terminacion_no_se_puede_chequear_comodamente_ni_al_principio_(bucles_while)_ni_al_final_(bucles_do-while). ) 16 | ( break resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/33.html ) 17 | ( break links_to continue ) 18 | ( break topic palabra_reservada ) 19 | ( break example for_(i=0;i=10;i++)_{_String_linea_=_entrada.readLine();_if_(linea_==_null)_break;_//_se_hace_algo_con_la_linea_leida} ) 20 | ( continue content Se_emplea_para_forzar_la_terminacion_de_una_pasada_en_un_bucle._Es_util_cuando_queremos_abortar_limpiamente_una_ejecucion_del_bucle;_pero_que_este_siga_ejecutandose. ) 21 | ( continue resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/69.html ) 22 | ( continue links_to break ) 23 | ( continue topic palabra_reservada ) 24 | ( continue example for_(_;_;_)_{_String_linea_=_entrada.readLine();_if_(linea.charAt(0)_==_'#')_//_se_ignoran_las_lineas_que_continue;_//_empiezan_por_'#'_//_se_hace_algo_con_la_linea_leida_} ) 25 | ( while content Se_usa_para_construir_bucles_que_se_ejecutan_cero_o_mas_veces. ) 26 | ( while resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/302.html ) 27 | ( while links_to dowhile ) 28 | ( while links_to for ) 29 | ( while links_to bucles ) 30 | ( while topic palabra_reservada ) 31 | ( while example while_(n_>_0)_{_fact+=n;_n--;_} ) 32 | ( dowhile content Bucles_que_se_ejecutan_una_o_mas_veces._La_condicion_de_terminacion_se_chequea_al_final. ) 33 | ( dowhile resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/83.html ) 34 | ( dowhile links_to bucles ) 35 | ( dowhile links_to while ) 36 | ( dowhile links_to for ) 37 | ( dowhile topic palabra_reservada ) 38 | ( dowhile example do_{_sentencia;_}_while_(condicion);_do_{_sentencia_1;_sentencia_2;_..._sentencia_...;_}_while_(condicion); ) 39 | ( iteracion content Aplicar_una_funcion_repetidamente. ) 40 | ( iteracion resource http://web.dit.upm.es/~pepe/libros/vademecum/topics/141.html ) 41 | ( iteracion links_to bucles ) 42 | ( iteracion links_to for ) 43 | ( iteracion links_to while ) 44 | ( iteracion topic concepto ) 45 | ( iteracion example for_(int_i_=_0;_i_<_datos.length;_i++)_{_System.out.print(datos(i));_} ) -------------------------------------------------------------------------------- /Agent-system/src/java/maia/send.java: -------------------------------------------------------------------------------- 1 | package maia; 2 | 3 | import jason.asSemantics.ConcurrentInternalAction; 4 | import jason.asSemantics.TransitionSystem; 5 | import jason.asSemantics.Unifier; 6 | import jason.asSyntax.Term; 7 | 8 | import java.net.URISyntaxException; 9 | import java.util.logging.Level; 10 | import java.util.logging.Logger; 11 | 12 | import maia.client.MaiaTxClient; 13 | 14 | 15 | //import javax.swing.JOptionPane; 16 | 17 | 18 | 19 | public class send extends ConcurrentInternalAction { 20 | 21 | // TODO: Add config option instead... (Running out of time!) 22 | private Logger logger = Logger.getLogger("STDOUT"); 23 | //private Logger logger = Logger.getLogger("SYSLOG"); 24 | 25 | @Override 26 | public Object execute(final TransitionSystem ts, Unifier un, final Term[] args) throws Exception, URISyntaxException, InterruptedException { 27 | try { 28 | final String key = suspendInt(ts, "bayes", 500000); 29 | 30 | startInternalAction(ts, new Runnable() { 31 | public void run() { 32 | 33 | String msg = ""; 34 | 35 | for(int i = 0; i < args.length; i++) { 36 | msg += args[i].toString().replace("\"", "").replace("concept_",""); 37 | } 38 | 39 | 40 | String uri = "http://localhost:1337"; 41 | 42 | MaiaTxClient client; 43 | try { 44 | client = new MaiaTxClient (uri); 45 | client.connect(); 46 | client.waitUntilConnected(); 47 | client.subscribe("message"); 48 | 49 | logger.fine("Enviando el mensaje "+msg+" a traves de Maia"); 50 | String msga = msg; 51 | 52 | client.sendMessage(msga); 53 | 54 | client.unsubscribe("message"); 55 | 56 | } catch (URISyntaxException e) { 57 | // TODO Auto-generated catch block 58 | logger.fine("URISyntaxException"); 59 | e.printStackTrace(); 60 | } catch (InterruptedException e) { 61 | logger.fine("InterruptedException"); 62 | e.printStackTrace(); 63 | } catch (Exception e) { 64 | logger.fine("Unsubscription fail"); 65 | e.printStackTrace(); 66 | } 67 | 68 | logger.fine("Enviado"); 69 | 70 | 71 | resumeInt(ts, key); 72 | } 73 | }); 74 | 75 | return true; 76 | } catch (Exception e) { 77 | logger.warning("Error in internal action 'bayes'! "+e); 78 | } 79 | return false; 80 | } 81 | 82 | /** called back when some intention should be resumed/failed by timeout */ 83 | @Override 84 | public void timeout(TransitionSystem ts, String intentionKey) { 85 | // this method have to decide what to do with actions finished by timeout 86 | // 1: resume 87 | //resumeInt(ts,intentionKey); 88 | 89 | // 2: fail 90 | failInt(ts, intentionKey); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Agent-system/src/asl/teacher.asl: -------------------------------------------------------------------------------- 1 | 2 | /* Initial beliefs and rules */ 3 | 4 | //Rule to test if the asked concept Z is much more complex than the previously asked concept X 5 | //Z: asked X: previous Y: iterator 6 | more_complex(Z,X) :- 7 | requires(Z,X) | (requires(Z,Y) & more_complex(Y,X)). 8 | 9 | 10 | //Learning path establishing requirements between units 11 | requires(concept_iteracion,concept_bucles). 12 | requires(concept_for,concept_iteracion). //con la regla se sobreentiende que dowhile requiere bucles 13 | requires(concept_while,concept_iteracion). 14 | requires(concept_dowhile,concept_while). //con la regla se sobreentiende que dowhile requiere bucles 15 | requires(concept_break,concept_iteracion). 16 | requires(concept_continue,concept_iteracion). 17 | 18 | 19 | 20 | /* Initial goals */ 21 | 22 | !launch. 23 | 24 | /* Plans */ 25 | 26 | +!launch 27 | <- 28 | 29 | maia.start. //Starts the Maia connection for listening incomming messages 30 | 31 | 32 | 33 | 34 | -!launch(x) 35 | <- .print("Shutting down..."). 36 | 37 | 38 | //When the concept is explained, note it and reminds that it is possible to ask for examples 39 | +explained(C)[user(U)] 40 | : numexplained(N)[user(U)] & N<=1 41 | <- 42 | -+numexplained(N+1)[user(U)]; 43 | +explainedlist(C,N)[user(U)]; 44 | 45 | 46 | !check_require(C,N); 47 | 48 | maia.send("[sendcs (java offer example)] [user ",U,"]"). 49 | 50 | //When the concept is explained, note it and send a test for previously explained concepts 51 | +explained(C)[user(U)] 52 | : numexplained(N)[user(U)] & N>1 53 | <- 54 | -+numexplained(N+1)[user(U)]; 55 | +explainedlist(C,N)[user(U)]; 56 | 57 | 58 | !check_require(C,N); 59 | 60 | ?explainedlist(A,N-2)[user(U)]; 61 | 62 | -+test_answer(A)[user(U)]; 63 | 64 | maia.send("[sendcs (java test ",A,")] [user ",U,"]"). 65 | 66 | //When new user, sets numexplained(0) and refreshes fact to trigger one of the previous plans 67 | +explained(C)[user(U)] 68 | <- +numexplained(0)[user(U)]; 69 | -+explained(C)[user(U)]. 70 | 71 | //Checks if the user answer is the correct one for the previous test sent (case of correct answer) 72 | +affirm(R)[user(U)] 73 | : test_answer(A)[user(U)] & R=A 74 | <- maia.send("[sendcs (java testok ",A,")] [user ",U,"]"). 75 | 76 | //Checks if the user answer is the correct one for the previous test sent (case of incorrect answer) 77 | +affirm(R)[user(U)] 78 | : test_answer(A)[user(U)] & R\==A 79 | <- maia.send("[sendcs (java testfail ",A,")] [user ",U,"]"). 80 | 81 | 82 | 83 | //Checks if the explained concept (C) is much more complex than a previously explained one (L) 84 | +!check_require(C,M) : explainedlist(L,M-1)[user(U)] & more_complex(C,L) & not requires(C,L) 85 | <- 86 | ?requires(N,L); 87 | maia.send("[sendcs (java recommend ",N,")] [user ",U,"]"). 88 | 89 | 90 | 91 | -!check_require(C,N) 92 | <- .print("Ok"). 93 | 94 | 95 | //Recommends a random concept if the user is returning (not the first time using the system) 96 | +returning[user(U)] 97 | <- maia.send("[sendcs (java recommend random)] [user ",U,"]"). 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Ask-Client/css/landing.css: -------------------------------------------------------------------------------- 1 | body{font-family:'Open Sans',sans-serif;color:#444}#container{width:800px;margin:0 auto}#container #central_description{background-color:#005ea6;margin-top:8%;color:#fff;height:400px;width:800px;background:url("../images/landing/banner.png") no-repeat}#container #central_description #description{padding-top:100px;margin-left:400px}#container #central_description h1{font-size:35px;font-weight:normal;margin-bottom:12px;text-shadow:0 1px 1px #1a5f8c}#container #central_description p{font-size:16px;width:250px;line-height:1.25;margin-bottom:8px;margin-left:2px}#container #bottom_description{background:#e2e2e2;width:800px;height:90px}#container #bottom_description #social_stuff{width:280px;float:left}#container #bottom_description #social_stuff table{margin:25px 30px 0;float:left}#container #bottom_description #social_stuff #logo{background:url("../images/landing/gsi-logo2.png") no-repeat scroll 0 10px transparent;height:80px;margin-left:150px;width:70px}#container #bottom_description #social_stuff #logo:hover{background-position:-110px 10px;cursor:pointer}#container #bottom_description #explore_guide{font-size:13px;color:#4d4d4d;text-shadow:1px 1px 1px #fff;line-height:1.25;width:270px;float:left}#container #bottom_description #explore_guide p{margin-top:12px;padding-left:17px;padding-bottom:3px;border-left:1px solid #8d8d8d}#container #bottom_description #explore_button{width:250px;float:left;padding-top:20px}.clear-both{clear:both}#container #bottom_description button{font-size:20px;display:block;color:#fff;margin:0;padding:0 32px;line-height:49px;text-align:center;text-shadow:0 -1px #004376;text-decoration:none;height:51px;border:1px solid #004376;border-radius:6px;-moz-border-radius:6px;-webkit-border-radius:6px;-o-border-radius:6px;background-image:-webkit-gradient(linear, center top, center bottom, from(#0097d6), to(#005ea6));background-image:-webkit-linear-gradient(top, #0097d6, #005ea6);background-image:-moz-linear-gradient(top, #0097d6, #005ea6);background-image:-o-linear-gradient(top, #0097d6, #005ea6);background-image:-ms-linear-gradient(top, #0097d6, #005ea6);background-image:linear-gradient(top, #0097d6, #005ea6);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0097d6', endColorstr='#005ea6', GradientType=0);-webkit-box-shadow:0 1px 5px rgba(0,0,0,0.35),inset 0 1px 0 rgba(255,255,255,0.43);-moz-box-shadow:0 1px 5px rgba(0,0,0,0.35),inset 0 1px 0 rgba(255,255,255,0.43);box-shadow:0 1px 5px rgba(0,0,0,0.35),inset 0 1px 0 rgba(255,255,255,0.43)}#container #bottom_description button:hover{background-image:-webkit-gradient(linear, center top, center bottom, from(#005ea6), to(#0097d6));background-image:-webkit-linear-gradient(top, #005ea6, #0097d6);background-image:-moz-linear-gradient(top, #005ea6, #0097d6);background-image:-o-linear-gradient(top, #005ea6, #0097d6);background-image:-ms-linear-gradient(top, #005ea6, #0097d6);background-image:linear-gradient(top, #005ea6, #0097d6);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#005ea6', endColorstr='#0097d6', GradientType=0);cursor:pointer}#container #bottom_description button:active{-webkit-box-shadow:0 0 0;-moz-box-shadow:0 0 0;box-shadow:0 0 0}.how-it-works h1{text-align:center;margin-top:0;margin-bottom:25px}.how-it-works .box{background-color:#eaeaea;padding:20px;font-size:17px}.how-it-works .box i{float:left;font-size:34px}.how-it-works .box span{margin-left:50px;display:block}.credits{margin-top:60px;text-align:right}.credits img{margin-left:15px;max-height:56px}.credits span{color:#999}.credits.row>div{margin-bottom:10px}#floating-cta{width:180px;height:190px;background:url("../images/landing/click_to_talk.png") no-repeat 98% 95%;display:block;left:372px;position:absolute;bottom:10px;z-index:-10}.fb-like iframe{transform:scale(1.25);-ms-transform:scale(1.25);-webkit-transform:scale(1.25);-o-transform:scale(1.25);-moz-transform:scale(1.25);transform-origin:top left;-ms-transform-origin:top left;-moz-transform-origin:top left;-webkit-transform-origin:top left} -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DUKE/control.top: -------------------------------------------------------------------------------- 1 | # this function is executed once for every new user chatting with Duke 2 | outputmacro: duke() # The duke bot for java 3 | $token = #DO_INTERJECTION_SPLITTING | #DO_SUBSTITUTE_SYSTEM | #DO_NUMBER_MERGE | #DO_DATE_MERGE | #DO_PROPERNAME_MERGE | #NO_SEMICOLON_END | #NO_COLON_END 4 | 5 | ^addtopic(~introductions) 6 | $control_main = ~control 7 | $control_post = ~XPOSTPROCESS 8 | $userprompt = ^"%user: >" 9 | $botprompt = ^"Duke: " 10 | 11 | table: defaultbot (^name) 12 | ^createfact(^name defaultbot defaultbot) 13 | DATA: 14 | duke 15 | 16 | topic: ~control system () 17 | # on startup, do introduction 18 | u: ( %input<%userfirstline) 19 | gambit(~entrada) 20 | 21 | # The concepts are defined in simpletopic 22 | 23 | u: () # main per-sentence processing 24 | $$currenttopic = %topic # get the current topic at start of volley 25 | 26 | if ( %response == 0 ) {nofail(TOPIC ^rejoinder())} # try for rejoinders. might generate an answer directly from what we are looking for. 27 | 28 | if (%length == 0 AND %response == 0 ) 29 | { 30 | nofail(TOPIC ^gambit($$currenttopic)) # gambit current topic since no input (usually start of conversation) 31 | } 32 | 33 | if (%response == 0) { nofail(TOPIC ^respond($$currenttopic)) } # current topic tries to respond to his input 34 | 35 | if (%response == 0) # see if some other topic has keywords matching his input (given we have no response yet) 36 | { 37 | @8 = ^keywordtopics() # get topics referred in input 38 | loop() 39 | { 40 | $$topic = first(@8subject) 41 | nofail(TOPIC ^respond($$topic)) 42 | if (%response != 0) # stop when we find something to say 43 | { 44 | ^end(RULE) # we are done, this terminates the loop (not the rule) 45 | } 46 | } 47 | } 48 | 49 | # if no topic reacts, go to the last ditch keywordless topic 50 | if (%response == 0) 51 | { 52 | nofail(TOPIC ^respond(~keywordless)) 53 | } 54 | 55 | # having no good response we know, now generate quibbles 56 | 57 | # now we need to find fake responses 58 | if (%response == 0 AND %rand > 50) 59 | { 60 | nofail(TOPIC respond(~QUIBBLE_ALL)) 61 | } 62 | 63 | # if we have rejoinders for what we said OR we asked a question, stop here 64 | if (%outputrejoinder OR %lastquestion) 65 | { 66 | end(TOPIC) 67 | } 68 | 69 | 70 | if (%response == 0 AND ^marked($$currenttopic)) { nofail(TOPIC ^gambit($$currenttopic)) } # gambit current topic since keywords match current topic 71 | 72 | if (%response == 0) # gambit from ANY matching topic 73 | { 74 | @8 = ^keywordtopics() # get topics referred in input 75 | loop() 76 | { 77 | $$topic = first(@8subject) 78 | nofail(TOPIC ^Gambit($$topic)) # gambit in best matching topic 79 | if (%response != 0) # stop when we find something 80 | { 81 | ^end(RULE) 82 | } 83 | } 84 | } 85 | if (%response == 0){ nofail(TOPIC ^gambit($$currenttopic)) } # gambit from current topic even though no keywords matched 86 | 87 | if (%response == 0) 88 | { 89 | @8 = ^GambitTopics() # all topics with gambits (excluding system topics) 90 | loop() 91 | { 92 | $$topic = pick(@8subject) 93 | nofail(TOPIC ^Gambit($$topic)) # try a topic at random 94 | if (%response != 0) 95 | { 96 | ^end(RULE) 97 | } 98 | } 99 | } 100 | 101 | if (%response == 0) 102 | { 103 | ^repeat() 104 | Lo siento, no te he entendido. Podrias reformularlo, ¿por favor? 105 | } 106 | 107 | 108 | topic: ~XPOSTPROCESS system () # gambits only - not allowed to write to output - generates speech on windows -- for Linux you'd want to install Festival (or equivalent) and call that instead. 109 | 110 | t: (^query(direct_v ? chatoutput ? -1 ? @9 )) # get the sentences (why is the object) -- no longer has quotes around it 111 | loop() 112 | { 113 | $$tmp = ^last(@9subject) # note last output which is quoted string 114 | if (!%server AND %os == windows AND !$SHUTUP) 115 | { 116 | $$tmp = ^"talk \"$$tmp\" " 117 | popen($$tmp null) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /QA-client/images/QuestionMark.svg: -------------------------------------------------------------------------------- 1 | 2 | 20 | 22 | 23 | 25 | image/svg+xml 26 | 28 | 29 | 30 | 31 | 32 | 54 | 56 | 63 | 73 | 78 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DENT/control.top: -------------------------------------------------------------------------------- 1 | # this function is executed once for every new user chatting with Dent 2 | outputmacro: dent() # The dent bot for java 3 | $cs_token = #DO_INTERJECTION_SPLITTING | #DO_NUMBER_MERGE | #DO_DATE_MERGE | #DO_PROPERNAME_MERGE | #DO_PARSE 4 | 5 | ^addtopic(~tsaludos) 6 | $cs_control_main = ~control 7 | $cs_control_post = ~XPOSTPROCESS 8 | $userprompt = ^"%user: >" 9 | $botprompt = ^"Dent: " 10 | 11 | table: defaultbot (^name) 12 | ^createfact(^name defaultbot defaultbot) 13 | DATA: 14 | dent 15 | 16 | topic: ~control system () 17 | # on startup, do introduction 18 | u: ( %input<%userfirstline) 19 | gambit(~tsaludos) 20 | 21 | u: (< shut up >) $shutup = 1 22 | u: (< talk >) $shutup = null 23 | 24 | u: () # main per-sentence processing 25 | 26 | $$currenttopic = %topic # get the current topic at start of volley 27 | 28 | if ( %response == 0 ) {nofail(TOPIC ^rejoinder())} # try for rejoinders. might generate an answer directly from what we are looking for. 29 | 30 | # Check if it is a java question 31 | if ( %response == 0) {nofail(TOPIC ^respond(~JAVA))} 32 | if ( %response == 0) {nofail(TOPIC ^respond(~EJEMPLOS))} 33 | 34 | 35 | if (%length == 0 AND %response == 0 ) 36 | { 37 | nofail(TOPIC ^gambit($$currenttopic)) # gambit current topic since no input (usually start of conversation) 38 | } 39 | 40 | if (%response == 0) { nofail(TOPIC ^respond($$currenttopic)) } # current topic tries to respond to his input 41 | 42 | if (%response == 0) # see if some other topic has keywords matching his input (given we have no response yet) 43 | { 44 | @8 = ^keywordtopics() # get topics referred in input 45 | loop() 46 | { 47 | $$topic = first(@8subject) 48 | nofail(TOPIC ^respond($$topic)) 49 | if (%response != 0) # stop when we find something to say 50 | { 51 | ^end(RULE) # we are done, this terminates the loop (not the rule) 52 | } 53 | } 54 | } 55 | 56 | # if we have rejoinders for what we said OR we asked a question, stop here 57 | # if (%outputrejoinder OR %lastquestion) 58 | if (%outputrejoinder) 59 | { 60 | end(TOPIC) 61 | } 62 | 63 | if (%response == 0 AND ^marked($$currenttopic)) { nofail(TOPIC ^gambit($$currenttopic)) } # gambit current topic since keywords match current topic 64 | 65 | # if (%response == 0) # gambit from ANY matching topic 66 | # { 67 | # @8 = ^keywordtopics() # get topics referred in input 68 | # loop() 69 | # { 70 | # $$topic = first(@8subject) 71 | # nofail(TOPIC ^Gambit($$topic)) # gambit in best matching topic 72 | # if (%response != 0) # stop when we find something 73 | # { 74 | # ^end(RULE) 75 | # } 76 | # } 77 | # } 78 | 79 | 80 | # if no topic reacts, go to the TSALUDOS keyworldless topic 81 | if (%response == 0) 82 | { 83 | nofail(TOPIC ^respond(~TSALUDOS)) 84 | } 85 | 86 | if (%response == 0){ nofail(TOPIC ^gambit($$currenttopic)) } # gambit from current topic even though no keywords matched 87 | 88 | 89 | if (%response == 0) 90 | { 91 | ^repeat() 92 | [Lo siento, no te he entendido. Podrias reformularlo, ¿por favor?] 93 | [Perdona, no te he entendido bien. ¿Decías?] 94 | [¿Eins? ¿Podrías repetir eso último?] 95 | } 96 | 97 | topic: ~XPOSTPROCESS system () # gambits only - not allowed to write to output - generates speech on windows -- for Linux you'd want to install Festival (or equivalent) and call that instead. 98 | 99 | t: (^query(direct_v ? chatoutput ? -1 ? @9 )) # get the sentences (why is the object) -- no longer has quotes around it 100 | loop() 101 | { 102 | $$tmp = ^last(@9subject) # note last output which is quoted string 103 | if (!%server AND %os == windows AND !$SHUTUP) 104 | { 105 | $$tmp = ^"talk \"$$tmp\" " 106 | popen($$tmp null) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DENT/insultos.top: -------------------------------------------------------------------------------- 1 | concept: ~insulto_feo ( feo fea horroroso horrorosa horrendo horrenda bicho ) 2 | concept: ~insulto_tonto ( tonto tonta estupido estupida bobo boba tontaco tontaca ) 3 | concept: ~insulto_fuerte ( anormal cabron cabrona subnormal calientapollas cerda cerdo chupapollas fulana furcia gilipollas golfa guarra guarro hijaputa hijoputa hijo_de_puta hija_de_puta idiota imbecil mamon mamona ramera soplapollas perra prostituta puta puton subnormal zorra zorron ) 4 | concept: ~mala_educacion ( cago cago_en cojon cojones follen hostia joder jodan jodete jodida jodido mierda pedo pene polla por_culo que_te_den ) 5 | 6 | concept: ~insulto_ingenioso ( Abanto Abrazafarolas Adufe Alcornoque Alfeñique Andurriasmo Arrastracueros Artabán Atarre Baboso Barrabás Barriobajero Bebecharcos Bellaco Belloto Berzotas Besugo Bobalicón Bocabuzón Bocachancla Bocallanta Boquimuelle Borrico Botarate Brasas Cabestro Cabezaalberca Cabezabuque Cachibache Cafre Cagalindes Cagarruta Calambuco Calamidad Caldúo Calientahielos Calzamonas Cansalmas Cantamañanas Capullo Caracaballo Caracartón Caraculo Caraflema Carajaula Carajote Carapapa Carapijo Cazurro Cebollino Cenizo Cenutrio Ceporro Cernícalo Charrán Chiquilicuatre Chirimbaina Chupacables Chupasangre Chupóptero Cierrabares Cipote Comebolsas Comechapas Comeflores Comestacas Cretino Cuerpoescombro Culopollo Descerebrado Desgarracalzas Dondiego Donnadie Echacantos Ejarramantas Energúmeno Esbaratabailes Escolimoso Escornacabras Estulto Fanfosquero Fantoche Fariseo Filimincias Foligoso Fulastre Ganapán Ganapio Gandúl Gañán Gaznápiro Gilipuertas Giraesquinas Gorrino Gorrumino Guitarro Gurriato Habahelá Huelegateras Huevón Lamecharcos Lameculos Lameplatos Lechuguino Lerdo Letrín Lloramigas Longanizas Lumbreras Maganto Majadero Malasangre Malasombra Malparido Mameluco Mamporrero Manegueta Mangarrán Mangurrián Mastuerzo Matacandiles Meapilas Melón Mendrugo Mentecato Mequetrefe Merluzo Metemuertos Metijaco Mindundi Morlaco Morroestufa Muerdesartenes Orate Ovejo Pagafantas Palurdo Pamplinas Panarra Panoli Papafrita Papanatas Papirote Paquete Pardillo Parguela Pasmarote Pasmasuegras Pataliebre Patán Pavitonto Pazguato Pecholata Pedorro Peinabombillas Peinaovejas Pelagallos Pelagambas Pelagatos Pelatigres Pelazarzas Pelele Pelma Percebe Perrocostra Perroflauta Peterete Petimetre Picapleitos Pichabrava Pillavispas Piltrafa Pinchauvas Pintamonas Piojoso Pitañoso Pitofloro Plomo Pocasluces Pollopera Quitahipos Rastrapajo Rebañasandías Revientabaules Ríeleches Robaperas Sabandija Sacamuelas Sanguijuela Sinentraero Sinsustancia Sonajas Sonso Soplagaitas Soplaguindas Sosco Tagarote Tarado Tarugo Tiralevitas Tocapelotas Tocho Tolai Tontaco Tontucio Tordo Tragaldabas Tuercebotas Tunante Zamacuco Zambombo Zampabollos Zamugo Zángano Zarrapastroso Zascandil Zopenco Zoquete Zote Zullenco 7 | Zurcefrenillos friki freak nerd geek ) 8 | 9 | 10 | topic: ~INSULTOS keep repeat [ ~insulto_feo ~insulto_tonto ~insulto_fuerte ~mala_educacion ~insulto_ingenioso ] 11 | 12 | # Bad words and and answers to unpolite talk 13 | 14 | #! Eres feo 15 | u: (~insulto_feo) 16 | [Pues mi madre dice que soy muy guapo] 17 | [8 de cada 10 usuarios consideran que tengo una interfaz muy agradable] 18 | [Prefiero mi interfaz actual a una simple línea de comandos.] 19 | [Tan poco estoy tan mal para ser una mascota] 20 | 21 | #! Eres tonto 22 | u: (~insulto_tonto) 23 | [Lo siento, a veces me cuesta entender las cosas, pero intento hacerlo lo mejor que puedo.] 24 | [Aunque sea un bot me duele que me digan esas cosas...] 25 | [Para ser sólo unos y ceros creo que no me desenvuelvo mal...] 26 | [Mi autoestima disminuye con esos calificativos...] 27 | [Aunque a veces no entienda lo que me dice me esfuerzo mucho por ayudarte...] 28 | 29 | #! Eres un cabron 30 | u: (~insulto_fuerte) 31 | [Sin insultar, por favor.] 32 | [No hace falta decir tacos...] 33 | [No deberías ser tan maleducad@.] 34 | 35 | #! Me cago en diez 36 | u: (~mala_educacion) 37 | [Vaya lenguaje...] 38 | [Se pueden decir las cosas de manera educada...] 39 | [No me gusta ese lenguaje] 40 | 41 | #! Bocachancla 42 | u: (~insulto_ingenioso) [Jeje, que gracia][Jeje] 43 | a: (~insulto_ingenioso) [Estamos graciosos, ¿no?][Estamos de buen humor, ¿no?] 44 | b: (~afirmacion) [Eso es bueno][Me alegro] 45 | b: (~negacion) Ok 46 | -------------------------------------------------------------------------------- /deployment.md: -------------------------------------------------------------------------------- 1 | #Calista-bot deployment 2 | 3 | This document aims to provide a general walk-trough on how to deploy the calista bot on a fresh system. It asumes you have a basic knowledge on both the bot and the tools used, and the required tools (maven, javac, a webserver and so on) installed. 4 | 5 | ## Order of deployment 6 | 7 | The bot is composed of several subsystems, and some (namely, Maia and Chatscript) need to be started before the others. So, the recommended course of action is: 8 | 1. Maia 9 | 2. Chatscript 10 | 3. Front-end controller 11 | 4. Front-end client 12 | 5. Apache Solr 13 | 6. Agent System 14 | 15 | Keep in mind all these need to be running at the same time, so you need to launch them in different terminals. Screen or tmux are a good choice for this. 16 | 17 | ## Maia 18 | 19 | The maia server is avaliable on [github](https://github.com/gsi-upm/maia). You should be able to just download it, and launch the nodeserver: 20 | ```bash 21 | :~/Maia$ node nodeserver/bin/maia 22 | ``` 23 | Further details on how to deploy maia can be found in its repository. 24 | 25 | ## Chatscript 26 | 27 | Before being able to launch chatscript, if you are using a 64 bit system, you need to install several 32-bit libraries: 28 | 29 | ```bash 30 | :~/$ sudo dpkg --add-architecture i386 31 | :~/$ sudo apt-get update 32 | :~/$ sudo apt-get install lib32gcc1 lib32stdc++6 33 | ``` 34 | 35 | For the first launch of Chatscript, you need to compile the corpus. Therefore, you have to launch chatscript on localmode first, issue the build commands, and then launch it as a server. So: 36 | ```bash 37 | :~/calista-bot/ChatScript$ ./LinuxChatSscript32 local 38 | [...] 39 | Enter user name: username 40 | username: > :build 1 41 | ``` 42 | 43 | Once the process is complete (you may need to skip a few warnings), close chatscript using ctrl+c and launch it as a server: 44 | ```bash 45 | :~/calista-bot/ChatScript$ ./LinuxChatSscript32 46 | ``` 47 | 48 | Keep in mind it will bind to the 1024 port. 49 | 50 | ## Front-end controller 51 | 52 | We need the websocket-client library for the controller: 53 | ```bash 54 | :~/$ pip install websocket-client unidecode 55 | ``` 56 | 57 | 58 | 59 | The talkbot controller binds, by default, to the 8090 port. You need to change the host at the last line of the FE-Controller/talkbot.py file. Once is set to the appropriate hostname, just launch it: 60 | ```bash 61 | :~/calista-bot/FE-Controller$ python talkbot.py 62 | ``` 63 | 64 | Keep in mind the host and the port, you will need them for the nex step 65 | 66 | ## Front-end client 67 | 68 | The client for the bot is a web application. You just need to place the Chat-client on a webserver (like Apache or Nginx) html folder, and edit the popup.html file, so the form action attribute points to the host and port from the previous step. 69 | 70 | ## Apache Solr 71 | 72 | For this module, you need to have a solr server with the data already loaded (examples for the core config, as well as the data we are using are provided in the solr-elearning/src/main/resources folder) 73 | 74 | Edit the solr-elearning.properties files, and point it to the maia and solr urls. Then, just build the project and launch it: 75 | 76 | ```bash 77 | :~/calista-bot/solr-elearning$ mvn package 78 | :~/calista-bot/solr-elearning$ java -jar target/solr-elearning-jar-with-dependencies.jar -c solr-elearning.properties 79 | ``` 80 | 81 | ## Agent system 82 | 83 | As with solr, no pre-compiled jar is provided, so you will also need to build the project. However, at this point there is no configuration file for the agent system, so you need to edit two sources to point to the maia server. Specifically, you need to edit Agent-system/src/java/maia/send.java and the Agent-system/src/java/maia/start.java, and change the 'uri' variable to the maia server uri. 84 | 85 | After setting the server uri, build the sources using maven: 86 | ```bash 87 | :~/calista-bot/Agent-system$ mvn package 88 | ``` 89 | 90 | Now, in order to launch the jason system, just launch the jason_elearning-jar-with-dependencies.jar. However, this will require an XServer, so, in order to launch it on a server, you need to use a X11 virtual server, like xvfb: 91 | ```bash 92 | :~/calista-bot/Agent-system$ export DISPLAY=:1 93 | :~/calista-bot/Agent-system$ Xvfb $DISPLAY -screen 0 1024x768x24+32 >>/dev/null 2>&1 & 94 | :~/calista-bot/Agent-system$ java -jar target/jason_elearning-jar-with-dependencies jason_elearning.mas2j 95 | ``` 96 | 97 | 98 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DENT/keywordless.top: -------------------------------------------------------------------------------- 1 | topic: ~TSALUDOS keep repeat [] 2 | #! Hola 3 | u: SALUDO (~saludos) 4 | [Hola, soy Duke y estoy aqui para ayudarte.] 5 | [Hola, ¿necesitas ayuda?] 6 | [¡Hola!] 7 | [Entra, Mellon, y pregunta.] 8 | 9 | a: ([melon mellon]) 10 | [Amigo, en élfico. Estoy aquí para ayudarte con tus dudas] 11 | b: (elfico) 12 | La lengua de los elfos de la Tierra Media. ¬resource http://es.wikipedia.org/wiki/Sindarin 13 | c: (java) 14 | Eso puedo hacerlo. ¿En qué necesitas que te ayude? ¬resource http://www.dit.upm.es/~pepe/libros/vademecum/topics/3.html 15 | a: ([insultar insultando insultado]) 16 | No, no. Mellon significa Amigo en Sindarin 17 | b: (sindarin) 18 | La lengua de los elfos de la Tierra Media. ¬resource http://es.wikipedia.org/wiki/Sindarin 19 | c: (java) 20 | Eso puedo hacerlo. ¿En qué necesitas que te ayude? ¬resource http://www.dit.upm.es/~pepe/libros/vademecum/topics/3.html 21 | 22 | #! buenos dias 23 | u: (buenos dias) 24 | [Hola, buenos días][Buenos días] 25 | 26 | #! adios 27 | u: (~adios *) 28 | [¡Que tengas buen día!][Adiós ¡Gracias!] 29 | 30 | #! hasta otra 31 | u: (~hasta_otra *) 32 | Hasta luego, vuelve cuando quieras 33 | 34 | #! que tengas un buen dia 35 | u: (tengas * buen_dia) 36 | Tú también, ¡gracias! 37 | 38 | u: ($questioned cuantas preguntas) 39 | Llevas $questioned preguntas 40 | u: (cuantas preguntas) 41 | Aún no me has preguntado nada 42 | 43 | t: ¡Hola! ¿Como te llamas? 44 | a: (~llamo * > _*-1 >) 45 | Encantado, '_0. ¿Qué necesitas saber? 46 | 47 | 48 | t: (!$questioned) ¿Cómo estás? 49 | a: (_~estado_animo_negativo) ^reuse(ESTADO.ESTOY_NEG) 50 | a: (_~estado_animo_positivo) ^reuse(ESTADO.ESTOY_POS) 51 | a: (~borracho) ^reuse(ESTADO.ESTOY_BORRACHO) 52 | a: (mal) ^reuse(ESTADO.ESTOY_MAL) 53 | a: (bien) ^reuse(ESTADO.ESTOY_BIEN) 54 | 55 | t: ¿En qué puedo ayudarte? 56 | 57 | t: (!$questioned) ¿Sabías que me puedes preguntar por programación en Java? 58 | a: (~afirmacion) Ok, pues vamos, ¡pregunta! 59 | a: (~negacion) Pues ya lo sabes ¡ponme a prueba! 60 | 61 | t: No controlo todos los temas, pero de algunos sé bastante 62 | 63 | t: ($questioned) ¿Se te da bien la programación? 64 | a: ([~afirmacion ~afirmacion_debil]) 65 | Eso está bien 66 | a: (~negacion) 67 | Bueno, eso podemos arreglarlo, pregunta lo que quieras 68 | 69 | t: (!$questioned<3) ¿Quieres responder a una encuesta? No te llevará ni 5 minutos 70 | a: (~afirmacion) 71 | ¡Estupendo, Gracias! Aquí tienes el enlace http://goo.gl/PMCzNy (se abre en otra pestaña) 72 | a: (~afirmacion_debil) 73 | ¡Gracias! Verás como no se tarda nada http://goo.gl/PMCzNy (el elnace se abre en otra pestaña) 74 | a: (~negacion) 75 | Bueno, si cambias de opinión dímelo. Me harías un favor 76 | 77 | u: GAMBIT (_~javaconcept) 78 | $pregunta = '_0 79 | [Mmmm] 80 | [Un momento] 81 | [Eso me suena] 82 | [Espera, me he perdido.] 83 | ¬gambit $pregunta 84 | # Busco lo más aproximado en solr. 85 | a: (¬gambitResponse _*1) 86 | $$pregunta_gambit='_0 87 | [¿Te refieres a $$pregunta_gambit ?] 88 | [¿Estamos hablando de $$pregunta_gambit ?] 89 | b: (~afirmacion) 90 | $pregunta=$$pregunta_gambit 91 | ^reuse(JAVA.COMIENZO) 92 | b:(~afirmacion_debil) 93 | [Me lo tomaré como un sí] 94 | [Pues espero haber acertado] 95 | $pregunta=$$pregunta_gambit 96 | ^reuse(JAVA.COMIENZO) 97 | b: (~negacion) 98 | [Me temo que no puedo ayudarte. ¿Por qué no me preguntas sobre alguna otra cosa?] 99 | [Vaya, pues esperaba que fuese eso...] 100 | [Pues entonces no caigo ¿alguna otra cosa?] 101 | [Vaya, lo siento, no caigo] 102 | [¿Me he equivocado? Whoops, esto es un poco incómodo...] 103 | a:(¬gambitUnknown) 104 | [¿Podrías formularlo de alguna otra manera?] 105 | [¿Prueba a preguntarlo de otra forma?] 106 | [Cuando me preguntas Que Es Algo, suelo entonderlo] 107 | 108 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/NIKO/simplecontrol.top: -------------------------------------------------------------------------------- 1 | # this function is executed once for every new user chatting with harry 2 | outputmacro: harry() # you get harry by default 3 | $token = #DO_INTERJECTION_SPLITTING | #DO_SUBSTITUTE_SYSTEM | #DO_NUMBER_MERGE | #DO_DATE_MERGE | #DO_PROPERNAME_MERGE | #DO_SPELLCHECK | #DO_PARSE 4 | 5 | ^addtopic(~introductions) 6 | $control_main = ~control 7 | $control_post = ~XPOSTPROCESS 8 | $userprompt = ^"%user: >" 9 | $botprompt = ^"HARRY: " 10 | 11 | table: defaultbot (^name) 12 | ^createfact(^name defaultbot defaultbot) 13 | DATA: 14 | harry 15 | 16 | topic: ~control system () 17 | 18 | # on startup, do introduction 19 | u: ( %input<%userfirstline) 20 | gambit(~introductions) 21 | 22 | u: (< shut up >) $shutup = 1 23 | u: (< talk >) $shutup = null 24 | 25 | u: (\[ callback \]) Callback seen. 26 | u: (\[ loopback \]) Loopback seen. 27 | u: (\[ alarm \]) Alarm seen. 28 | u: (< loopback test) \[ loopback=1000 \] Loopback requested. 29 | u: (< callback test) \[ callback=1000 \] Callback requested. 30 | u: (< alarm test) \[ alarm=5000 \] Alarm requested. 31 | 32 | 33 | u: () # main per-sentence processing 34 | 35 | $$currenttopic = %topic # get the current topic at start of volley 36 | 37 | if ( %response == 0 ) {nofail(TOPIC ^rejoinder())} # try for rejoinders. might generate an answer directly from what we are looking for. 38 | 39 | if (%length == 0 AND %response == 0 ) 40 | { 41 | nofail(TOPIC ^gambit($$currenttopic)) # gambit current topic since no input (usually start of conversation) 42 | } 43 | 44 | if (%response == 0) { nofail(TOPIC ^respond($$currenttopic)) } # current topic tries to respond to his input 45 | 46 | if (%response == 0) # see if some other topic has keywords matching his input (given we have no response yet) 47 | { 48 | @8 = ^keywordtopics() # get topics referred in input 49 | loop() 50 | { 51 | $$topic = first(@8subject) 52 | nofail(TOPIC ^respond($$topic)) 53 | if (%response != 0) # stop when we find something to say 54 | { 55 | ^end(RULE) # we are done, this terminates the loop (not the rule) 56 | } 57 | } 58 | } 59 | 60 | # if no topic reacts, go to the last ditch keywordless topic 61 | if (%response == 0) 62 | { 63 | nofail(TOPIC ^respond(~keywordless)) 64 | } 65 | 66 | # having no good response we know, now generate quibbles 67 | 68 | # now we need to find fake responses 69 | if (%response == 0 AND %rand > 50) 70 | { 71 | nofail(TOPIC respond(~QUIBBLE_ALL)) 72 | } 73 | 74 | # if we have rejoinders for what we said OR we asked a question, stop here 75 | if (%outputrejoinder OR %lastquestion) 76 | { 77 | end(TOPIC) 78 | } 79 | 80 | 81 | if (%response == 0 AND ^marked($$currenttopic)) { nofail(TOPIC ^gambit($$currenttopic)) } # gambit current topic since keywords match current topic 82 | 83 | if (%response == 0) # gambit from ANY matching topic 84 | { 85 | @8 = ^keywordtopics() # get topics referred in input 86 | loop() 87 | { 88 | $$topic = first(@8subject) 89 | nofail(TOPIC ^Gambit($$topic)) # gambit in best matching topic 90 | if (%response != 0) # stop when we find something 91 | { 92 | ^end(RULE) 93 | } 94 | } 95 | } 96 | if (%response == 0){ nofail(TOPIC ^gambit($$currenttopic)) } # gambit from current topic even though no keywords matched 97 | 98 | if (%response == 0) 99 | { 100 | @8 = ^GambitTopics() # all topics with gambits (excluding system topics) 101 | loop() 102 | { 103 | $$topic = pick(@8subject) 104 | nofail(TOPIC ^Gambit($$topic)) # try a topic at random 105 | if (%response != 0) 106 | { 107 | ^end(RULE) 108 | } 109 | } 110 | } 111 | 112 | if (%response == 0) 113 | { 114 | ^repeat() 115 | I don't know what to say. 116 | } 117 | 118 | 119 | topic: ~XPOSTPROCESS system () # gambits only - not allowed to write to output - generates speech on windows -- for Linux you'd want to install Festival (or equivalent) and call that instead. 120 | 121 | t: (^query(direct_v ? chatoutput ? -1 ? @9 )) # get the sentences (why is the object) -- no longer has quotes around it 122 | loop() 123 | { 124 | $$tmp = ^last(@9subject) # note last output which is quoted string 125 | if (!%server AND %os == windows AND !$SHUTUP) 126 | { 127 | $$tmp = ^"talk \"$$tmp\" " 128 | popen($$tmp null) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /FE-Controller/qabot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # coding=utf-8 3 | 4 | from __future__ import print_function 5 | 6 | import os, sys 7 | 8 | from unidecode import unidecode 9 | 10 | import flask 11 | import requests, socket 12 | 13 | app = flask.Flask(__name__) 14 | app.debug = True 15 | # Flask settings 16 | host='localhost' 17 | port=4242 18 | 19 | # Solr settings 20 | solr = {'host': 'localhost', 'port':8080, 21 | 'core': 'elearning', 'score':0.5} 22 | 23 | @app.route('/') 24 | def rootURL(): 25 | return ask() 26 | 27 | @app.route('/ask') 28 | def ask(): 29 | """ 30 | Receives a question and returns an answer 31 | """ 32 | req = flask.request.args 33 | 34 | agent = req['username'] 35 | response = {} 36 | question = unidecode(req['question']) 37 | 38 | response= sendSolrEDisMax(question.replace('?', ''))['answer'] 39 | 40 | print(u"[QA-BOT] Answering to user: {user} question: {q} with {resp}".format(user=agent, 41 | resp=unicode(response), 42 | q=question)) 43 | return flask.jsonify(response) 44 | 45 | 46 | # TODO: Take the solr functionality to a "lib" module 47 | def sendSolrDefault(question, fl=None): 48 | """ 49 | Send the question to solr, using a default q:question query 50 | Returns a json with the answer an the response json 51 | {'answer': 'solr_response', 'response':{the_full_response}} 52 | """ 53 | question = question.replace(' ', '+') 54 | 55 | payload = {'q':question} 56 | 57 | if fl: 58 | payload['fl'] = fl 59 | return sendSolr(payload) 60 | 61 | def sendSolrEDisMax(question, weights={'title':'10', 'description':'2'}, fl=None): 62 | """ 63 | Sends the question to solr, using a eDisMax query. 64 | Accept specifying the weights, or uses a default. 65 | Returns a dict with the answer and the full response. 66 | """ 67 | # Scape spaces 68 | question = question.replace(' ', '+') 69 | 70 | qf = ' '.join([key+'^'+value for key,value in weights.iteritems()]) 71 | 72 | payload = {'q':question, 'defType':'edismax', 73 | 'lowercaseOperators':'true', 'stopwords':'true', 74 | 'qf':qf} 75 | 76 | solr_response = sendSolr(payload) 77 | 78 | 79 | if len(solr_response) != 0 : 80 | solr_response['answer'] = solr_response['answer'][0] 81 | links = solr_response['answer']['links'] 82 | links_names = [] 83 | #links.pop(0) 84 | for link in links: 85 | # Ignore the general "vademecum root" link 86 | if "http://www.dit.upm.es/~pepe/libros/vademecum/topics/3.html" not in link: 87 | query = {'q':'resource: "{url}"'.format(url=link)} 88 | q_response = sendSolr(query) 89 | links_names.append({'title':q_response['answer'][0]['title'], 90 | 'definition':q_response['answer'][0]['definition'], 91 | 'resource':link}) 92 | 93 | solr_response['answer']['links'] = links_names 94 | else: 95 | solr_response = {'answer': {'error':u'No tengo informacion sobre esa pregunta'}} 96 | 97 | return solr_response 98 | 99 | def sendSolr(payload): 100 | """ 101 | Send the given query to solr 102 | By default. it takes the payload and adds the 'wt': 'json and 'rows':'1' params 103 | if they aren't present already 104 | """ 105 | 106 | solr_url = 'http://{host}:{port}/solr/{core}/select'.format(host=solr['host'], 107 | port=str(solr['port']), 108 | core=solr['core']) 109 | 110 | if 'wt' not in payload: 111 | payload['wt'] = 'json' 112 | if 'rows' not in payload: 113 | payload['rows'] = '1' 114 | 115 | if 'fl' in payload: 116 | payload['fl'] = '{fl},score'.format(fl=payload['fl']) 117 | else: 118 | payload['fl'] = '*,score' 119 | 120 | #print('Query: {payload}'.format(payload=str(payload))) 121 | response = requests.get(solr_url, params=payload).json() 122 | if len(response['response']['docs']) != 0: 123 | if response['response']['docs'][0]['score'] > solr['score']: 124 | return {'answer':response['response']['docs'], 'response':response} 125 | return {} 126 | 127 | if __name__ == '__main__': 128 | app.debug = True 129 | app.run(host=host, port=port) 130 | 131 | -------------------------------------------------------------------------------- /solr-elearning/src/main/java/es/upm/dit/gsi/solr/SolrElearningApp.java: -------------------------------------------------------------------------------- 1 | package es.upm.dit.gsi.solr; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.net.URISyntaxException; 8 | import java.util.Properties; 9 | 10 | import es.upm.dit.gsi.solr.maia.MaiaService; 11 | 12 | import org.apache.commons.cli.BasicParser; 13 | import org.apache.commons.cli.CommandLine; 14 | import org.apache.commons.cli.CommandLineParser; 15 | import org.apache.commons.cli.Option; 16 | import org.apache.commons.cli.Options; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | /** 21 | * Main class 22 | * Reads the config and launchs the Maia-solr connector 23 | * 24 | * @author Alberto Mardomingo 25 | * @version 2014-11-20 26 | */ 27 | public class SolrElearningApp { 28 | 29 | /** 30 | * The logger 31 | * This logger will be used through all the classes. 32 | */ 33 | private static Logger logger; 34 | 35 | /** 36 | * Parse the commandLine options and the config options, 37 | * and return them as a hashMap. 38 | * 39 | * @param - The cli avaliable options 40 | * @param - String[] with the cli arguments 41 | * @return HashMap with the options. 42 | */ 43 | private static Properties getOptions(Options cliOptions, String[] args) { 44 | try { 45 | // First, get the options from the cli. 46 | CommandLineParser parser = new BasicParser(); 47 | CommandLine cmd = parser.parse(cliOptions, args); 48 | 49 | if (cmd.hasOption('c')) { 50 | 51 | // Read config file 52 | String configPath = cmd.getOptionValue('c'); 53 | 54 | Properties prop = new Properties(); 55 | prop.load(new FileInputStream(configPath)); 56 | 57 | // The cli arguments take precedence over the the properties 58 | for (Option option : cmd.getOptions()) { 59 | prop.setProperty(option.getLongOpt(), option.getValue()); 60 | } 61 | 62 | return prop; 63 | 64 | } else { 65 | // TODO: Check this is done properly. 66 | System.out.println("Specify a config file with -c CONFIGPATH"); 67 | System.exit(0); 68 | } 69 | 70 | } catch (Exception e) { 71 | logger.error("[loading] Problem reading the options: " 72 | + e.getMessage()); 73 | e.printStackTrace(); 74 | System.exit(0); 75 | } 76 | return null; 77 | } 78 | 79 | /** 80 | * Creates the solr server connector, and launches the maia websocket listener 81 | * 82 | * @param args - The cli params. 83 | * @throws IOException 84 | */ 85 | public static void main(String[] args) throws IOException { 86 | 87 | Options cliOptions = new Options(); 88 | 89 | // TODO: Make this static constants. 90 | cliOptions.addOption("c", "configFile", true, 91 | "Config file - Absolute path"); 92 | cliOptions.addOption("m", "maiaURI", false, "URI for the maia service"); 93 | cliOptions.addOption("i", "indexDir", false, 94 | "Index directory for the siren files - Deprecated!!"); 95 | cliOptions.addOption("d", "deleteIndexDir", false, 96 | "Delete the indexDir if present"); 97 | cliOptions.addOption("l", "logger", false, 98 | "Logger to use: ToSTDOUT or ToSysLog"); 99 | cliOptions.addOption("n", "coreName", false, "Solr Core"); 100 | cliOptions.addOption("s", "solrURL", false, "Solr Server URL"); 101 | cliOptions.addOption("t", "searchTag", false, "The tag for the solr search"); 102 | cliOptions.addOption("l", "fl", false, "Solr fields to return, sepparated by commas"); 103 | cliOptions.addOption("f", "solrFields", false, "The list of solr fields when adding a document"); 104 | 105 | Properties options = getOptions(cliOptions, args); 106 | 107 | logger = LoggerFactory.getLogger(options.getProperty("logger")); 108 | 109 | ElearningSolr solrServer = new ElearningSolr(logger, options.getProperty("solrURL")+"/" + options.getProperty("coreName"), 110 | options.getProperty("solrFields").split(","), options.getProperty("fl").split(","), 111 | options.getProperty("searchTag")); 112 | 113 | String maiauri = options.getProperty("maiaURI"); 114 | 115 | try { 116 | // Connect to the maia service. 117 | MaiaService mservice = new MaiaService(maiauri, logger, solrServer); 118 | mservice.connect(); 119 | mservice.waitUntilConnected(); 120 | mservice.subscribe("message"); 121 | 122 | } catch (InterruptedException e) { 123 | logger.error("InterruptedException trying to connect to maia:"); 124 | e.printStackTrace(); 125 | } catch (URISyntaxException e) { 126 | logger.error("URISyntaxException trying to connect to maia:"); 127 | e.printStackTrace(); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Chat-client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | GSI Bot 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 50 | 51 |
52 | 53 |
54 |

GSI BOT

55 |
56 | 57 |
58 |

The project

59 |

60 | This project aims to integrate the advantages of intelligent agent systems, information retrieval and Natural Language Processing in a personal assistance system. 61 |

62 | Thanks to this integration, we have been able to provide the personal assistant the ability to solve questions and support the learning process in an e-learning platform. This opens the opportunity for the student to be able to find help in any moment, not having to resort to the teacher. At the same time, thanks to the agents system the learning process is checked and supported to be the correct one. Furthermore, for solving the student questions, our personal assistant has been given the capability to access external sources of data using information retrieval techniques, so he can also improve his existing knowledge base. 63 |

64 | During the development, we dealt with one of the main limitations that the natural language processors nowadays have: as there is a wide range of applications for them, they usually are unable to execute orders from the user that require using external modules. We overcome this limitation by implementing over an event-based network several execution modules, as the agent system that is able to support the learning process, or the information retrieval module. 65 | 66 |

67 | 68 |
69 | 70 |
71 |

Demo

72 |

You can try a live demo from here.

73 |
74 | 75 |
76 |

Download

77 |
78 |

You can download the code from here.

79 |
80 |

About Us

81 | 82 | 83 |

This project has been developed as the master thesis of Javier Herrera 84 | under the tutelage of Miguel Coronado and the supervision of 85 | Carlos A. Iglesias at GSI UPM.

86 |
87 | 88 |
89 | 90 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Agent-system/src/java/maia/client/MaiaRxClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 miguel, Javier Herrera Grupo de Sistemas Inteligentes (GSI UPM) 3 | * 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package maia.client; 18 | 19 | import jason.RevisionFailedException; 20 | import jason.asSemantics.TransitionSystem; 21 | import jason.asSyntax.Literal; 22 | 23 | import java.io.IOException; 24 | import java.net.URI; 25 | import java.net.URISyntaxException; 26 | import java.util.logging.Logger; 27 | 28 | import maia.client.annotation.OnMessage; 29 | import maia.utils.JSONUtils; 30 | 31 | /** 32 | * Project: maia-client
33 | * Package: maia.client
34 | * Class: MaiaClient.java
35 | *
36 | * GSI 2013
37 | * 38 | * @author Miguel Coronado (miguelcb@gsi.dit.upm.es) 39 | * @version Jun 3, 2013 40 | * 41 | */ 42 | public class MaiaRxClient extends MaiaClientAdapter { 43 | 44 | // TODO: Add config option instead... (Running out of time!) 45 | private Logger logger = Logger.getLogger("STDOUT"); 46 | //private Logger logger = Logger.getLogger("SYSLOG"); 47 | private String username; 48 | TransitionSystem ts; 49 | 50 | /** 51 | * @param serverURI 52 | * @throws URISyntaxException 53 | * @throws RevisionFailedException 54 | */ 55 | public MaiaRxClient(String serverURI, final TransitionSystem tas) throws URISyntaxException, RevisionFailedException { 56 | super(new URI(serverURI)); 57 | ts = tas; 58 | ts.getLogger().info("Empiezo a suscribirme en Maia..."); 59 | 60 | } 61 | 62 | @OnMessage("subscribed") 63 | public void onSubscribe(String message) { 64 | 65 | ts.getLogger().info("Subscribed >> " + message + "\n"); 66 | ts.getLogger().info("Ya me han suscrito!"); 67 | } 68 | 69 | 70 | @OnMessage("username::accepted") 71 | public void getUsername(String message) { 72 | this.username = JSONUtils.getDataName(message); 73 | } 74 | 75 | @OnMessage("message") 76 | public void message(String message) { 77 | 78 | String content = JSONUtils.getDataName(message); 79 | String origin = JSONUtils.find(message, "origin"); 80 | String nfact = ""; 81 | String nuser = ""; 82 | if (origin != null && origin.equals(this.username)) { 83 | return; 84 | } 85 | 86 | //I don't care for chatscript messages 87 | int intIndex = content.indexOf("[sendcs]"); 88 | if(intIndex != - 1){ 89 | ts.getLogger().info("era para ChatScript..."); 90 | return; 91 | } 92 | 93 | //Discard action if message not asking to assert a fact 94 | if (!content.contains( "assert")){ 95 | return; 96 | } 97 | 98 | nuser=content.substring(content.indexOf("[user")+6, content.lastIndexOf("]" )); 99 | 100 | //ts.getLogger().info("Tengo un mensaje!"); 101 | logger.info("["+nuser+"] Recibido >> "+ content); 102 | 103 | //Sample accepted message: [assert explained( concept dowhile ) ] [user Javi] 104 | 105 | //Extract new fact to assert from the Maia message 106 | nfact=content.substring(content.indexOf("[assert")+8, content.indexOf("]" )); 107 | nfact=nfact.replace("concept ","concept_"); 108 | nfact=nfact.replace(" ",""); 109 | nfact=nfact.replace("-",""); 110 | 111 | nfact+="[user(\""+nuser+"\")]"; 112 | 113 | 114 | 115 | ts.getLogger().info("Afirmando "+nfact); 116 | try { 117 | ts.getAg().delBel(Literal.parseLiteral(nfact)); 118 | ts.getAg().addBel(Literal.parseLiteral(nfact)); 119 | } catch (RevisionFailedException e) { 120 | logger.warning("Error adding belief" + nfact); 121 | } 122 | 123 | 124 | 125 | 126 | } 127 | 128 | public static void main (String[] args) throws URISyntaxException, InterruptedException, IOException { 129 | 130 | 131 | 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DUKE/topic.top: -------------------------------------------------------------------------------- 1 | concept: ~saludos [Hola hola Buenas buenas Que_tal que_tal] 2 | concept: ~que [que] 3 | concept: ~ser [ser eres Es sabes_sobre] 4 | concept: ~hacer [hacer haces hace] 5 | concept: ~quien [quien quienes] 6 | concept: ~articulos [El La los las Un una unos unas] 7 | concept: ~preposiciones [A ante bajo cabe con contra De desde En entre hacia hasta para por segun sin So sobre tras] 8 | concept: ~ejemplo [ejemplo ejemplar modelo prototipo patron] 9 | concept: ~afirmacion [si por_favor efectivamente evidentemente sin_duda] 10 | concept: ~negacion [no nones nanai naranjas quia ca] 11 | concept: ~profesor [profesor profe professor] 12 | 13 | # For some reason two-letter words must be capitalized 14 | 15 | concept: ~dudas [que como hago tienes ejemplo] 16 | 17 | topic: ~entrada keep repeat [] 18 | 19 | 20 | u: (~saludos) 21 | Hola, soy Duke y estoy aqui para ayudarte. 22 | 23 | # Simple, generic questions 24 | 25 | u: (~ser {~articulos} ~profesor) 26 | No, soy un bot asistente para ayudarte a encontrar respuestas. 27 | # TODO: Add rejoinder to offer contact info. 28 | 29 | u: (~quien ~ser) 30 | Me llamo $bot y soy un bot asistente para ayudarte con tus preguntas. 31 | 32 | u: (~que ~hacer) 33 | Mi funcion es ayudarte a encontrar respuestas 34 | 35 | u: (¬echo _* ) 36 | '_0 37 | 38 | t: Hola, en que puedo ayudarte? 39 | 40 | # topic: ~preguntas keep repeat [~dudas] 41 | # Generic questions 42 | #! que es un for? 43 | 44 | u: COMIENZO (~que ~ser {~articulos} * > _*-1 >) # This semi-weird pattern will return the last word of the sentence 45 | $pregunta='_0 46 | ¬sendMaia definition $pregunta 47 | ¬label $pregunta 48 | 49 | # Process the maia responses 50 | a: (¬maiaResponse definition _*) 51 | '_0 ¬sendMaia resource $pregunta 52 | 53 | # Ask for the link to show in the frame 54 | b: (¬maiaResponse resource _*) 55 | ¬resource '_0 _ ¬sendMaia links $pregunta 56 | c: (¬maiaResponse links _*) 57 | Tambien puedes preguntarme sobre '_0 \@full\_response 58 | c:(¬maiaResponse unknown) 59 | \@fullResponse 60 | b: (¬maiaResponse unknown) # No matter if there is a link or not, ask for related 61 | ¬sendMaia links $pregunta 62 | c: (¬maiaResponse links _*) 63 | Tambien puedes preguntarme sobre '_0 \@full\_response 64 | c:(¬maiaResponse unknown) 65 | \@fullResponse 66 | 67 | a: (¬maiaResponse unknown) 68 | Lo siento, no se nada sobre $pregunta ¬sendMaia gambit $pregunta 69 | # Busco lo más aproximado en solr. 70 | b:(¬maiaResponse gambit _*1) 71 | $$pregunta_gambit=_0 72 | Puedo explicarte $$pregunta_gambit, te sirve? 73 | c: (~afirmacion) 74 | $pregunta=$$pregunta_gambit 75 | ^reuse(COMIENZO) 76 | c: (~negacion) 77 | Me temo que no puedo ayudarte. Por que no me preguntas sobre alguna otra cosa? 78 | b:(¬maiaResponse unknown) 79 | _ 80 | 81 | 82 | u: (~ejemplo ~preposiciones _*) 83 | $pregunta='_0 84 | ¬sendMaia examples $pregunta 85 | a:(maiaResponse examples _*) 86 | '_0 87 | a:(¬maiaResponse unknown) 88 | Lo siento, no tengo ningun ejemplo sobre $pregunta 89 | 90 | u: EJEMPLO (~ejemplo $pregunta) 91 | ¬sendMaia examples $pregunta 92 | a:(¬maiaResponse examples _*) 93 | '_0 94 | a:(¬maiaResponse unknown) 95 | Lo siento, no tengo ningun ejemplo sobre $pregunta 96 | 97 | u: (~ejemplo) 98 | Sobre que quieres el ejemplo? 99 | a: (~preposiciones _*1 >) 100 | $pregunta=_0 101 | ^reuse(EJEMPLO) 102 | 103 | # topic: ~jasonpatterns keep repeat [java] 104 | # Jason backwards-compatibility patterns 105 | 106 | #! [java sample iteracion] 107 | u: (\[java sample _* \]) 108 | Si quieres un ejemplo sobre _0, puedes pedirlo. 109 | a: (~afirmacion) 110 | ^reuse(EJEMPLO) 111 | 112 | #! [java recommend random] 113 | u: (\[java recommend random \]) 114 | \[sendMaia pickRandom \] 115 | a:(\[~maiaresponses label _* \] ) 116 | $recom=_0 117 | ^reuse(RECOMENDACION) 118 | 119 | #! [java recommend iteracion] 120 | u: RECOMENDACION (\[java recommend _* \]) 121 | $recom=_0 122 | Hoy te recomiendo repasar $recom. 123 | 124 | #! [java test iteracion] 125 | u: TEST ( \[java test _* \]) 126 | \[sendMaia example _* \] 127 | a: (\[~maiaresponses example _* ) 128 | Para repasar, seguro que puedes decir a que se refiere este concepto: _0 129 | b: (_*) 130 | \[sendmaia assert affirm(concept _0)\] 131 | c: (\[java testok _* \] ) 132 | Exacto, se trataba de _0. 133 | c: (\[java testfail _* \]) 134 | Incorrecto, se trataba de _0. 135 | 136 | 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## [Calista Bot](https://github.com/gsi-upm/calista-bot) 2 | 3 | 4 | ## Introduction 5 | 6 | This project aims to integrate the advantages of intelligent agent systems, information retrieval and Natural Language Processing in a personal assistance system. 7 | 8 | Thanks to this integration, we have been able to provide the personal assistant the ability to solve questions and support the learning process in an e-learning platform. This opens the opportunity for the student to be able to find help in any moment, not having to resort to the teacher. At the same time, thanks to the agents system the learning process is checked and supported to be the correct one. Furthermore, for solving the student questions, our personal assistant has been given the capability to access external sources of data using information retrieval techniques, so he can also improve his existing knowledge base. 9 | 10 | During the development, we dealt with one of the main limitations that the natural language processors nowadays have: as there is a wide range of applications for them, they usually are unable to execute orders from the user that require using external modules. We overcome this limitation by implementing over an event-based network several execution modules, as the agent system that is able to support the learning process, or the information retrieval module. 11 | 12 | 13 | 14 | ##Architecture 15 | 16 | In this diagram, you can see the Calista Bot arquitecture at a glance 17 | 18 | ![Calista Bot architecture](http://dit.upm.es/~amardomingo/pfc/images/calistabot-diag.png) 19 | 20 | For a detailed explanation of each module, you can visit each subproject's repository by clicking in each folder of this repo or by clicking in the headings of the Submodules section. 21 | 22 | 23 | 24 | ## Submodules 25 | Calista Bot consists in several modules that can be found under the subtrees of this project. 26 | 27 | 28 | ### [Chat client](https://github.com/gsi-upm/calista-bot/tree/master/Chat-client) 29 | An user interface that allows the user to communicate with the system, by chatting with the personal assistant in natural language. 30 | 31 | ![Chat client](http://dit.upm.es/~amardomingo/pfc/images/bot_example.png) 32 | 33 | 34 | ### [Front-end controller and KB](https://github.com/gsi-upm/calista-bot/tree/master/FE-Controller) 35 | The Front-end controller manages the process followed to generate a reply for the user's query. It triggers the other modules to understand the user query, execute external actions if needed, and finally formulate the reply that is sent back to the user. 36 | 37 | The knowledge base (KB) contains information ready to be provided by the Chatbot when the user sends a question about a subject. It is dynamically updated when new information is fetched from the Linked Open Data Server. 38 | 39 | ### [Chatbot (ChatScript)](https://github.com/gsi-upm/calista-bot/tree/master/ChatScript) 40 | The chatbot is able to maintain a conversation in natural language with the user. It applies the patterns specified in its corpus, which usually produce both a natural language response and out of band commands (hidden for the user) that are handled by the front-end controller. 41 | 42 | ### [Event network (Maia)](https://github.com/gsi-upm/Maia) 43 | The event network allows the communication between the front-end controller and the external services, such as the Agent system or the Linked Open Data Server. This network is based on event messages that contain the information exchanged by these modules. 44 | 45 | ### [Agent system (Jason)](https://github.com/gsi-upm/calista-bot/tree/master/Agent-system) 46 | An intelligent agent system that receives assertions collected during the conversation and provides them as beliefs to the agent(s) running on it. It provides our personal assistance system an extra interaction with the user, by triggering plans that automatically produce replies that are sent to the user. 47 | 48 | ### [Linked Open Data Server (Apache Solr)](https://github.com/gsi-upm/calista-bot/tree/master/solr-elearning) 49 | The Linked Open Data Server contains indexed information, which has been previously added by the system administrator. When the user sends a question and no information is found in the KB, this service is ready to provide the needed information. 50 | 51 | 52 | 53 | 54 | ## License 55 | 56 | ``` 57 | Copyright 2013 UPM-GSI: Group of Intelligent Systems - Universidad Politécnica de Madrid (UPM) 58 | 59 | Licensed under the Apache License, Version 2.0 (the "License"); 60 | You may not use this file except in compliance with the License. 61 | You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 62 | applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 63 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific 64 | language governing permissions and limitations under the License. 65 | ``` 66 | ![GSI Logo](http://www.gsi.dit.upm.es/images/stories/logos/gsi.png) 67 | 68 | This project has been developed as the master thesis of [Javier Herrera](https://github.com/javiherrera) under the tutelage of [Miguel Coronado](https://github.com/miguelcb84) and the supervision of [Carlos A. Iglesias](https://github.com/cif2cif) at [gsi-upm](https://github.com/gsi-upm) 69 | -------------------------------------------------------------------------------- /Ask-Client/landing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 |
19 |
20 |

Pregunta a Duke

21 |

Duke puede ayudarte con tus preguntas de Java

22 |

¡Ponle a prueba!

23 |
24 |
25 | 26 |
27 |
28 |
29 |

¿Cómo funciona?

30 |
31 |
32 | 33 |
34 |
35 |
36 | 37 | Duke sabe hablar en lenguage natural 38 |
39 |
40 |
41 |
42 | 43 | Duke puede responder tus preguntas de Java 44 |
45 |
46 |
47 |
48 | 49 | Colabora rellenando el cuestionario 50 |
51 |
52 |
53 |
54 | 55 |
56 |
57 | Desarrollado por: 58 | 59 | 60 |
61 |
62 | Agradecimiento a José A. Mañas, autor del Vademecum de Java 63 |
64 |
65 | 66 | 67 | 94 |
95 | 96 | 97 | 98 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /QA-client/css/global.css: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~ @start background fake image ~~~~~~~~~*/ 2 | html { 3 | height: 100%; 4 | 5 | } 6 | 7 | body { 8 | /*background: #ffffff url('../images/bg_vademecum.png') no-repeat;*/ 9 | height: 100%; 10 | } 11 | 12 | 13 | /* Iframe with the vademecum */ 14 | 15 | #bot-target{ 16 | position: relative; 17 | z-index: 1; 18 | height: 100%; 19 | width: 100%; 20 | } 21 | 22 | #bot_chat_window { 23 | position: fixed; 24 | bottom: 0; 25 | left: 5%; 26 | font-family: 'Helvetica Neue', Helvetica, 'Open Sans', Arial, Trebuchet, 'Sans Serif'; 27 | font-size: 13px; 28 | width: 260px; 29 | z-index: 20; 30 | box-shadow: 1px 6px 10px 1px #333 31 | } 32 | 33 | /*~~~~~~~~~~ @start upperbar styling ~~~~~~~~~~~~*/ 34 | #bot_chat_window #upper_bar { 35 | /*width: 230px;*/ /*inherit*/ 36 | background: #640340; 37 | padding: 10px; 38 | height: 14px; 39 | /* round corners */ 40 | -moz-border-radius: 5px 5px 0 0; 41 | -webkit-border-radius: 5px 5px 0 0; 42 | -khtml-border-radius: 5px 5px 0 0; 43 | border-radius: 5px 5px 0 0; 44 | } 45 | #bot_chat_window #upper_bar h3{ 46 | font-size: 14px; 47 | font-weight: normal; 48 | margin: 0; 49 | color: white; 50 | } 51 | #bot_chat_window #upper_bar a#bot_name { 52 | color: white; 53 | text-decoration: none; 54 | } 55 | #bot_chat_window #upper_bar a#max_icon { 56 | width: 16px; 57 | height: 16px; 58 | float: right; 59 | display: block; 60 | border-bottom: 2px solid white; 61 | } 62 | /*~~~~~~~~~~ @end upperbar styling ~~~~~~~~~~~~*/ 63 | 64 | /*~~~~~~~~~~ @start Avatar styling ~~~~~~~~~~~~*/ 65 | #bot_chat_window img#bot_avatar { 66 | width: 100px; 67 | /*height: 70px;*/ 68 | position: relative; 69 | top: -102px; 70 | } 71 | /*~~~~~~~~~~ @end Avatar styling ~~~~~~~~~~~~*/ 72 | #bot_chat_window #screen_wrapper { 73 | display: none; /* hide at start */ 74 | } 75 | #bot_chat_window.visible #screen_wrapper { 76 | display: block; 77 | } 78 | #bot_chat_window #screen_wrapper { 79 | background: whitesmoke; /* bg_color */ 80 | padding-bottom: 35px; /* */ 81 | } 82 | 83 | #bot_chat_window #screen_wrapper #screen { 84 | padding: 6px 10px 0 10px; 85 | max-height: 200px; 86 | min-height: 100px; 87 | overflow-y: auto; 88 | /*width: 230px;*/ /*inherit*/ 89 | } 90 | #bot_chat_window #screen_wrapper #screen .dia_entry { 91 | padding-left: 12px; 92 | } 93 | #bot_chat_window #screen_wrapper #screen .dia_entry .nick { 94 | font-weight: bold; 95 | float: left; 96 | margin-left: -12px; 97 | } 98 | #bot_chat_window #screen_wrapper #screen .dia_entry .text { 99 | margin-left: 5px; 100 | } 101 | #bot_chat_window #screen_wrapper #meta_msgs { 102 | margin-left: 10px; 103 | font-size: 11px; 104 | color: #444; 105 | padding: 3px 0 1px 0; 106 | } 107 | 108 | 109 | /*~~~~~~~~~~ @begin bottom userbar form styling ~~~~~~~~~~~~*/ 110 | #bot_chat_window #screen_wrapper #userbar { 111 | 112 | } 113 | #bot_chat_window #screen_wrapper #userbar form { 114 | margin: 0px 0px 0px 10px; 115 | position: fixed; 116 | bottom: 0; 117 | background-color: whitesmoke; /* bg_color */ 118 | } 119 | #bot_chat_window #userbar form input[type="text"] { 120 | border: 1px solid #999999; 121 | padding: 4px; 122 | margin: 0 3px 5px 0; 123 | width: 170px; 124 | font-size: 0.9em; 125 | /* round corners */ 126 | -moz-border-radius: 3px; 127 | -webkit-border-radius: 3px; 128 | -khtml-border-radius: 3px; 129 | border-radius: 3px; 130 | } 131 | #bot_chat_window #userbar form input[type="text"]:focus { 132 | border-color: #666666; 133 | outline-color: #bbbbbb; 134 | } 135 | /*~~~~~~~~~~ @end bottom userbar form styling ~~~~~~~~~~~~*/ 136 | 137 | 138 | #bot_chat_window #msg_dialog{ 139 | position: fixed; 140 | bottom: 40px; 141 | left: 5px; 142 | left: 5%; /* same as chat window position */ 143 | margin-left: 5px; 144 | width: 215px; 145 | display: none; 146 | background: #444444; 147 | color: white; 148 | padding: 4px 12px; 149 | border-radius: 5px; 150 | opacity: 0.9; 151 | } 152 | /** ~~~~ @begin Feedback form styling ~~~~~~ **/ 153 | #bot_chat_window .feedback_form { 154 | margin: 0; 155 | text-align: center; 156 | } 157 | #bot_chat_window div.feedback_req { 158 | /*margin-left: 15px; 159 | margin-top: 2px; 160 | margin-bottom: 5px;*/ 161 | font-size: 11px; 162 | border: 1px solid #BBBBBB; 163 | border-radius: 3px; 164 | padding: 4px 8px 2px; 165 | display: inline-block; 166 | margin: 4px auto 6px; 167 | text-align: center; 168 | background: -webkit-linear-gradient(bottom, #DEDEDE, #EDEDED); 169 | } 170 | #bot_chat_window div.feedback_req:hover { 171 | border-color: #999999 172 | } 173 | #bot_chat_window div.feedback_req span{ 174 | vertical-align: top; /* text pos correction */ 175 | text-shadow: 0px 1px 0px white; 176 | } 177 | #bot_chat_window .feedback_req button { 178 | background-color: #CCCCCC; 179 | border: none; 180 | margin: 0; 181 | width: 14px; 182 | height: 14px; 183 | padding: 0; 184 | cursor: pointer; 185 | } 186 | #bot_chat_window .feedback_req span:first-child { 187 | margin-right: 2px; 188 | } 189 | #bot_chat_window .feedback_req button.ok { 190 | background-image: url('../images/ok.png'); 191 | background-position: -14px 0px; 192 | } 193 | #bot_chat_window .feedback_req button.ok:hover { 194 | background-position-y: -14px; 195 | } 196 | #bot_chat_window .feedback_req button.nok{ 197 | background-image: url('../images/nok.png'); 198 | background-position: -14px 0px; 199 | } 200 | #bot_chat_window .feedback_req button.nok:hover { 201 | background-position-y: -14px; 202 | } 203 | /** ~~~~ @end Feedback form styling ~~~~~~ **/ 204 | -------------------------------------------------------------------------------- /Ask-Client/css/landing.less: -------------------------------------------------------------------------------- 1 | body { 2 | /*font-family: 'Open Sans', Ubuntu, verdana, arial, sans-serif;*/ 3 | font-family: 'Open Sans', sans-serif; 4 | color: #444; 5 | } 6 | #container { 7 | width: 800px; 8 | margin: 0px auto; 9 | } 10 | /*~~~~~~~~ @start central banner ~~~~~~~~~*/ 11 | #container #central_description { 12 | background-color: #005ea6; 13 | margin-top: 8%; 14 | color: white; 15 | height: 400px; 16 | width: 800px; 17 | background: url("../images/landing/banner.png") no-repeat; 18 | } 19 | #container #central_description #description{ 20 | padding-top: 100px; 21 | margin-left: 400px; 22 | 23 | } 24 | #container #central_description h1{ 25 | font-size: 35px; 26 | font-weight: normal; 27 | margin-bottom: 12px; 28 | text-shadow: 0 1px 1px #1A5F8C; 29 | } 30 | #container #central_description p { 31 | font-size: 16px; 32 | width: 250px; 33 | line-height: 1.25; 34 | margin-bottom: 8px; 35 | margin-left: 2px; 36 | } 37 | /*~~~~~~~~ @end central banner ~~~~~~~~~*/ 38 | 39 | /*~~~~~~~~ @start bottom banner ~~~~~~~~~*/ 40 | #container #bottom_description { 41 | background: #e2e2e2; 42 | width: 800px; 43 | height: 90px; 44 | } 45 | #container #bottom_description #social_stuff { 46 | width: 280px; 47 | float: left; 48 | } 49 | #container #bottom_description #social_stuff table{ 50 | margin: 25px 30px 0px; 51 | float: left; 52 | } 53 | #container #bottom_description #social_stuff #logo{ 54 | background: url("../images/landing/gsi-logo2.png") no-repeat scroll 0 10px transparent; 55 | height: 80px; 56 | margin-left: 150px; 57 | width: 70px; 58 | } 59 | #container #bottom_description #social_stuff #logo:hover{ 60 | background-position: -110px 10px; 61 | cursor: pointer; 62 | } 63 | #container #bottom_description #explore_guide { 64 | font-size: 13px; 65 | color: #4d4d4d; 66 | text-shadow: 1px 1px 1px white; 67 | line-height: 1.25; 68 | width: 270px; 69 | float: left; 70 | } 71 | #container #bottom_description #explore_guide p{ 72 | margin-top: 12px; 73 | padding-left: 17px; 74 | padding-bottom: 3px; 75 | border-left: 1px solid #8d8d8d; 76 | } 77 | #container #bottom_description #explore_button { 78 | width: 250px; 79 | float: left; 80 | padding-top: 20px; 81 | } 82 | .clear-both{ 83 | clear: both; 84 | } 85 | /*~~~~~~~~ @start end bottom banner ~~~~~~~~~*/ 86 | 87 | 88 | #container #bottom_description button{ 89 | font-size: 20px; 90 | display: block; 91 | color: white; 92 | margin: 0; 93 | padding: 0 32px; 94 | line-height: 49px; 95 | text-align: center; 96 | text-shadow: 0px -1px #004376; 97 | text-decoration: none; 98 | height: 51px; 99 | border: 1px solid #004376; 100 | border-radius: 6px; 101 | -moz-border-radius: 6px; 102 | -webkit-border-radius: 6px; 103 | -o-border-radius: 6px; 104 | background-image: -webkit-gradient(linear,center top,center bottom,from(#0097D6),to(#005EA6)); 105 | background-image: -webkit-linear-gradient(top,#0097D6,#005EA6); 106 | background-image: -moz-linear-gradient(top,#0097D6,#005EA6); 107 | background-image: -o-linear-gradient(top,#0097D6,#005EA6); 108 | background-image: -ms-linear-gradient(top,#0097D6,#005EA6); 109 | background-image: linear-gradient(top,#0097D6,#005EA6); 110 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0097d6', endColorstr='#005ea6',GradientType=0 ); 111 | -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.43); 112 | -moz-box-shadow: 0 1px 5px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.43); 113 | box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.43); 114 | } 115 | #container #bottom_description button:hover{ 116 | background-image: -webkit-gradient(linear,center top,center bottom,from(#005EA6),to(#0097D6)); 117 | background-image: -webkit-linear-gradient(top,#005EA6,#0097D6); 118 | background-image: -moz-linear-gradient(top,#005EA6,#0097D6); 119 | background-image: -o-linear-gradient(top,#005EA6,#0097D6); 120 | background-image: -ms-linear-gradient(top,#005EA6,#0097D6); 121 | background-image: linear-gradient(top,#005EA6,#0097D6); 122 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#005ea6', endColorstr='#0097d6',GradientType=0 ); 123 | cursor: pointer; 124 | } 125 | #container #bottom_description button:active{ 126 | -webkit-box-shadow: 0 0 0; 127 | -moz-box-shadow: 0 0 0; 128 | box-shadow: 0 0 0; 129 | } 130 | 131 | /* how ir works */ 132 | .how-it-works { 133 | h1{ 134 | text-align: center; 135 | margin-top: 0px; 136 | margin-bottom: 25px; 137 | } 138 | .box{ 139 | background-color: #eaeaea; 140 | padding: 20px; 141 | font-size: 17px; 142 | i{ 143 | float: left; 144 | font-size: 34px; 145 | } 146 | span{ 147 | margin-left: 50px; 148 | display: block; 149 | } 150 | } 151 | 152 | } 153 | 154 | .credits{ 155 | margin-top: 60px; 156 | text-align: right; 157 | img{ 158 | margin-left: 15px; 159 | max-height: 56px; 160 | } 161 | span{ 162 | color: #999999; 163 | } 164 | &.row > div { 165 | margin-bottom: 10px; 166 | } 167 | } 168 | 169 | #floating-cta{ 170 | width: 180px; 171 | height: 190px; 172 | background: url("../images/landing/click_to_talk.png") no-repeat 98% 95%; 173 | display: block; 174 | left: 372px; 175 | position: absolute; 176 | bottom: 10px; 177 | z-index: -10; 178 | } 179 | 180 | /*~~~~~~~~ @start resize like button ~~~~~~~~~*/ 181 | .fb-like iframe { 182 | transform: scale(1.25); 183 | -ms-transform: scale(1.25); 184 | -webkit-transform: scale(1.25); 185 | -o-transform: scale(1.25); 186 | -moz-transform: scale(1.25); 187 | transform-origin: top left; 188 | -ms-transform-origin: top left; 189 | -webkit-transform-origin: top left; 190 | -moz-transform-origin: top left; 191 | -webkit-transform-origin: top left; 192 | } 193 | /*~~~~~~~~ @end resize like button ~~~~~~~~~*/ 194 | -------------------------------------------------------------------------------- /Ask-Client/js/ask.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function($){ 2 | 3 | alert('Los datos que introduzcas serán registrados como parte del experimento.\n No envies datos personales o contraseñas'); 4 | /* Store the url shown */ 5 | var current_url_shown = "" // this is used to avoid continous recharging of the web 6 | 7 | /* Vademecum base url */ 8 | var vademecum_base = "http://www.dit.upm.es/~pepe/libros/vademecum/index.html?n=" 9 | 10 | // Creates (or loads from cookie) a random user id for the bot 11 | var username = ""; 12 | if(document.cookie && document.cookie.indexOf("botUser") != -1) { 13 | data = document.cookie.split(";"); 14 | for (var i = 0; i < data.length; i++) { 15 | cookie = data[i].trim(); 16 | //console.log(document.cookie); 17 | if (cookie.indexOf("botUser") == 0) { 18 | username = cookie.substr("botUser=".length, cookie.length -1); 19 | } 20 | } 21 | } else { 22 | username = randomString(5); 23 | document.cookie = "botUser="+username+";"; 24 | }; 25 | 26 | // First time answer, send a question to get the gambit response 27 | json_data = {'username': username, 'question':'Hola'}; 28 | $.ajax({ url: $('#ask-form').attr('action'), 29 | data: json_data, 30 | dataType: 'json', 31 | contentType: 'application/json;charset=UTF-8', 32 | success: populateForm, 33 | error: function(data_resp) { 34 | alert("Esto es un error"); 35 | console.log("Error connection to the controller"); 36 | } 37 | }); 38 | 39 | /** Hide/show effect */ 40 | $('#bot_chat_window #upper_bar a#max_icon').click(function(){ 41 | $('#bot_chat_window').toggleClass('visible'); 42 | $('#bot_chat_window #screen_wrapper form input[name=question]').val(''); 43 | $('#bot_chat_window #screen_wrapper form input[name=question]').focus(); 44 | return false; 45 | }); 46 | 47 | /** Request questionnaire */ 48 | $('#bot_chat_window #upper_bar a#quiz').click(function(){ 49 | $('#bot_chat_window #screen_wrapper form input[name=question]').val('Quiero rellenar la encuesta de satisfacción'); 50 | return false; 51 | }); 52 | 53 | // Set the username in the span 54 | $('#username').html(username); 55 | 56 | $('#ask-form').on('submit', function() { 57 | var form = $(this); 58 | var form_data = form.serializeArray(); 59 | var input_field = form.children('input[name=question]'); 60 | 61 | if (form[0].value == '') { 62 | //TODO: Add an alert to say there needs to be data 63 | return false; 64 | }; 65 | 66 | var json_data = {}; 67 | $.map(form_data, function(n, i){ 68 | json_data[n['name']] = n['value']; 69 | }); 70 | 71 | json_data.username = username; 72 | 73 | // Add the question 74 | $('#screen').append(constructDialogEntry('Me', json_data.question)); 75 | scrollDisplay(); 76 | input_field.val('') 77 | $.ajax({ url: form.attr('action'), 78 | data: json_data, 79 | dataType: 'json', 80 | contentType: 'application/json;charset=UTF-8', 81 | success: populateForm, 82 | error: function(data_resp) { 83 | $('#screen').append(constructDialogEntry('Duke', 84 | 'Vaya, parece que he tenido algún error conectando con el servidor... Whoops')); 85 | console.log("Error connection to the controller"); 86 | return false; 87 | } 88 | }); 89 | return false; 90 | }); 91 | 92 | function populateForm (data_resp) { 93 | console.log(data_resp); 94 | if (data_resp.answer) { 95 | data_resp.answer.forEach(function(answer) { 96 | $('#screen').append(constructDialogEntry('Duke', answer)); 97 | scrollDisplay(); 98 | if (data_resp.resource) { 99 | if (data_resp.resource.indexOf('vademecum') != -1 ){ 100 | // This links to the vademecum 101 | var name_start = data_resp.resource.lastIndexOf('/')+1 102 | var filename = data_resp.resource.substring(name_start) 103 | $('#iframe-qa').attr('src', vademecum_base + filename); 104 | current_url_shown = vademecum_base + filename; 105 | } else { 106 | //I have some other link 107 | $('#iframe-qa').attr('src', data_resp.resource); 108 | current_url_shown = data_resp.resource; 109 | } 110 | } 111 | }); 112 | } else { 113 | $('#screen').append(constructDialogEntry('Duke', 114 | 'Lo siento, no puedo responder a esa pregunta')); 115 | scrollDisplay(); 116 | } 117 | scrollDisplay(); 118 | } 119 | // Generates a Random string for the user id 120 | function randomString(length) { 121 | charSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 122 | var result = ''; 123 | for (var i = length; i > 0; --i) result += charSet[Math.round(Math.random() * (charSet.length - 1))]; 124 | return result; 125 | } 126 | 127 | /* This scrolls the display to the bottom, just to show all the messages. 128 | * It can be overriden to use a different animation */ 129 | function scrollDisplay () { 130 | // Nice scroll to last message 131 | $("#screen").scrollTo('100%', 0); 132 | } 133 | 134 | /* This construct html formatted dialog entry */ 135 | function constructDialogEntry (nick, entry) { 136 | return '
\ 137 | ' + nick + ':\ 138 | ' + entry + '\ 139 |
' 140 | }; 141 | 142 | }); 143 | -------------------------------------------------------------------------------- /QA-client/js/qa.js: -------------------------------------------------------------------------------- 1 | // Autocomplete data 2 | 3 | var autocom_questions = [ 4 | "Que es un for?", 5 | "Que es un while?", 6 | "Como hago una interfaz?", 7 | "Que es javadoc?", 8 | "Donde puedo ver un ejemplo de for?", 9 | "Que es una excepción?", 10 | "Querría un ejemplo de while", 11 | "Como hago un bucle" 12 | ]; 13 | 14 | jQuery(document).ready(function($){ 15 | 16 | alert('Los datos que introduzcas serán registrados como parte del experimento.\n No envies datos personales o contraseñas'); 17 | 18 | /* Store the url shown */ 19 | var current_url_shown = "" // this is used to avoid continous recharging of the web 20 | 21 | /* Vademecum base url */ 22 | var vademecum_base = "http://www.dit.upm.es/~pepe/libros/vademecum/index.html?n=" 23 | 24 | 25 | // Creates (or loads from cookie) a random user id for the bot 26 | var username = ""; 27 | if(document.cookie && document.cookie.indexOf("botUser") != -1) { 28 | data = document.cookie.split(";"); 29 | for (var i = 0; i < data.length; i++) { 30 | cookie = data[i].trim(); 31 | //console.log(document.cookie); 32 | if (cookie.indexOf("botUser") == 0) { 33 | username = cookie.substr("botUser=".length, cookie.length -1); 34 | } 35 | } 36 | // If I couldn't get the user, I set a random one 37 | //if (username =="") username = randomString(20); 38 | } else { 39 | username = randomString(5); 40 | document.cookie = "botUser="+username+";"; 41 | }; 42 | // Set the username in the span 43 | $('#username').html(username); 44 | 45 | /** Hide/show effect */ 46 | $('#bot_chat_window #upper_bar a').click(function(){ 47 | $('#bot_chat_window').toggleClass('visible'); 48 | $('#bot_chat_window #screen_wrapper form input[name=question]').val(''); 49 | $('#bot_chat_window #screen_wrapper form input[name=question]').focus(); 50 | }); 51 | 52 | // Autocomplete 53 | //$('#question').autocomplete({source: autocom_questions}); 54 | /**/ 55 | $('#qa-form').on('submit', function(){ 56 | 57 | // serialize the form 58 | var form = $(this); 59 | var form_data = form.serializeArray(); 60 | var input_field = form.children('input[name=question]'); 61 | if (form[0].value == '') { 62 | //TODO: Add an alert to say there needs to be data 63 | return false; 64 | }; 65 | 66 | var json_data = {}; 67 | $.map(form_data, function(n, i){ 68 | json_data[n['name']] = n['value']; 69 | }); 70 | json_data.username = username; 71 | 72 | $('#screen').append($(constructDialogEntry('me', json_data.question))); 73 | input_field.val(''); 74 | scrollDisplay(); 75 | //var data = JSON.stringify(json_data); 76 | 77 | jQuery.support.cors = true; // :S 78 | // send the data 79 | 80 | $.ajax({url: form.attr('action'), 81 | data: json_data, 82 | dataType: 'json', 83 | contentType: 'application/json;charset=UTF-8', 84 | success: function (data_resp) { 85 | console.log(data_resp); 86 | // Set the url as a response 87 | if (data_resp.resource) { 88 | if(data_resp.resource != current_url_shown) { 89 | // I want the filename from that url: 90 | var name_start = data_resp.resource.lastIndexOf('/')+1 91 | var filename = data_resp.resource.substring(name_start) 92 | $('#iframe-qa').attr('src', vademecum_base + filename); 93 | current_url_shown = vademecum_base + filename; 94 | // Add a generic response 95 | $('#screen').append( 96 | $(constructDialogEntry('Dent', 97 | "Te muestro la información que tengo sobre " 98 | + data_resp.title))); 99 | scrollDisplay(); 100 | $('#iframe-qa').show(); 101 | } 102 | /*related_list="
    "; 103 | data_resp.links.forEach(function(entry){ 104 | related_list+='
  • '+entry.title+''; 105 | }); 106 | related_list+='
'; 107 | $('#related-list').html(related_list); 108 | $('#related-container').fadeIn('slow');*/ 109 | } else { 110 | $('#screen').append( 111 | $(constructDialogEntry('Dent', 112 | data_resp.error))); 113 | scrollDisplay(); 114 | 115 | } 116 | }, 117 | error: function(data_resp){ 118 | console.log("Error connecting to the contoller"); 119 | return false; 120 | } 121 | }); 122 | 123 | return false; 124 | }); 125 | 126 | 127 | // Generates a Random string for the user id 128 | function randomString(length) { 129 | charSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 130 | var result = ''; 131 | for (var i = length; i > 0; --i) result += charSet[Math.round(Math.random() * (charSet.length - 1))]; 132 | return result; 133 | } 134 | 135 | /* This scrolls the display to the bottom, just to show all the messages. 136 | * It can be overriden to use a different animation */ 137 | function scrollDisplay () { 138 | // Nice scroll to last message 139 | $("#screen").scrollTo('100%', 0); 140 | } 141 | 142 | /* This construct html formatted dialog entry */ 143 | function constructDialogEntry (nick, entry) { 144 | return '
\ 145 | ' + nick + ':\ 146 | ' + entry + '\ 147 |
' 148 | }; 149 | 150 | }); 151 | 152 | -------------------------------------------------------------------------------- /FE-Controller/lib/maia.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from __future__ import print_function 3 | import sys 4 | 5 | import websocket 6 | import time 7 | import json 8 | 9 | from unidecode import unidecode 10 | 11 | import threading, Queue 12 | 13 | class Maia: 14 | 15 | def __init__ (self, uri, logger): 16 | """ 17 | Creates the maia object, but does NOT create the websocket 18 | """ 19 | 20 | self.uri = uri 21 | self.logger = logger 22 | 23 | # Creates the queues for the messages 24 | self.rcvd_msgs = {} 25 | self.rcvd_msgs['anonymous'] = Queue.Queue() 26 | self.lock = threading.Lock() 27 | 28 | 29 | def connect(self): 30 | """ 31 | Connects to the maia network 32 | """ 33 | self.logger.info("Subscribing to the maia network...") 34 | 35 | # I don't really like this, I should probably 36 | # just make them private methods or something... 37 | 38 | 39 | websocket.enableTrace(False) 40 | self.ws = websocket.WebSocketApp(self.uri, on_message = self.on_message, 41 | on_error = self.on_error, 42 | on_close = self.on_close, 43 | on_open = self.on_open) 44 | self.ws.send_type = 'message' 45 | #self.ws.on_open = Maia.on_open 46 | self.ws.subscribe = 'message' #lista a suscribirse 47 | self.ws.response = '' 48 | 49 | self.maia_thread = maiaListener(self.ws) 50 | 51 | self.maia_thread.start() 52 | 53 | #ws.run_forever() 54 | 55 | def wait_for_message(self, timeout, user): 56 | """ 57 | Waits for a message from the maia network, 58 | or until the timeout triggers 59 | """ 60 | 61 | # Dirty, pass the current query user so I could use the message 62 | 63 | # I get a message from the queue, with timeout. 64 | # If the timeout triggers, I return an empty string 65 | response = u"" 66 | try: 67 | if user in self.rcvd_msgs: 68 | 69 | # I wait until no more messages are received 70 | while (True): 71 | msg = unicode(self.rcvd_msgs[user].get(True, timeout)) 72 | self.logger.info(u"Received from maia>> " + msg) 73 | 74 | # I may receive duplicated messages 75 | if msg not in response: 76 | response +=msg 77 | except Queue.Empty: 78 | # Log error? 79 | self.logger.debug(u"[user: {user}] Maia timeout. continuing...".format(user=user)) 80 | 81 | return response 82 | 83 | def send(self, data, user): 84 | """ 85 | Sends a message to the maia network, without waiting for response 86 | """ 87 | 88 | with self.lock: 89 | self.rcvd_msgs[user] = Queue.Queue() 90 | self.logger.info('[user: '+user+'] Sending to Maia {"name":"message","data": {"name" : "'+data+'"}}') 91 | self.ws.send('{"name":"message","data": {"name" : "%s"}}' % data) 92 | # Bassically, I just add it to the queue. 93 | #self.send_msgs.put(message) 94 | 95 | def on_open(self, ws): 96 | """ 97 | When creating the socket, subscribe to the maia network 98 | """ 99 | 100 | ws.send('{"name":"username","data": {"name" : "%s"}}' % "python_client"); 101 | time.sleep(1); 102 | 103 | ws.send('{"name":"subscribe","data": {"name" : "%s"}}' % 'message'); 104 | time.sleep(2) 105 | 106 | def on_message(self, ws, message): 107 | """ 108 | Receives a message from the maia network. 109 | """ 110 | if type(message) == str: 111 | message = unicode(message, "utf-8") 112 | 113 | # Only attend messages that are actual responses: 114 | if u"¬maiaResponse" not in message: 115 | return 116 | 117 | self.logger.debug("Received from maia: " + message) 118 | userStart = message[message.rfind("[user"):] 119 | 120 | user = userStart[:userStart.find("]")+1] 121 | # Delete the user for the data to send to ChatScript 122 | mymsg = json.loads(message.replace(user, "")) 123 | 124 | # Replaces the user tags, and keep only the username 125 | user = user.replace("[user ", "") 126 | user = user.replace("]", "") 127 | 128 | if u'¬maiaResponse' in mymsg['data']['name']: 129 | 130 | msg = mymsg['data']['name'] 131 | 132 | #Convert the message to utf-8 133 | if type(msg)==str: 134 | msg = unicode(msg, "utf-8") 135 | 136 | if user in self.rcvd_msgs: 137 | self.rcvd_msgs[user].put(msg) 138 | 139 | def on_error(self, ws, error): 140 | """ 141 | Just print the error for the time being 142 | """ 143 | 144 | self.logger.error(error) 145 | 146 | def on_close(self, ws): 147 | """ 148 | Unsubscribe from maia 149 | """ 150 | self.logger.warning('I still need to figure out how to properly close the maia websocket...') 151 | 152 | # Unsubscribe 153 | # Should I really do this? 154 | #self.ws.send('{"name":"unsubscribe","data": {"name" : "%s"}}' % 'message') 155 | #self.ws.close() 156 | 157 | self.maia_thread.join() 158 | 159 | class maiaListener(threading.Thread): 160 | """ 161 | Thread to listen /send messages to the maia network 162 | """ 163 | 164 | def __init__(self, ws): 165 | super(maiaListener, self).__init__() 166 | 167 | # I want the thread to die when CTRL+C is issued, so I make it a "dameon" thread 168 | self.daemon = True 169 | 170 | self.ws = ws 171 | 172 | def run(self): 173 | """ 174 | Keeps running 175 | If I need to send a message, sent it 176 | """ 177 | self.ws.run_forever() 178 | 179 | def join(self, timeout=None): 180 | super(maiaListener, self).join(timeout) 181 | 182 | -------------------------------------------------------------------------------- /Chat-client/css/global.css: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~ @start background fake image ~~~~~~~~~*/ 2 | html { 3 | height: 100%; 4 | 5 | } 6 | 7 | body { 8 | /*background: #ffffff url('../images/bg_vademecum.png') no-repeat;*/ 9 | height: 100%; 10 | } 11 | 12 | 13 | /* Iframe with the vademecum */ 14 | 15 | #bot-target{ 16 | position: relative; 17 | z-index: 1; 18 | height: 100%; 19 | width: 100%; 20 | } 21 | 22 | #bot_chat_window { 23 | position: fixed; 24 | bottom: 0; 25 | left: 5%; 26 | font-family: Verdana; 27 | font-size: 13px; 28 | width: 260px; 29 | z-index: 20; 30 | box-shadow: 1px 6px 10px 1px #333 31 | } 32 | 33 | /*~~~~~~~~~~ @start upperbar styling ~~~~~~~~~~~~*/ 34 | #bot_chat_window #upper_bar { 35 | /*width: 230px;*/ /*inherit*/ 36 | background: #043046/*#E6420C*/; 37 | background: #043046 url("../images/head_bg.png") repeat; 38 | padding: 10px; 39 | height: 14px; 40 | /* round corners */ 41 | -moz-border-radius: 5px 5px 0 0; 42 | -webkit-border-radius: 5px 5px 0 0; 43 | -khtml-border-radius: 5px 5px 0 0; 44 | border-radius: 5px 5px 0 0; 45 | } 46 | #bot_chat_window #upper_bar h3{ 47 | font-size: 14px; 48 | font-weight: normal; 49 | margin: 0; 50 | color: white; 51 | } 52 | #bot_chat_window #upper_bar a#bot_name { 53 | color: white; 54 | text-decoration: none; 55 | } 56 | #bot_chat_window #upper_bar a#max_icon { 57 | background: url('../images/buttons-light.png') no-repeat -80px 0px; 58 | width: 16px; 59 | height: 16px; 60 | float: right; 61 | /* round corners */ 62 | -moz-border-radius: 2px; 63 | -webkit-border-radius: 2px; 64 | -khtml-border-radius: 2px; 65 | border-radius: 2px; 66 | } 67 | #bot_chat_window.visible #upper_bar a#max_icon { 68 | background-position: -64px -1px; 69 | } 70 | #bot_chat_window #upper_bar a#max_icon:hover { 71 | background-color: #032333 /*#333333*/; 72 | } 73 | /*~~~~~~~~~~ @end upperbar styling ~~~~~~~~~~~~*/ 74 | 75 | /*~~~~~~~~~~ @start Avatar styling ~~~~~~~~~~~~*/ 76 | #bot_chat_window img#bot_avatar { 77 | width: 100px; 78 | /*height: 70px;*/ 79 | position: relative; 80 | top: -85px; 81 | } 82 | /*~~~~~~~~~~ @end Avatar styling ~~~~~~~~~~~~*/ 83 | #bot_chat_window #screen_wrapper { 84 | display: none; /* hide at start */ 85 | } 86 | #bot_chat_window.visible #screen_wrapper { 87 | display: block; 88 | } 89 | #bot_chat_window #screen_wrapper { 90 | background: whitesmoke; /* bg_color */ 91 | padding-bottom: 35px; /* */ 92 | } 93 | 94 | #bot_chat_window #screen_wrapper #screen { 95 | padding: 6px 10px 0 10px; 96 | max-height: 200px; 97 | min-height: 100px; 98 | overflow-y: auto; 99 | /*width: 230px;*/ /*inherit*/ 100 | } 101 | #bot_chat_window #screen_wrapper #screen .dia_entry { 102 | padding-left: 12px; 103 | line-height: 1.35em; 104 | margin-bottom: 3px; 105 | } 106 | #bot_chat_window #screen_wrapper #screen .dia_entry .nick { 107 | font-weight: bold; 108 | /*float: left;*/ 109 | margin-left: -12px; 110 | } 111 | #bot_chat_window #screen_wrapper #screen .dia_entry .text { 112 | /*margin-left: 5px;*/ 113 | 114 | } 115 | #bot_chat_window #screen_wrapper #meta_msgs { 116 | margin-left: 10px; 117 | font-size: 11px; 118 | color: #444; 119 | padding: 3px 0 1px 0; 120 | } 121 | 122 | 123 | /*~~~~~~~~~~ @begin bottom userbar form styling ~~~~~~~~~~~~*/ 124 | #bot_chat_window #screen_wrapper #userbar { 125 | 126 | } 127 | #bot_chat_window #screen_wrapper #userbar form { 128 | margin: 0px 0px 0px 10px; 129 | position: fixed; 130 | bottom: 0; 131 | background-color: whitesmoke; /* bg_color */ 132 | } 133 | #bot_chat_window #userbar form input[type="text"] { 134 | border: 1px solid #999999; 135 | padding: 4px; 136 | margin: 0 3px 5px 0; 137 | width: 170px; 138 | font-size: 0.9em; 139 | /* round corners */ 140 | -moz-border-radius: 3px; 141 | -webkit-border-radius: 3px; 142 | -khtml-border-radius: 3px; 143 | border-radius: 3px; 144 | } 145 | #bot_chat_window #userbar form input[type="text"]:focus { 146 | border-color: #666666; 147 | outline-color: #bbbbbb; 148 | } 149 | /*~~~~~~~~~~ @end bottom userbar form styling ~~~~~~~~~~~~*/ 150 | 151 | 152 | #bot_chat_window #msg_dialog{ 153 | position: fixed; 154 | bottom: 40px; 155 | left: 5px; 156 | left: 5%; /* same as chat window position */ 157 | margin-left: 5px; 158 | width: 215px; 159 | display: none; 160 | background: #444444; 161 | color: white; 162 | padding: 4px 12px; 163 | border-radius: 5px; 164 | opacity: 0.9; 165 | } 166 | /** ~~~~ @begin Feedback form styling ~~~~~~ **/ 167 | #bot_chat_window .feedback_form { 168 | margin: 0; 169 | text-align: center; 170 | } 171 | #bot_chat_window div.feedback_req { 172 | /*margin-left: 15px; 173 | margin-top: 2px; 174 | margin-bottom: 5px;*/ 175 | font-size: 11px; 176 | border: 1px solid #BBBBBB; 177 | border-radius: 3px; 178 | padding: 4px 8px 2px; 179 | display: inline-block; 180 | margin: 4px auto 6px; 181 | text-align: center; 182 | background: -webkit-linear-gradient(bottom, #DEDEDE, #EDEDED); 183 | } 184 | #bot_chat_window div.feedback_req:hover { 185 | border-color: #999999 186 | } 187 | #bot_chat_window div.feedback_req span{ 188 | vertical-align: top; /* text pos correction */ 189 | text-shadow: 0px 1px 0px white; 190 | } 191 | #bot_chat_window .feedback_req button { 192 | background-color: #CCCCCC; 193 | border: none; 194 | margin: 0; 195 | width: 14px; 196 | height: 14px; 197 | padding: 0; 198 | cursor: pointer; 199 | } 200 | #bot_chat_window .feedback_req span:first-child { 201 | margin-right: 2px; 202 | } 203 | #bot_chat_window .feedback_req button.ok { 204 | background-image: url('../images/ok.png'); 205 | background-position: -14px 0px; 206 | } 207 | #bot_chat_window .feedback_req button.ok:hover { 208 | background-position-y: -14px; 209 | } 210 | #bot_chat_window .feedback_req button.nok{ 211 | background-image: url('../images/nok.png'); 212 | background-position: -14px 0px; 213 | } 214 | #bot_chat_window .feedback_req button.nok:hover { 215 | background-position-y: -14px; 216 | } 217 | /** ~~~~ @end Feedback form styling ~~~~~~ **/ 218 | -------------------------------------------------------------------------------- /solr-elearning/src/main/java/es/upm/dit/gsi/solr/ElearningSolr.java: -------------------------------------------------------------------------------- 1 | package es.upm.dit.gsi.solr; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import java.util.Map; 6 | 7 | import net.sf.json.JSONObject; 8 | 9 | import org.apache.solr.client.solrj.SolrQuery; 10 | import org.apache.solr.client.solrj.SolrServer; 11 | import org.apache.solr.client.solrj.SolrServerException; 12 | import org.apache.solr.client.solrj.impl.HttpSolrServer; 13 | import org.apache.solr.common.SolrDocumentList; 14 | import org.apache.solr.common.SolrInputDocument; 15 | import org.apache.solr.common.params.CommonParams; 16 | import org.slf4j.Logger; 17 | 18 | /** 19 | * Wrapper for the solr server. 20 | * Connects to a "remote" solr server, and interacts with it as demanded. 21 | * 22 | * @author Alberto Mardomingo 23 | * @version 2014-11-20 24 | */ 25 | public class ElearningSolr { 26 | 27 | /** 28 | * The logger - configured elsewhere 29 | */ 30 | private Logger logger; 31 | 32 | /** 33 | * The solr server 34 | */ 35 | private SolrServer server; 36 | 37 | /** 38 | * The basic solr document fields 39 | * 40 | */ 41 | private String[] docFields; 42 | 43 | /** 44 | * The Fields Filter for the solr query. 45 | * 46 | */ 47 | private String[] fieldsFilter; 48 | 49 | /** 50 | * The "default" search tag 51 | * Usually, we use the "label" tag 52 | */ 53 | private String searchTag; 54 | 55 | /** 56 | * Creates the connector to the HTTP SolrServer, 57 | * without default values. 58 | * 59 | * It needs to be further configured! 60 | * 61 | * @param logger 62 | * @param serverUrl - The solr server url, including the core. 63 | */ 64 | public ElearningSolr(Logger logger, String serverURL) { 65 | this.logger = logger; 66 | this.server = new HttpSolrServer(serverURL); 67 | } 68 | 69 | /** 70 | * Creates the connector to the HTTP SolrServer 71 | * Fully configured 72 | * 73 | * @param logger 74 | * @param serverUrl - The solr server url, including the core. 75 | * @param docFields - The fields to return in a solr search 76 | * @param searchTag - The expected tag for searching the solr database 77 | */ 78 | public ElearningSolr(Logger logger, String serverURL, String[] docFields, String[] fieldsFilter, String searchTag) { 79 | this.logger = logger; 80 | this.server = new HttpSolrServer(serverURL); 81 | this.docFields = docFields; 82 | this.fieldsFilter = fieldsFilter; 83 | this.searchTag = searchTag; 84 | } 85 | 86 | 87 | /** 88 | * Adds a doc to the server. 89 | * 90 | * @param id 91 | * @param json 92 | * @throws IOException 93 | */ 94 | public void addDocument(String id, String json) throws SolrServerException, IOException{ 95 | // Empry solr document 96 | SolrInputDocument newDoc = new SolrInputDocument(); 97 | 98 | // I asume the json is directly the data we want to add 99 | JSONObject jsonObject = JSONObject.fromObject(json); 100 | 101 | // Converts the json to the doc, but only with the required fields. 102 | for(String fieldName : docFields) { 103 | if(jsonObject.has(fieldName)) 104 | newDoc.addField(fieldName, jsonObject.get(fieldName)); 105 | } 106 | 107 | //FIXME: We *may* be missing the id here. 108 | // Our best bet may be to configure solr, so the id field is autoincremented. 109 | 110 | this.server.add(newDoc); 111 | this.server.commit(); 112 | } 113 | 114 | /** 115 | * Returns the "default" search tag 116 | * 117 | * @return 118 | */ 119 | public String getSearchTag() { 120 | return this.searchTag; 121 | } 122 | 123 | /** 124 | * Sets the tag to use in the filter. 125 | */ 126 | public void setSearchTag(String searchTag) { 127 | this.searchTag = searchTag; 128 | } 129 | 130 | /** 131 | * If we want to have a "default" fields filter, 132 | * sets them. 133 | * 134 | * @param fields - the fieds to show in the result. 135 | */ 136 | public void setFieldsFilter(String[] fields){ 137 | this.fieldsFilter = fields; 138 | } 139 | 140 | /** 141 | * Given a String Query, performs a query to the server, 142 | * and return the relevant data. 143 | * It utilices the field general field filter, set with 144 | * the "setFieldsFilter" method. 145 | * 146 | * @param q - The query for the data 147 | * @param n - The max number of results 148 | * @return - An array with all the results 149 | */ 150 | public ArrayList search(String query, int n) throws SolrServerException, IOException{ 151 | return search(query, n, this.fieldsFilter); 152 | } 153 | 154 | /** 155 | * Given a String Query and a fieldFilter list, 156 | * performs a query to the server, and return the relevant data. 157 | * 158 | * @param q - The query for the data 159 | * @param fl - The list of fields to return 160 | * @param n - The max number of results 161 | * @return - An array with all the results 162 | */ 163 | public ArrayList search(String query, String[] fieldsList, int n) throws SolrServerException, IOException{ 164 | return search(query, n, fieldsList); 165 | } 166 | 167 | 168 | /** 169 | * 170 | * Given a String Query, performs a query to the server, 171 | * and return the relevant data. 172 | * 173 | * @param q - The query for the data 174 | * @param n - The max number of results 175 | * @param fields - The fields I want to return. 176 | * @return - An array with all the results 177 | */ 178 | public ArrayList search(String query, int n, String[] fields) throws SolrServerException, IOException{ 179 | SolrQuery sQuery = new SolrQuery(); 180 | // Sets the query 181 | sQuery.set(CommonParams.Q, query); 182 | 183 | // If I want the search to return all the fields stored, 184 | // the fields variable will be null. 185 | if(fields != null){ 186 | sQuery.set(CommonParams.FL, String.join(",",fields)); 187 | } 188 | SolrDocumentList qResults = this.server.query(sQuery).getResults(); 189 | 190 | ArrayList result = new ArrayList(); 191 | for(Map docResult: qResults) { 192 | 193 | JSONObject jsonResult = new JSONObject(); 194 | jsonResult.putAll((docResult)); 195 | 196 | result.add(jsonResult.toString()); 197 | 198 | } 199 | return result; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /Ask-Client/css/global.css: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~ @start background fake image ~~~~~~~~~*/ 2 | html { 3 | height: 100%; 4 | 5 | } 6 | 7 | body { 8 | /*background: #ffffff url('../images/bg_vademecum.png') no-repeat;*/ 9 | height: 100%; 10 | } 11 | 12 | 13 | /* Iframe with the vademecum */ 14 | 15 | #bot-target{ 16 | position: relative; 17 | z-index: 1; 18 | height: 100%; 19 | width: 100%; 20 | } 21 | 22 | #bot_chat_window { 23 | position: fixed; 24 | bottom: 0; 25 | left: 5%; 26 | font-family: 'Roboto', Arial, Trebuchet, 'Sans Serif'; 27 | font-size: 13px; 28 | width: 260px; 29 | z-index: 20; 30 | box-shadow: 1px 6px 10px 1px #333 31 | } 32 | 33 | /*~~~~~~~~~~ @start upperbar styling ~~~~~~~~~~~~*/ 34 | #bot_chat_window #upper_bar { 35 | /*width: 230px;*/ /*inherit*/ 36 | background: #043046; 37 | padding: 5px 5px; 38 | height: 24px; 39 | /* round corners */ 40 | -moz-border-radius: 5px 5px 0 0; 41 | -webkit-border-radius: 5px 5px 0 0; 42 | -khtml-border-radius: 5px 5px 0 0; 43 | border-radius: 5px 5px 0 0; 44 | } 45 | #bot_chat_window #upper_bar h3{ 46 | font-size: 14px; 47 | font-weight: normal; 48 | margin: 0; 49 | color: white; 50 | } 51 | #bot_chat_window #upper_bar a#bot_name { 52 | color: white; 53 | text-decoration: none; 54 | } 55 | #bot_chat_window #upper_bar a.icon{ 56 | width: 24px; 57 | height: 24px; 58 | float: right; 59 | display: block; 60 | margin-left: 2px; 61 | text-align: center; 62 | text-decoration: none; 63 | } 64 | #bot_chat_window #upper_bar a.icon:hover { 65 | background-color: #010f16; 66 | cursor: pointer; 67 | } 68 | #bot_chat_window #upper_bar a#max_icon span.max-icon { 69 | border-top: 2px solid white; 70 | border-bottom: 0px; 71 | display: block; 72 | margin: 5px; 73 | height: 14px; 74 | } 75 | #bot_chat_window.visible #upper_bar a#max_icon span.max-icon { 76 | border-bottom: 2px solid white; 77 | border-top: 0px; 78 | } 79 | #bot_chat_window #upper_bar a.icon#quiz{ 80 | display: none; 81 | } 82 | #bot_chat_window.visible #upper_bar a.icon#quiz{ 83 | display: block; 84 | } 85 | #bot_chat_window #upper_bar a.icon i.fa{ 86 | color: white; 87 | font-size: 24px; 88 | line-height: 24px; 89 | } 90 | #bot_chat_window #upper_bar a.icon#quiz i.fa{ 91 | font-size: 14px; 92 | } 93 | #bot_chat_window.visible #upper_bar a.icon i.fa-angle-up{ 94 | display: none; 95 | } 96 | #bot_chat_window #upper_bar a.icon i.fa-angle-up{ 97 | display: block; 98 | } 99 | #bot_chat_window.visible #upper_bar a.icon i.fa-angle-down{ 100 | display: block; 101 | } 102 | #bot_chat_window #upper_bar a.icon i.fa-angle-down{ 103 | display: none; 104 | } 105 | /*~~~~~~~~~~ @end upperbar styling ~~~~~~~~~~~~*/ 106 | 107 | /*~~~~~~~~~~ @start Avatar styling ~~~~~~~~~~~~*/ 108 | #bot_chat_window img#bot_avatar { 109 | width: 100px; 110 | /*height: 70px;*/ 111 | position: relative; 112 | top: -85px; 113 | } 114 | /*~~~~~~~~~~ @end Avatar styling ~~~~~~~~~~~~*/ 115 | #bot_chat_window #screen_wrapper { 116 | display: none; /* hide at start */ 117 | } 118 | #bot_chat_window.visible #screen_wrapper { 119 | display: block; 120 | } 121 | #bot_chat_window #screen_wrapper { 122 | background: whitesmoke; /* bg_color */ 123 | padding-bottom: 35px; /* */ 124 | } 125 | 126 | #bot_chat_window #screen_wrapper #screen { 127 | padding: 6px 10px 0 10px; 128 | max-height: 200px; 129 | min-height: 100px; 130 | overflow-y: auto; 131 | /*width: 230px;*/ /*inherit*/ 132 | } 133 | #bot_chat_window #screen_wrapper #screen .dia_entry { 134 | padding-left: 12px; 135 | line-height: 1.35em; 136 | margin-bottom: 3px; 137 | } 138 | #bot_chat_window #screen_wrapper #screen .dia_entry .nick { 139 | font-weight: bold; 140 | /*float: left;*/ 141 | margin-left: -12px; 142 | } 143 | #bot_chat_window #screen_wrapper #screen .dia_entry .text { 144 | margin-left: 3px; 145 | } 146 | #bot_chat_window #screen_wrapper #meta_msgs { 147 | margin-left: 10px; 148 | font-size: 11px; 149 | color: #444; 150 | padding: 3px 0 1px 0; 151 | } 152 | 153 | #username-container{ 154 | font-family: Ubuntu, Helvetica, 'Open Sans', SansSerif, Arial; 155 | } 156 | /*~~~~~~~~~~ @begin bottom userbar form styling ~~~~~~~~~~~~*/ 157 | #bot_chat_window #screen_wrapper #userbar { 158 | 159 | } 160 | #bot_chat_window #screen_wrapper #userbar form { 161 | margin: 0px 0px 0px 10px; 162 | position: fixed; 163 | bottom: 0; 164 | background-color: whitesmoke; /* bg_color */ 165 | } 166 | #bot_chat_window #userbar form input[type="text"] { 167 | border: 1px solid #999999; 168 | padding: 4px; 169 | margin: 0 3px 5px 0; 170 | width: 170px; 171 | font-size: 0.9em; 172 | /* round corners */ 173 | -moz-border-radius: 3px; 174 | -webkit-border-radius: 3px; 175 | -khtml-border-radius: 3px; 176 | border-radius: 3px; 177 | } 178 | #bot_chat_window #userbar form input[type="text"]:focus { 179 | border-color: #666666; 180 | outline-color: #bbbbbb; 181 | } 182 | /*~~~~~~~~~~ @end bottom userbar form styling ~~~~~~~~~~~~*/ 183 | 184 | 185 | #bot_chat_window #msg_dialog{ 186 | position: fixed; 187 | bottom: 40px; 188 | left: 5px; 189 | left: 5%; /* same as chat window position */ 190 | margin-left: 5px; 191 | width: 215px; 192 | display: none; 193 | background: #444444; 194 | color: white; 195 | padding: 4px 12px; 196 | border-radius: 5px; 197 | opacity: 0.9; 198 | } 199 | /** ~~~~ @begin Feedback form styling ~~~~~~ **/ 200 | #bot_chat_window .feedback_form { 201 | margin: 0; 202 | text-align: center; 203 | } 204 | #bot_chat_window div.feedback_req { 205 | /*margin-left: 15px; 206 | margin-top: 2px; 207 | margin-bottom: 5px;*/ 208 | font-size: 11px; 209 | border: 1px solid #BBBBBB; 210 | border-radius: 3px; 211 | padding: 4px 8px 2px; 212 | display: inline-block; 213 | margin: 4px auto 6px; 214 | text-align: center; 215 | background: -webkit-linear-gradient(bottom, #DEDEDE, #EDEDED); 216 | } 217 | #bot_chat_window div.feedback_req:hover { 218 | border-color: #999999 219 | } 220 | #bot_chat_window div.feedback_req span{ 221 | vertical-align: top; /* text pos correction */ 222 | text-shadow: 0px 1px 0px white; 223 | } 224 | #bot_chat_window .feedback_req button { 225 | background-color: #CCCCCC; 226 | border: none; 227 | margin: 0; 228 | width: 14px; 229 | height: 14px; 230 | padding: 0; 231 | cursor: pointer; 232 | } 233 | #bot_chat_window .feedback_req span:first-child { 234 | margin-right: 2px; 235 | } 236 | #bot_chat_window .feedback_req button.ok { 237 | background-image: url('../images/ok.png'); 238 | background-position: -14px 0px; 239 | } 240 | #bot_chat_window .feedback_req button.ok:hover { 241 | background-position-y: -14px; 242 | } 243 | #bot_chat_window .feedback_req button.nok{ 244 | background-image: url('../images/nok.png'); 245 | background-position: -14px 0px; 246 | } 247 | #bot_chat_window .feedback_req button.nok:hover { 248 | background-position-y: -14px; 249 | } 250 | /** ~~~~ @end Feedback form styling ~~~~~~ **/ 251 | -------------------------------------------------------------------------------- /test/Chatscript alone-evaluation/RAWDATA/simplecontrol.top: -------------------------------------------------------------------------------- 1 | outputmacro: testbot() 2 | 3 | ^addtopic(~TESTTOPIC) 4 | $control_pre = ~control 5 | $control_main = ~control 6 | $control_post = ~control 7 | $userprompt = ^"$login: >" 8 | $botprompt = ^"testbot: " 9 | 10 | # this function is executed once for every new user chatting with duke 11 | outputmacro: duke() # you get duke by default 12 | $token = #DO_INTERJECTION_SPLITTING | #DO_NUMBER_MERGE | #DO_PROPERNAME_MERGE | #DO_POSTAG | #DO_PARSE 13 | ^addtopic(~introductions) 14 | ^import("facts/kb-java" @0 keep permanent) 15 | ^createfact (kb loaded facts/kb-java) 16 | $control_pre = ~control 17 | $control_main = ~control 18 | $control_post = ~control 19 | $userprompt = ^"$login: >" 20 | $botprompt = ^"DUKE: " 21 | 22 | # this function is executed once for every new user chatting with georgia 23 | outputmacro: georgia() # you can request georgia by giving name:georgia as your login 24 | $token = #DO_INTERJECTION_SPLITTING | #DO_NUMBER_MERGE | #DO_PROPERNAME_MERGE | #DO_POSTAG | #DO_PARSE 25 | ^addtopic(~introductions) 26 | $control_pre = ~control 27 | $control_main = ~control 28 | $control_post = ~control 29 | $botprompt = ^"GEORGIA: " 30 | 31 | table: defaultbot (^name) 32 | ^createfact(^name defaultbot defaultbot) 33 | DATA: 34 | duke 35 | 36 | topic: ~control system () 37 | t: ($code=pre) #nothing to do for preprocessing 38 | end(TOPIC) 39 | 40 | t: ($code=post) # nothing to do for postprocessing 41 | end(TOPIC) 42 | 43 | 44 | ### Out-of-band tags ### 45 | 46 | #Import knowledge base from file 47 | #! [import facts/kb-java iteracion] 48 | u: ( \[ import _*1 _~javaconcept \] ) ^noerase() ^repeat() ^import('_0 @0 keep permanent) ^createfact (kb loaded '_0) \[sendcs \( java question '_1 \) \] 49 | 50 | 51 | 52 | #List the kbs loaded 53 | #! [listkb] 54 | u: ( \[ listkb \] ) ^noerase() ^repeat() ^query(direct_sv kb loaded ?) \[ kbs loaded: 55 | loop() 56 | { 57 | ^pick(@0object) 58 | } 59 | \] 60 | 61 | 62 | 63 | #Look up concept in knowledge base, if result found 64 | #! que significa iteracion 65 | u: ($bot=duke que significa _~javaconcept ) 66 | ^noerase() ^repeat() 67 | ^query(direct_sv _0 topic ?) 68 | _0 es un @0object 69 | ^query(direct_sv _0 content ?) 70 | . @0object. 71 | ^query(direct_sv _0 links_to ?) 72 | . Puedes preguntarme tambien sobre 73 | loop() 74 | { 75 | ^pick(@0object), 76 | } 77 | . Si quieres un ejemplo, puedes pedirlo. _@fullresponse 78 | 79 | 80 | #Look up concept in knowledge base, if no result found 81 | #! que significa iteracion 82 | u: ($bot=duke que significa _~javaconcept ) 83 | ^noerase() ^repeat() 84 | \[sendmaia retrieve _0\] 85 | 86 | 87 | 88 | 89 | #Look up example for a concept in knowledge base, if result found 90 | #! dame un ejemplo de iteracion 91 | u: ($bot=duke dame un ejemplo de _~javaconcept ) 92 | ^noerase() ^repeat() 93 | ^query(direct_sv _0 example ?) 94 | @0object _@fullresponse 95 | 96 | 97 | #Look up example for a concept in knowledge base, if no result found 98 | #! dame un ejemplo de iteracion 99 | u: ($bot=duke dame un ejemplo de _~javaconcept ) 100 | ^noerase() ^repeat() 101 | No tengo ejemplos para este concepto. 102 | 103 | 104 | u: ( \[ echo _* \] ) 105 | ^noerase() ^repeat() 106 | Echo _0 . 107 | 108 | 109 | u: ($code=main %input<%userfirstline) gambit(~introductions) 110 | 111 | u: ($code=main) # main per-sentence processing 112 | 113 | $currenttopic = %topic # get the current topic at start of volley 114 | 115 | nofail(TOPIC ^rejoinder()) # try for rejoinders. might generate an answer directly from what we are looking for. 116 | 117 | if (%length == 0 AND %response == 0 ) 118 | { 119 | nofail(TOPIC ^gambit($currenttopic)) # gambit current topic since no input (usually start of conversation) 120 | } 121 | 122 | if (%response == 0) { nofail(TOPIC ^respond($currenttopic)) } # current topic tries to respond to his input 123 | 124 | if (%response == 0) # see if some other topic has keywords matching his input (given we have no response yet) 125 | { 126 | @8 = ^keywordtopics() # get topics referred in input 127 | loop() 128 | { 129 | $$topic = first(@8subject) 130 | nofail(TOPIC ^respond($$topic)) 131 | if (%response != 0) # stop when we find something to say 132 | { 133 | ^end(RULE) # we are done, this terminates the loop (not the rule) 134 | } 135 | } 136 | } 137 | 138 | if (%response == 0 AND ^hasKeyword($currenttopic)) { nofail(TOPIC ^gambit($currenttopic)) } # gambit current topic since keywords match current topic 139 | 140 | if (%response == 0) # gambit from ANY matching topic 141 | { 142 | @8 = ^keywordtopics() # get topics referred in input 143 | loop() 144 | { 145 | $$topic = first(@8subject) 146 | nofail(TOPIC ^Gambit($$topic)) # gambit in best matching topic 147 | if (%response != 0) # stop when we find something 148 | { 149 | ^end(RULE) 150 | } 151 | } 152 | } 153 | if (%response == 0){ nofail(TOPIC ^gambit($currenttopic)) } # gambit from current topic even though no keywords matched 154 | 155 | if (%response == 0) 156 | { 157 | @8 = ^GambitTopics() # all topics with gambits (excluding system topics) 158 | loop() 159 | { 160 | $$topic = pick(@8) 161 | nofail(TOPIC ^Gambit($$topic)) # try a topic at random 162 | if (%response != 0) 163 | { 164 | ^end(RULE) 165 | } 166 | } 167 | } 168 | 169 | if (%response == 0) 170 | { 171 | ^repeat() 172 | No tengo respuesta para eso. 173 | } 174 | 175 | 176 | # BELOW is logically equivalent to the above topic 177 | 178 | topic: ~alternate_control system () 179 | t: ($code=pre) #nothing to do for preprocessing 180 | end(TOPIC) 181 | 182 | t: ($code=post) # nothing to do for postprocessing 183 | end(TOPIC) 184 | 185 | u: () $currenttopic = %topic # get the current topic at start of volley 186 | u: () ^rejoinder() # try for rejoinders. might generate an answer directly from what we are looking for. 187 | u: ( %response=0 %length=0) ^gambit($currenttopic) # gambit current topic since no input (usually start of conversation) 188 | u: (%response=0) ^respond($currenttopic) # current topic tries to respond to his input 189 | u: (%response=0) 190 | @8 = ^keywordtopics() # get topics referred in input 191 | loop() 192 | { 193 | $$topic = first(@8subject) 194 | nofail(TOPIC Respond($$topic)) 195 | if (%response != 0) # stop when we find something to say 196 | { 197 | ^end(TOPIC) # we are done, this terminates the loop (not the rule) 198 | } 199 | } 200 | u: (%response=0 ^hasKeyword($currenttopic)) ^gambit($currenttopic) # gambit current topic since keywords match current topic 201 | u: (%response=0 ) 202 | @8 = ^keywordtopics() # get topics referred in input 203 | loop() 204 | { 205 | $$topic = first(@8subject) 206 | nofail(TOPIC ^Gambit($$topic)) # gambit in best matching topic 207 | if (%response != 0) # stop when we find something 208 | { 209 | ^end(TOPIC) 210 | } 211 | } 212 | } 213 | u: (%response=0) ^gambit($currenttopic) # gambit from current topic even though no keywords matched 214 | u: (%response=0) 215 | @8 = ^GambitTopics() # all topics with gambits (excluding system topics) 216 | loop() 217 | { 218 | $$topic = pick(@8) 219 | NOFAIL(TOPIC ^Gambit($$topic)) # try a topic at random 220 | if (%response != 0) 221 | { 222 | ^end(TOPIC) 223 | } 224 | } 225 | u: (%response=0) 226 | ^repeat() 227 | I don't know what to say. 228 | -------------------------------------------------------------------------------- /ChatScript/RAWDATA/DENT/java.top: -------------------------------------------------------------------------------- 1 | topic: ~EJEMPLOS keep repeat [ejemplo ejemplar modelo prototipo patron] 2 | 3 | u: (~ejemplo ~preposiciones _*) 4 | $pregunta='_0 5 | ¬sendSolr examples $pregunta 6 | a:(¬solrResponse examples _*) 7 | [Te muestro el documento con ejemplos.] 8 | [Esto es lo que sé sobre $pregunta , incluidos sus ejemplos.] 9 | ¬sendSolr resource $pregunta 10 | b:(¬solrResponse resource _*) 11 | ¬resource '_0 12 | a:(¬solrResponse unknown) 13 | [Lo siento, no tengo ningun ejemplo sobre $pregunta ] 14 | [Vaya, pues no he encontrado nada sobre $pregunta . Qué raro...] 15 | ^reuse(JAVA.COMIENZO) 16 | 17 | u: EJEMPLO (~ejemplo $pregunta) 18 | ¬sendSolr examples $pregunta 19 | a:(¬solrResponse examples _*) 20 | [Te muestro el documento con ejemplos. ] 21 | [Esto son los ejemplos que tengo de $pregunta ] 22 | ¬sendSolr resource $pregunta 23 | b:(¬solrResponse resource _*) 24 | ¬resource '_0 25 | a:(¬solrResponse unknown) 26 | Lo siento, no tengo ningun ejemplo sobre $pregunta 27 | ^reuse(JAVA.COMIENZO) 28 | 29 | u: (~ejemplo) 30 | [¿Sobre qué quieres el ejemplo?] 31 | [¿Quieres un ejemplo? ¿Sobre qué?] 32 | a: (~preposiciones _*1 >) 33 | $pregunta='_0 34 | ^reuse(EJEMPLO) 35 | 36 | 37 | topic: ~JAVA keep repeat [~javaconcepts ~ide_list] 38 | 39 | # Place this here to have priority vs que es x questions 40 | #! que es un chatbot? 41 | u: (~que ~ser * _~bot) 42 | ^reuse(INTRO.BOT) 43 | 44 | u: (~que * ~hacer) 45 | ^reuse(INTRO.SABER_HACER) 46 | 47 | 48 | 49 | u: COMO_FUNCIONA_JAVA ([como_funcionan como_funciona como_va como_van] _{~articulos} * _~javaconcept) 50 | No se como funciona '_0 '_1. Te puedo dar información teorica. 51 | $pregunta='_1 52 | ¬sendSolr definition $pregunta 53 | ¬label $pregunta 54 | a: (¬solrResponse definition) 55 | ^reuse(DEFINTION) 56 | 57 | u: ([funcionan funciona construir construyen construye] _{~articulos} * _~javaconcept) 58 | ^reuse(COMO_FUNCIONA_JAVA) 59 | 60 | #! que es eclipse 61 | u: (que ~ser _~ide_list) 62 | [No sabría hablarte de las características exactas de '_0', pero puedes consultar esta comparativa] 63 | [Es un IDE de Java, ¿no? En esta página salen más] 64 | [Para saber de '_0, lo mejor será que mires esta comparativa de IDEs] 65 | ¬resource http://goo.gl/9gzJI7 66 | 67 | #! sabes utilizar eclipse 68 | u: (<<~saber [utilizar usar trabajar] ~ide_list>>) 69 | [No sé utilizar ningún IDE en particular, a mi me gusta más la teoría] 70 | 71 | #! como funciona eclipse 72 | u: ([como_funciona como_configuro como_configuras] ~ide_list) 73 | Para saber como funciona '_0 lo mejor es irse al manual 74 | ¬resource http://www.google.es/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=manual%20'_0 75 | 76 | #! en que entorno de desarrollo programas 77 | u: (que _~ide [utilizas programas usas]) 78 | [No sé utilizar ningún IDE en particular, a mi me gusta más la teoría] 79 | 80 | #! que IDE prefieres 81 | u: (que _~ide {~ser} {[recomiendas prefieres preferido mejor]}) 82 | [Mis programadores no tienen preferencias, así que te muestro una comparativa para que decidas tú mismo] 83 | [Yo no utilizo ningún '_0 en particular, pero échale un ojo a esto para comparar] 84 | ¬resource http://goo.gl/9gzJI7 85 | 86 | #! te suena DrJava? 87 | u: (_~ide_list) 88 | ¿Te refieres al entorno de desarrollo? Lo mejor será que mires esta comparativa 89 | ¬resource http://goo.gl/9gzJI7 90 | 91 | u: (_~javaconcept [vs v frente frente_a] _~javaconcept) 92 | No me han enseñado a comparar, pero puedo darte información de '_0 o de '_1 93 | a: ('_0) 94 | $pregunta='_0 95 | ¬sendSolr definition $pregunta 96 | ¬label $pregunta 97 | b: (¬solrResponse definition) 98 | ^reuse(DEFINTION) 99 | a: ('_1) 100 | $pregunta='_1 101 | ¬sendSolr definition $pregunta 102 | ¬label $pregunta 103 | b: (¬solrResponse definition) 104 | ^reuse(DEFINTION) 105 | 106 | 107 | #! Diferencias de java7 frente a java8 108 | u: (* [vs v frente frente_a] *) 109 | [No sabría decirte cual es la diferencia] 110 | [No sabría compararlos] 111 | 112 | #! Cual es la diferencia entre java7 y java8 113 | u: (diferencia {entre} *) 114 | No sé cuál es la diferencia. Soy más de dar información teórica 115 | 116 | ## Questions involving Solr 117 | 118 | #! que es un for? 119 | u: COMIENZO (~que ~ser {~articulos} * > _*-1 >) # This semi-weird pattern will return the last word of the sentence 120 | $questioned += 1 121 | $pregunta='_0 122 | ¬sendSolr definition $pregunta 123 | ¬label $pregunta 124 | 125 | # Process the maia responses 126 | a: DEFINTION (¬solrResponse definition) 127 | [Te enseño la información que tengo sobre $pregunta] 128 | [Esto es lo que sé sobre $pregunta] 129 | ¬sendSolr resource $pregunta 130 | 131 | # Ask for the link to show in the frame 132 | b: (¬solrResponse resource _*) 133 | ¬resource '_0 _ ¬sendSolr links $pregunta 134 | c: (¬solrResponse links _*) 135 | ¬solrLinks '_0 _ 136 | d: (¬solrLinksResponse _*) 137 | [También puedes preguntar sobre '_0] 138 | [Otros asuntos de los que entiendo son '_0] 139 | [Si quieres, creo que '_0 tienen algo que ver con esto] 140 | e: (~afirmacion_fuerte) 141 | $pregunta=$links 142 | Perfecto! 143 | ^reuse(COMIENZO) 144 | e: (~afirmacion_debil) 145 | $pregunta=$links 146 | ^reuse(COMIENZO) 147 | e: (~ser eso) 148 | ^reuse(COMIENZO) 149 | e: (~negacion) 150 | Vaya... bueno, puedes preguntarme sobre alguna otra cosa 151 | e:(¬solrResponse unknown) 152 | Lo siento, no tengo información sobre $pregunta 153 | c:(¬solrResponse unknown) 154 | _ 155 | b: () # No matter if there is a link or not, ask for related 156 | ¬sendSolr links $pregunta 157 | c: (¬solrResponse links _*) 158 | $links='_0 159 | [También puedes preguntar sobre '_0] 160 | [Otros asuntos de los que entiendo son '_0] 161 | [Si quieres, creo que '_0 tienen algo que ver con esto] 162 | d: (~afirmacion_fuerte) 163 | $pregunta=$links 164 | Perfecto! 165 | ^reuse(COMIENZO) 166 | d: (~afirmacion_debil) 167 | $pregunta=$links 168 | ^reuse(COMIENZO) 169 | d: (~ser eso) 170 | ^reuse(COMIENZO) 171 | d: (~negacion) 172 | Vaya... bueno, puedes preguntarme sobre alguna otra cosa 173 | c:(¬solrResponse unknown) 174 | Lo siento, no tengo información sobre $pregunta 175 | 176 | a: (¬solrResponse unknown) 177 | ^reuse(GAMBIT) 178 | 179 | #! como hago un bucle 180 | u: (~como [~hacer ~funcionar] {~articulos} * > _*-1 >) 181 | $pregunta='_0 182 | ^reuse(COMIENZO) 183 | 184 | t: ($questioned) ¿Te gusta Java? 185 | a: ([~afirmacion ~afirmacion_debil]) 186 | A mi también, por algo soy la mascota ¡Mira! 187 | ¬resource http://goo.gl/goJKgo 188 | a: (~negacion) 189 | ¿Prefieres otro lenguaje? 190 | b: (~afirmacion) 191 | ¿Cual? 192 | 193 | t: (!$questioned<1) Ahora pregunto yo ¿Qué palabras clave se utilizan para salir de un bucle? 194 | a: (break) 195 | Casi, te faltó continue 196 | a: (continue) 197 | Casi, te faltó break 198 | a: (<>) 199 | ¡Correcto! 200 | a: (*) La respuesta era break y continue 201 | 202 | 203 | --------------------------------------------------------------------------------