Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions src/api/fixtures/initial.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
"salut"
],
"project": 1
}
}
},
{
"model": "api.intent",
Expand All @@ -157,7 +157,7 @@
"jamais"
],
"project": 1
}
}
},
{
"model": "api.intent",
Expand Down Expand Up @@ -380,7 +380,7 @@
{
"model": "api.utter",
"pk": 1,

"fields": {
"name": "utter_default",
"multiple_alternatives": true,
Expand Down Expand Up @@ -436,8 +436,8 @@
"pk": 5,
"fields": {
"name": "utter_tudo_bem",
"multiple_alternatives": false,
"alternatives":[
"multiple_alternatives": false,
"alternatives":[
["Tudo bem, obrigada! Em que posso te ajudar?"]
],
"project": 1
Expand All @@ -449,9 +449,9 @@
"fields": {
"name": "utter_continuar_conversa",
"multiple_alternatives": false,
"alternatives":[
"alternatives":[
[" E aí, qual nosso próximo assunto?"]

],
"project": 1
}
Expand All @@ -462,20 +462,20 @@
"fields": {
"name": "utter_contato",
"multiple_alternatives": false,
"alternatives":[
"alternatives":[
["Para entrar em contato por meio do Suporte bastante acessar este link: lappis.rocks"]

],
"project": 1
}
},
},
{
"model": "api.utter",
"pk": 8,
"fields": {
"name": "utter_endereco",
"multiple_alternatives": false,
"alternatives":[
"alternatives":[
["O Lappis fica na Universidade de Brasília, campus do Gama"]

],
Expand All @@ -488,7 +488,7 @@
"fields": {
"name": "utter_definicao",
"multiple_alternatives": true,
"alternatives":[
"alternatives":[
["Eu sou uma assistente virtual da Secretaria Especial da Cultura, meu objetivo é tirar dúvidas sobre a Lei de Incentivo à Cultura."],
["Uma assistente virtual é uma inteligência artificial criada para interagir com as pessoas."],
["Para me comunicar com vocês utilizo algoritmos de aprendizagem profundo (deep learning) e sou toda software livre :P"],
Expand All @@ -504,7 +504,7 @@
"fields": {
"name": "utter_quem_criou_a_tais",
"multiple_alternatives": true,
"alternatives":[
"alternatives":[
["Fui desenvolvida pelo LAPPIS (Laboratório Avançado de Produção Pesquisa e Inovação em Software) na Universidade de Brasília, um laboratório super inovador e descolado!"],
["Se quiser me conhecer mais, acesse o meu projeto :) https://github.com/lappis-unb/tais"]

Expand All @@ -518,7 +518,7 @@
"fields": {
"name": "utter_elogios",
"multiple_alternatives": false,
"alternatives":[
"alternatives":[
["Obrigada! É sempre bom dar e receber elogios :P"]

],
Expand All @@ -531,7 +531,7 @@
"fields": {
"name": "utter_tem_wpp",
"multiple_alternatives": false,
"alternatives":[
"alternatives":[
["Eu não tenho wpp, eu só posso me comunicar com você aqui pelo portal, aqui é minha casa."]

],
Expand All @@ -544,7 +544,7 @@
"fields": {
"name": "utter_o_que_sei_falar",
"multiple_alternatives": true,
"alternatives":[
"alternatives":[
["Veja alguns dos assuntos em que posso te ajudar :)"],
["Agora que você já sabe do que podemos conversar, vou te dar outras dicas..."],
["Eu consigo te entender melhor quando você me faz perguntas curtas e me manda uma pergunta de cada vez."],
Expand All @@ -561,7 +561,7 @@
"fields": {
"name": "utter_menu",
"multiple_alternatives": true,
"alternatives":[
"alternatives":[
["Podemos conversar sobre como submeter um projeto, as etapas, algumas dúvidas operacionais…"],
["Ou se você já tiver um projeto cadastrado, a gente pode falar sobre isso também."],
["Para lembrar dos assuntos que eu domino, é só digitar: MEAJUDA"],
Expand All @@ -577,7 +577,7 @@
"fields": {
"name": "utter_agradecimento",
"multiple_alternatives": true,
"alternatives":[
"alternatives":[
["De nada, é sempre um prazer ajudar!"],
["Qual o próximo assunto que te interessa?"]

Expand All @@ -591,7 +591,7 @@
"fields": {
"name": "utter_definicao_tais",
"multiple_alternatives": false,
"alternatives":[
"alternatives":[
["Eu sou uma assistente virtual da Secretaria Especial da Cultura, meu objetivo é tirar dúvidas sobre a Lei de Incentivo à Cultura.",
"Uma assistente virtual é uma inteligência artificial criada para interagir com as pessoas. Para me comunicar com vocês utilizo algoritmos de aprendizagem profundo (deep learning) e sou toda software livre :P",
"Em cada interação que temos aqui, eu aprendendo mais para que a gente se comunique melhor. Obrigada por conversar comigo!"]
Expand All @@ -605,7 +605,7 @@
"fields": {
"name": "utter_objetivo",
"multiple_alternatives": false,
"alternatives":[
"alternatives":[
["Mas antes, para a nossa conversa ser mais eficiente, você quer saber como submeter uma proposta?"]
],
"project": 1
Expand All @@ -615,6 +615,7 @@
"model": "api.story",
"pk": 1,
"fields": {
"is_checkpoint": true,
"content":[
{"type": "intent", "name": "quem_criou_a_tais"},
{"type": "utter", "name": "utter_definicao_tais"},
Expand Down Expand Up @@ -691,7 +692,8 @@
"content":[
{"type": "intent", "name": "endereco"},
{"type": "utter", "name": "utter_endereco"},
{"type": "utter", "name": "utter_continuar_conversa"}
{"type": "utter", "name": "utter_continuar_conversa"},
{"type": "checkpoint", "name": "Diálogo_RasaBot_1" }
]
}
},
Expand Down
18 changes: 18 additions & 0 deletions src/api/migrations/0003_story_is_checkpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.6 on 2019-10-03 15:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0002_auto_20190909_1838'),
]

operations = [
migrations.AddField(
model_name='story',
name='is_checkpoint',
field=models.BooleanField(default=False),
),
]
2 changes: 1 addition & 1 deletion src/api/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .project import Project, ProjectSerializer
from .intent import Intent, IntentSerializer, IntentListSerializer, IntentExampleSerializer
from .utter import Utter, UtterSerializer, UtterListSerializer, UtterExampleSerializer
from .story import Story, StorySerializer, StoryListSerializer
from .story import Story, StorySerializer, StoryListSerializer, CheckpointSerializer, CheckpointListSerializer
56 changes: 40 additions & 16 deletions src/api/models/story.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,38 @@ class Story(models.Model):
project = models.EmbeddedModelField(
model_container=Project
)
is_checkpoint = models.BooleanField(default=False)

objects = models.DjongoManager()

class StorySerializer(serializers.ModelSerializer):
content = serializers.SerializerMethodField()

def get_example(self, obj):
intent_ids = [element['id'] for element in obj.content if element['type'] == 'intent']
intents = Intent.objects.filter(pk__in=intent_ids)

utter_ids = [element['id'] for element in obj.content if element['type'] == 'utter']
utters = Utter.objects.filter(pk__in=utter_ids)
for i, element in enumerate(obj.content):

elements = {}
elements['intent'] = intents
elements['utter'] = utters
if element['type'] == 'utter':
element_obj = Utter.objects.filter(pk=element['id']).first()
obj.content[i]['example'] = random.choice(getattr(element_obj, 'alternatives'))
obj.content[i]['name'] = getattr(element_obj, 'name')
elif element['type'] == 'intent':
element_obj = Intent.objects.filter(pk=element['id']).first()
obj.content[i]['example'] = random.choice(getattr(element_obj, 'samples'))
obj.content[i]['name'] = getattr(element_obj, 'name')
elif element['type'] == 'checkpoint':
element_obj = Story.objects.filter(pk=element['id']).first()
obj.content[i]['name'] = getattr(element_obj, 'name')

field = {}
field['intent'] = 'samples'
field['utter'] = 'alternatives'

for i, element in enumerate(obj.content):
element_obj = elements[element['type']].filter(pk=element['id']).first()
obj.content[i]['example'] = random.choice(getattr(element_obj, field[element['type']]))
obj.content[i]['name'] = getattr(element_obj, 'name')

def get_content(self, obj):
self.get_example(obj)
return [dict(content) for content in obj.content]

class Meta:
model = Story
fields = ['id', 'name', 'content']
fields = ['id', 'name', 'content', 'is_checkpoint']

class StoryListSerializer(serializers.ModelSerializer):
content = serializers.SerializerMethodField()
Expand All @@ -57,4 +56,29 @@ def get_content(self, obj):

class Meta:
model = Story
fields = ['id', 'name', 'content']
fields = ['id', 'name', 'content']


class CheckpointSerializer(serializers.ModelSerializer):
content = serializers.SerializerMethodField()

def get_content(self, obj):
StorySerializer.get_example(self, obj)

return [{
'id': content['id'],
'name': content['name'],
'example': content['example'],
'type': content['type']
} for content in obj.content]

class Meta:
model = Story
fields = ['id', 'name', 'content']


class CheckpointListSerializer(serializers.ModelSerializer):

class Meta:
model = Story
fields = ['id', 'name']
28 changes: 19 additions & 9 deletions src/api/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ def format_utter(utter_name):
else:
return utter_name

def format_checkpoint(name):
return "checkpoint_" + name

class StoryParser:
"""
Generate a markdown string from a given
Expand All @@ -16,23 +19,30 @@ class StoryParser:
def parse(self, story: Story):
name = f'## {unidecode(story.name)}\n'
body = ''


if story.is_checkpoint:
body += self._checkpoint_parser(story.name)

for c in story.content:
if c['type'] == "intent":
body += self._intent_parser(c)
elif c['type'] == "utter":
body += '\t' + self._utter_parser(c)
elif c['type'] == "checkpoint":
body += self._checkpoint_parser(c["name"])

return name + body + '\n'


def _intent_parser(self, intent):
return f'* {unidecode(intent["name"])}\n'


def _utter_parser(self, utter):
return f'- {unidecode(format_utter(utter["name"]))}\n'

def _checkpoint_parser(self, name):
return f'> {unidecode(format_checkpoint(name))}\n'


class IntentParser:
"""
Expand All @@ -55,7 +65,7 @@ class DomainParser:
"""
def parse(self, project: Project):
content = ''

intents = Intent.objects.filter(project=project)
utters = Utter.objects.filter(project=project)
entities = []
Expand All @@ -67,25 +77,25 @@ def parse(self, project: Project):
# content += self._generic_list_parser('entities', [e.name for e in entities])
content += self._templates_parser(utters)
content += self._generic_list_parser('actions', [unidecode(format_utter(u.name)) for u in utters])

return content

def _generic_list_parser(self, name: str, elements: list):
result = f'{unidecode(name)}:\n'

for e in elements:
result += f' - {e}\n'

return result + '\n'





def _templates_parser(self, utters: list):
result = f'templates:\n'

for u in utters:
for u in utters:
ident = 2 * ' '
utter_name = format_utter(u.name)
result += f'{ident}{unidecode(utter_name)}:\n'
Expand All @@ -96,5 +106,5 @@ def _templates_parser(self, utters: list):
ident = 10 * ' '
result += f'{ident}{t}\n'
result += f'\n'

return result + '\n'
4 changes: 3 additions & 1 deletion src/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
path('projects/<int:project_id>/intents/<int:intent_id>', ListIntents.as_view()),
path('projects/<int:project_id>/intents/<int:intent_id>/example', ListIntentExample.as_view()),
path('projects/<int:project_id>/utters/', ListUtters.as_view()),
path('projects/<int:project_id>/utters/<int:utter_id>', ListUtters.as_view()),
path('projects/<int:project_id>/utters/<int:utter_id>', ListUtters.as_view()),
path('projects/<int:project_id>/utters/<int:utter_id>/example', ListUtterExample.as_view()),
path('projects/<int:project_id>/stories/', ListStories.as_view()),
path('projects/<int:project_id>/stories/<int:story_id>', ListStories.as_view()),
path('projects/<int:project_id>/stories/checkpoints', ListCheckpoints.as_view()),
path('projects/<int:project_id>/stories/<int:story_id>/checkpoint', ListCheckpoints.as_view()),
path('files/<int:project_id>/stories/', StoriesFile.as_view(), name='stories-file'),
path('files/<int:project_id>/intents/', IntentsFile.as_view(), name='intents-file'),
path('files/<int:project_id>/domain/', DomainFile.as_view(), name='domain-file'),
Expand Down
Loading