180 lines
6.2 KiB
Python
180 lines
6.2 KiB
Python
import os
|
|
from dash_extensions.enrich import Dash, Input, Output, State, Trigger, callback, ALL, MATCH
|
|
import dash_core_components as dcc
|
|
from dash_html_components import Div, Label
|
|
from dash_local_react_components import load_react_component
|
|
import ai
|
|
|
|
app = Dash(__name__)
|
|
|
|
Magi = load_react_component(app, 'components', 'magi.js')
|
|
WiseMan = load_react_component(app, 'components', 'wise_man.js')
|
|
Response = load_react_component(app, 'components', 'response.js')
|
|
Modal = load_react_component(app, 'components', 'modal.js')
|
|
Header = load_react_component(app, 'components', 'header.js')
|
|
Status = load_react_component(app, 'components', 'status.js')
|
|
|
|
app.layout = Div(
|
|
className='system',
|
|
children=[
|
|
Magi(id='magi', children=[
|
|
Header(side='left', title='質 問'),
|
|
Header(side='right', title='解 決'),
|
|
Status(id='status'),
|
|
WiseMan(
|
|
id={'type': 'wise-man', 'name': 'melchior'},
|
|
name='melchior',
|
|
order_number=1,
|
|
personality='You are a scientist. Your goal is to further our understanding of the universe and advance our technological progress.'),
|
|
WiseMan(
|
|
id={'type': 'wise-man', 'name': 'balthasar'},
|
|
name='balthasar',
|
|
order_number=2,
|
|
personality='You are a mother. Your goal is to protect your children and ensure their well-being.'),
|
|
WiseMan(
|
|
id={'type': 'wise-man', 'name': 'casper'},
|
|
name='casper',
|
|
order_number=3,
|
|
personality='You are a woman. Your goal is to pursue love, dreams and desires.'),
|
|
Response(id='response', status='info')
|
|
]),
|
|
Div(className='input-container', children=[
|
|
Label('access code: '),
|
|
dcc.Input(id='key', autoComplete='off', type='password', value=os.getenv('OPENAI_API_KEY', '')),
|
|
Label('question: '),
|
|
dcc.Input(id='query', type='text', value='', debounce=True, autoComplete='off'),
|
|
]),
|
|
Modal(id={'type': 'modal', 'name': 'melchior'}, name='melchior'),
|
|
Modal(id={'type': 'modal', 'name': 'balthasar'}, name='balthasar'),
|
|
Modal(id={'type': 'modal', 'name': 'casper'}, name='casper'),
|
|
|
|
dcc.Store(id='question', data={'id': 0, 'query': ''}),
|
|
dcc.Store(id='annotated-question', data={'id': 0, 'query': '', 'is_yes_or_no_question': False}),
|
|
dcc.Store(id='is_yes_or_no_question', data=False),
|
|
dcc.Store(id='question-id', data=0),
|
|
])
|
|
|
|
|
|
@callback(
|
|
Output('question', 'data'),
|
|
Input('query', 'value'),
|
|
State('question', 'data'),
|
|
prevent_initial_call=True)
|
|
def question(query: str, question: dict):
|
|
return {'id': question['id'] + 1, 'query': query}
|
|
|
|
|
|
@callback(
|
|
Output('annotated-question', 'data'),
|
|
Input('question', 'data'),
|
|
State('key', 'value'),
|
|
prevent_initial_call=True)
|
|
def annotated_question(question: dict, key: str):
|
|
try:
|
|
is_yes_or_no_question = ai.is_yes_or_no_question(question['query'], key)
|
|
|
|
return {
|
|
'id': question['id'],
|
|
'query': question['query'],
|
|
'is_yes_or_no_question': is_yes_or_no_question,
|
|
'error': None
|
|
}
|
|
except Exception as e:
|
|
return {
|
|
'id': question['id'],
|
|
'query': question['query'],
|
|
'is_yes_or_no_question': False,
|
|
'error': str(e)
|
|
}
|
|
|
|
|
|
@callback(
|
|
Output('status', 'extention'),
|
|
Input('question', 'data'),
|
|
Input('annotated-question', 'data'))
|
|
def extention(question: dict, annotated_question: dict):
|
|
if question['id'] != annotated_question['id']:
|
|
return '????'
|
|
|
|
return '7312' if annotated_question['is_yes_or_no_question'] else '3023'
|
|
|
|
|
|
@callback(
|
|
Output({'type': 'wise-man', 'name': MATCH}, 'answer'),
|
|
Input('annotated-question', 'data'),
|
|
State({'type': 'wise-man', 'name': MATCH}, 'personality'),
|
|
State('key', 'value'),
|
|
prevent_initial_call=True)
|
|
def wise_man_answer(question: dict, personality: str, key: str):
|
|
if question['error']:
|
|
return {'id': question['id'], 'response': question['error'], 'status': 'error'}
|
|
|
|
try:
|
|
answer = ai.get_answer(question['query'], personality, key)
|
|
|
|
if question['is_yes_or_no_question']:
|
|
classification = ai.classify_answer(question['query'], personality, answer, key)
|
|
else:
|
|
classification = {'status': 'info', 'conditions': None}
|
|
|
|
return {'id': question['id'], 'response': answer, 'status': classification['status'], 'conditions': classification['conditions'], 'error': None}
|
|
|
|
except Exception as e:
|
|
return {'id': question['id'], 'response': None, 'status': 'error', 'conditions': 'None', 'error': str(e)}
|
|
|
|
|
|
@callback(
|
|
Output({'type': 'wise-man', 'name': MATCH}, 'question_id'),
|
|
Input('question', 'data'))
|
|
def wise_man_question_id(question: dict):
|
|
return question['id']
|
|
|
|
|
|
@callback(
|
|
Output('response', 'question_id'),
|
|
Input('question', 'data'))
|
|
def response_question_id(question: dict):
|
|
return question['id']
|
|
|
|
|
|
@callback(
|
|
Output('response', 'status'),
|
|
Output('response', 'answer_id'),
|
|
Input({'type': 'wise-man', 'name': ALL}, 'answer'),
|
|
prevent_initial_call=True)
|
|
def response_status(answers: list):
|
|
answer_id = min([answer['id'] for answer in answers])
|
|
status = 'info'
|
|
|
|
if any([answer['status'] == 'error' for answer in answers]):
|
|
status = 'error'
|
|
elif any([answer['status'] == 'no' for answer in answers]):
|
|
status = 'no'
|
|
elif any([answer['status'] == 'conditional' for answer in answers]):
|
|
status = 'conditional'
|
|
elif all([answer['status'] == 'yes' for answer in answers]):
|
|
status = 'yes'
|
|
|
|
return status, answer_id
|
|
|
|
|
|
@callback(
|
|
Output({'type': 'modal', 'name': MATCH}, 'is_open'),
|
|
Trigger({'type': 'wise-man', 'name': MATCH}, 'n_clicks'),
|
|
prevent_initial_call=True)
|
|
def modal_visibility():
|
|
return True
|
|
|
|
|
|
@callback(
|
|
Output({'type': 'modal', 'name': MATCH}, 'question'),
|
|
Output({'type': 'modal', 'name': MATCH}, 'answer'),
|
|
Input('question', 'data'),
|
|
Input({'type': 'wise-man', 'name': MATCH}, 'answer'))
|
|
def modal_content(question: dict, answer: dict):
|
|
return question, answer
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app.run_server(debug=True)
|