Final touches to the style.

This commit is contained in:
Tomasz Rewak
2023-05-16 15:23:02 +02:00
parent 9f3b8a616d
commit 07e0f292fb
5 changed files with 253 additions and 82 deletions
+6 -8
View File
@@ -28,13 +28,12 @@ def get_answer(question: str, personality: str, key: str):
response = openai.ChatCompletion.create(
model='gpt-3.5-turbo',
messages=[
{'role': 'system', 'content': personality},
{'role': 'system', 'content': 'Your answers are rather concise.'},
{'role': 'system', 'content': f'{personality} Your answers are rather concise.'},
{'role': 'user', 'content': question},
]
)
return response['choices'][0]['text']
return response['choices'][0]['message']['content']
def classify_answer(question: str, personality: str, answer: str, key: str):
@@ -42,8 +41,7 @@ def classify_answer(question: str, personality: str, answer: str, key: str):
response = openai.ChatCompletion.create(
model='gpt-3.5-turbo',
messages=[
{'role': 'system', 'content': personality},
{'role': 'system', 'content': 'Your answers are rather concise.'},
{'role': 'system', 'content': f'{personality} Your answers are rather concise.'},
{'role': 'user', 'content': question},
{'role': 'system', 'content': answer},
{'role': 'user', 'content': 'Summarize you answer with a simple "yes" or "no" (answering with a single word). If (and only if) that\'s not possible, instead of answering with "yes" or "no", list conditions under which the answer would be "yes".'},
@@ -53,9 +51,9 @@ def classify_answer(question: str, personality: str, answer: str, key: str):
content = response['choices'][0]['message']['content']
if re.match('^\W*yes\W*$', content, re.IGNORECASE):
return {'classification': True, 'conditions': None}
return {'status': 'yes', 'conditions': None}
if re.match('^\W*no\W*$', content, re.IGNORECASE):
return {'classification': False, 'conditions': None}
return {'status': 'no', 'conditions': None}
return {'classification': True, 'conditions': content}
return {'status': 'conditional', 'conditions': content}
+69 -4
View File
@@ -1,11 +1,21 @@
body {
background: black;
html {
background: repeating-linear-gradient(45deg, rgb(0 0 0) 0px, rgb(0 0 0) 20px, #211200 20px, #211200 40px);
min-height: 100vh;
}
input {
body {
margin: 15px;
}
.system {
background: black;
border: 2px solid #ff8d00;
color: #ff8d00;
padding: 15px;
max-width: 1500px;
display: flex;
flex-direction: column;
position: relative;
margin: 0 auto;
}
.magi {
@@ -87,6 +97,7 @@ input {
display: flex;
background: #ff8d00;
padding: 2px;
cursor: pointer;
}
.magi>.wise-man>.inner {
@@ -161,4 +172,58 @@ input {
.connection.balthasar-melchior {
grid-area: 4 / 5 / 5 / 6;
transform: rotate(54deg);
}
.modal {
border: 2px solid #ff8d00;
color: #ff8d00;
font-family: 'Helvetica';
font-family: 'Lucida Console';
position: absolute;
background: black;
max-width: 40vw;
top: 10vh;
right: 10vw;
}
.modal>.modal-header {
display: flex;
flex-direction: row;
border-bottom: 2px solid #ff8d00;
}
.modal>.modal-header>.modal-title {
flex: 1;
padding: 5px;
background: repeating-linear-gradient(45deg, rgb(0 0 0) 0px, rgb(0 0 0) 10px, #211200 10px, #211200 20px);
}
.modal>.modal-header>.close {
padding: 5px;
border-left: 2px solid #ff8d00;
cursor: pointer;
}
.modal>.modal-body {
display: grid;
grid-template-columns: auto auto;
column-gap: 10px;
padding: 10px;
}
.input-container {
display: grid;
grid-template-columns: auto 1fr;
color: #ff8d00;
font-family: 'Helvetica';
font-family: 'Lucida Console';
column-gap: 10px;
row-gap: 5px;
margin-top: 15px;
}
.input-container > input {
background: #211200;
border: 2px solid #ff8d00;
color: #ff8d00;
}
+34
View File
@@ -0,0 +1,34 @@
import React from 'react';
export default function Modal({ setProps, name, is_open, question, answer }) {
if (!is_open) return null;
const questionId = question.id;
const answerId = answer.id;
if (questionId !== answerId)
answer = { id: questionId, status: 'error', error: 'questionId !== answerId' };
const close = () => {
setProps({ is_open: false });
};
return React.createElement('div', { className: 'modal' }, [
React.createElement('div', { className: 'modal-header' }, [
React.createElement('div', { className: 'modal-title' }, [name]),
React.createElement('div', { className: 'close', onClick: close }, ['X']),
]),
React.createElement('div', { className: 'modal-body' }, [
React.createElement('div', {}, 'question: '),
React.createElement('div', {}, question.query),
React.createElement('div', {}, 'status: '),
React.createElement('div', {}, answer.status),
React.createElement('div', {}, 'error: '),
React.createElement('div', {}, answer.error),
React.createElement('div', {}, 'conditions: '),
React.createElement('div', {}, answer.conditions),
React.createElement('div', {}, 'full response: '),
React.createElement('div', {}, answer.response)
]),
]);
}
+15 -4
View File
@@ -11,22 +11,33 @@ function useColor(status) {
if (status === 'info')
return '#3caee0';
if (status == 'conditional')
if (status === 'conditional')
return 'repeating-linear-gradient(56deg, rgb(82, 230, 145) 0px, rgb(82, 230, 145) 30px, #82cd68 30px, #82cd68 60px)';
if (status === 'error')
return 'black';
throw new Error(`Invalid status: ${status}`);
}
export default function WiseMan(props) {
const { setProps, name, order_number, question_id, answer } = props;
const { setProps, name, order_number, question_id, answer, n_clicks } = props;
const fullName = `${name.toUpperCase()}${order_number}`;
const color = useColor(answer['status']);
const processing = question_id !== answer['id'];
return React.createElement('div', { className: `wise-man ${name}` },
const onClick = () => {
setProps({ n_clicks: n_clicks + 1 });
};
return React.createElement('div', { className: `wise-man ${name}`, onClick: onClick, key: name },
[
React.createElement('div', { className: `inner ${processing ? 'flicker' : ''}`, style: { background: color } }, [
fullName
])
])
}
}
WiseMan.defaultProps = {
n_clicks: 0
};
+129 -66
View File
@@ -1,10 +1,9 @@
from dataclasses import dataclass
import os
from dash_extensions.enrich import Dash, Input, Output, State, Trigger, callback, ALL, MATCH
from dash_extensions.enrich import Dash, Input, Output, State, Trigger, callback, ALL, MATCH, callback_context
import dash_core_components as dcc
import dash_html_components as html
from dash_local_react_components import load_react_component
import random
import ai
app = Dash(__name__)
@@ -12,67 +11,76 @@ 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')
app.layout = html.Div(children=[
Magi(id='magi', children=[
html.Div(className='connection casper-balthasar'),
html.Div(className='connection casper-melchior'),
html.Div(className='connection balthasar-melchior'),
html.Div(
className='system-status',
children=[
html.Div(children='CODE:473'),
html.Div(children='FILE:MAGI_SYS'),
html.Div(id='extention', children='EXTENTION:????'),
html.Div(children='EX_MODE:OFF'),
html.Div(children='PRIORITY:AAA')]),
WiseMan(
id={'type': 'wise-man', 'name': 'melchior'},
name='melchior',
order_number=1,
personality='You are a scientist. Your goal is to further our our understanding of the universe and advance our technological progress.',
question_id=0,
answer={'id': 0, 'response': 'yes', 'status': 'yes'}),
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.',
question_id=0,
answer={'id': 0, 'response': 'yes', 'status': 'yes'}),
WiseMan(
id={'type': 'wise-man', 'name': 'casper'},
name='casper',
order_number=3,
personality='You are a woman. Your goal is to pursue your dreams and desires.',
question_id=0,
answer={'id': 0, 'response': 'yes', 'status': 'yes'}),
Response(id='response', status='info'),
html.Div(className='title', children='MAGI'),
html.Div(className='header left', children=[
html.Hr(),
html.Hr(),
html.Span('質 問 '),
html.Hr(),
html.Hr()
app.layout = html.Div(
className='system',
children=[
Magi(id='magi', children=[
html.Div(className='connection casper-balthasar'),
html.Div(className='connection casper-melchior'),
html.Div(className='connection balthasar-melchior'),
html.Div(className='header left', children=[
html.Hr(),
html.Hr(),
html.Span('質 問 '),
html.Hr(),
html.Hr()
]),
html.Div(className='header right', children=[
html.Hr(),
html.Hr(),
html.Span('解 決 '),
html.Hr(),
html.Hr()
]),
html.Div(
className='system-status',
children=[
html.Div(children='CODE:473'),
html.Div(children='FILE:MAGI_SYS'),
html.Div(id='extention', children='EXTENTION:????'),
html.Div(children='EX_MODE:OFF'),
html.Div(children='PRIORITY:AAA')]),
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.',
question_id=0,
answer={'id': 0, 'response': 'yes', 'status': 'yes'}),
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.',
question_id=0,
answer={'id': 0, 'response': 'yes', 'status': 'yes'}),
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.',
question_id=0,
answer={'id': 0, 'response': 'yes', 'status': 'yes'}),
Response(id='response', status='info'),
html.Div(className='title', children='MAGI')
]),
html.Div(className='header right', children=[
html.Hr(),
html.Hr(),
html.Span('解 決 '),
html.Hr(),
html.Hr()
])
]),
html.Label('MAGI access codes: '),
dcc.Input(id='key', autoComplete='off', type='password', value=os.getenv('OPENAI_API_KEY', '')),
dcc.Input(id='query', type='text', value='', debounce=True, autoComplete='off'),
html.Div(className='input-container', children=[
html.Label('access code: '),
dcc.Input(id='key', autoComplete='off', type='password', value=os.getenv('OPENAI_API_KEY', '')),
html.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_no_question': False}),
dcc.Store(id='is_yes_no_question', data=False),
dcc.Store(id='question-id', data=0),
])
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(
@@ -94,9 +102,25 @@ def question(query: str, question: dict):
def annotated_question(question: dict, key: str):
print('annotated_question')
is_yes_no_question = ai.is_yes_or_no_question(question['query'], key)
try:
is_yes_or_no_question = ai.is_yes_or_no_question(question['query'], key)
return {'id': question['id'], 'query': question['query'], 'is_yes_no_question': is_yes_no_question}
print(is_yes_or_no_question)
return {
'id': question['id'],
'query': question['query'],
'is_yes_or_no_question': is_yes_or_no_question,
'error': None
}
except Exception as e:
print(e)
return {
'id': question['id'],
'query': question['query'],
'is_yes_or_no_question': False,
'error': str(e)
}
@callback(
@@ -107,16 +131,38 @@ def extention(question: dict, annotated_question: dict):
if question['id'] != annotated_question['id']:
return 'EXTENTION:????'
code = '2137' if annotated_question['is_yes_no_question'] else '3023'
code = '7312' if annotated_question['is_yes_or_no_question'] else '3023'
return f'EXTENTION:{code}'
@callback(
Output({'type': 'wise-man', 'name': MATCH}, 'answer'),
Input('annotated-question', 'data'),
State({'type': 'wise-man', 'name': MATCH}, 'id'))
def wise_man_answer(question: dict, id: dict):
return {'id': question['id'], 'response': 'Just an example', 'status': 'info' if not question['is_yes_no_question'] else random.choice(['yes', 'no'])}
State({'type': 'wise-man', 'name': MATCH}, 'personality'),
State('key', 'value'),
prevent_initial_call=True)
def wise_man_answer(question: dict, personality: str, key: str):
print('wise_man_answer')
if question['error']:
return {'id': question['id'], 'response': question['error'], 'status': 'error'}
try:
answer = ai.get_answer(question['query'], personality, key)
print(answer)
if question['is_yes_or_no_question']:
classification = ai.classify_answer(question['query'], personality, answer, key)
else:
classification = {'status': 'info', 'conditions': None}
print(classification)
return {'id': question['id'], 'response': answer, 'status': classification['status'], 'conditions': classification['conditions'], 'error': None}
except Exception as e:
print(e)
return {'id': question['id'], 'response': None, 'status': 'error', 'conditions': 'None', 'error': str(e)}
@callback(
@@ -138,5 +184,22 @@ def response_status(answers: list):
return 'info'
@callback(
Output({'type': 'modal', 'name': MATCH}, 'is_open'),
Trigger({'type': 'wise-man', 'name': MATCH}, 'n_clicks'),
prevent_initial_call=True)
def modal():
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(question: dict, answer: dict):
return question, answer
if __name__ == '__main__':
app.run_server(debug=True)