-
Notifications
You must be signed in to change notification settings - Fork 77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add feedback component #793
Conversation
📝 Updated mephisto-worker-experience with usage of Feedback
📝 Added documentation for width prop
🏷️ Added return types to review_tips_for_task.py ✨ Added feedback tag to tips example ✨ UUpdated ClientIOHandler to handle packet details for feedback
✏️ Updated some of the print statements to be more clear/have more spacing
✨ Added a deffault length limit to feedback textarea
🎨 Changed width property to represent the width of the textarea.
📝 Uppdated readme to reflect these new props.
♻️ Refactored some of the user script code by putting acceptable responses in a set
✅ Modified spacing in Tips/index.js to pass test
🚛 Moved submit button into its own file 🎨 Added a red border for textareas when there is an error 🔥 Removed observer code for error popup as textarea resize direction was changed to exclusively vertical 📝 Updated docstrings for functions
🔥 Removed createTip and createFeedback from exports, might revisit later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some explanatory comments on what I have done
<Feedback | ||
maxTextLength={30} | ||
questions={[ | ||
"What is your favorite part of this task?", | ||
"Were you satisfied with this task?", | ||
]} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new Feedback component, you can optionally pass in questions or have no questions and just have general feedback.
mephisto/data_model/agent.py
Outdated
feedback_to_add = { | ||
"id": str(uuid4()), | ||
"question": question_obj["question"], | ||
"text": new_feedback_text, | ||
"reviewed": False, | ||
"toxicity": str(new_feedback_toxicity), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New feedback object that gets added
""" | ||
Script that allows for feedback to be reviewed. | ||
Feedback are collected by retrieving all units and then getting the agent of each unit. | ||
The agent state has the feedback data. | ||
|
||
When running the script you first have the option of | ||
filtering out potential toxic feedback. | ||
After that you have the ability to view reviewed or unreviewed feedback. | ||
|
||
If you select reviewed feedback, then the script will print out all of the reviewed feedback. | ||
If you select unreviewed feedback, then the script will print out each | ||
unreviewed feedback and give you the option to mark the feedback as reviewed. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this script gets reworked with rich in #816
### `maxHeaderLength` | ||
The max character length of a tip header before an error message is shown. The default value for this prop is 72. | ||
### `maxTextLength` | ||
The max character length of tip text before an error message is shown. The default value for this prop is 500. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some new props for tips in this pr.
If length exceeds the max lengths an error message shows up that prevents the submission of the tips
## Documentation | ||
### `headless` | ||
The `headless` prop accepts a boolean where a a true value removes most of the styling and a false value keeps the original styling. The default value of this prop is false. | ||
### `questions` | ||
The `questions` prop accepts a list of strings where each string is displayed with its own textarea input. When reviewing the feedback in the task, there is an option to filter by question. By default there are no questions defined and feedback is collected under the 'General Feedback' label. | ||
### `handleSubmit` | ||
The `handleSubmit` prop accepts a function that runs when the "Submit Feedback" button is pressed instead of the default behavior of submitting feedback. The text property can be passed down through to the function. | ||
### `textAreaWidth` | ||
The `textAreaWidth` prop accepts a string that sets the width of the text-area. ex: textAreaWidth="30rem" sets the text-area width. The default value for this prop is 100%. | ||
### `maxTextLength` | ||
The max character length of feedback text before an error message is shown. The default value for this prop is 700. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feedback properties
<FeedbackTextArea | ||
id={`question-${index}`} | ||
ref={ref} | ||
index={index} | ||
width={textAreaWidth} | ||
questionsFeedbackText={questionsFeedbackText} | ||
feedbackText={questionsFeedbackText[index]} | ||
setFeedbackText={(textValue) => { | ||
const tempQuestionsFeedback = [...questionsFeedbackText]; | ||
tempQuestionsFeedback[index] = textValue; | ||
setQuestionsFeedbackText(tempQuestionsFeedback); | ||
}} | ||
stylePrefix={stylePrefix} | ||
state={state} | ||
dispatch={dispatch} | ||
maxFeedbackLength={maxFeedbackLength} | ||
containsQuestions | ||
placeholder={placeholder} | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are a lot of props for some of these components, but using context or a state management lib are probably overkill for this package.
useEffect(() => { | ||
if (questions) setQuestionsFeedbackText(questions.map(() => "")); | ||
}, [questions]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initialize with correct length
const [state, dispatch] = useReducer(feedbackReducer, { | ||
status: 0, | ||
text: "", | ||
errorIndexes: null, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handles different states that the feedback component can be in (error, loading, normal, etc...)
import { createFeedback, createTip } from "./Functions"; | ||
export { Tips, createFeedback, createTip }; | ||
import Feedback from "./Feedback/index"; | ||
export { Tips, Feedback }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The createFeedback & createTip methods are way more involved/complex than they previously were, so it makes not sense for them to be exported for the user to run.
Tests are failing because detoxify is not installed globally |
🎨 Improved layout of feedback and tips in task
Updated video: updated-feedback-component.mov |
Can you merge #779 into this and then set it as a base branch for this PR? Should let you then add |
Wouldn't setting #779 as the base branch for #793 just make this code go into #779 once #793 is merged? Do we want that? I also have to add it to requirements.txt as well right? |
…phisto into add-feedback-component
|
And ideally we'll be merging #779 in first! Setting the base branch in this case just makes review easier by isolating the changeset. |
Okay, so I guess I just have to remember to switch the base branch back to main before merging this pr in. |
Codecov Report
@@ Coverage Diff @@
## main #793 +/- ##
==========================================
- Coverage 64.62% 64.50% -0.12%
==========================================
Files 107 107
Lines 9264 9281 +17
==========================================
Hits 5987 5987
- Misses 3277 3294 +17
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only small comments on the backend, the overall implementation looks great!
As an aside, I imagine it would be really cool to provide a navbar-style meta-component that can hold these types of add-ons behind button toggles in an attached overlay. (similar to how tips already works!)
I'll hold off on stamping to merge until tests are passing and the underlying PR is in.
mephisto/data_model/agent.py
Outdated
@@ -30,6 +30,7 @@ | |||
) | |||
|
|||
from typing import Optional, Mapping, Dict, Any, cast, TYPE_CHECKING | |||
from detoxify import Detoxify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like Detoxify
is a pretty heavy import for the Agent
class, as well as one that we may allow people to skip. For this we can do an import flag:
try:
from detoxify import Detoxify
DETOXIFY_INSTALLED = True
except ImportError:
DETOXIFY_INSTALLED = False
Then later in the elif "feedback" in data:
block you can use Detoxify
if DETOXIFY_INSTALLED
else use some kind of null or not evaluated value for new_feedback_toxicity
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That certainly is a way of doing it. Something that I saw in the codebase was putting imports inside an if statement
elif "feedback" in data:
from detoxify import Detoxify
...
Would this be a fix to this problem as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was considering this approach as well, though it makes the choice less deliberate. I tend to only use it when there are potential dependency loops. It also means if someone wanted to drop detoxify
they'd have to patch here, while someone wanting a lightweight system could benefit from just not installing detoxify.
Of course, there may be the case of someone who already has detoxify
installed but who doesn't want to use it here, but I'm not terribly concerned there.
print("\nTask Names:") | ||
for task_name in task_names: | ||
print(task_name) | ||
|
||
# Getting the task name | ||
task_name = input( | ||
"\nEnter the name of the task that you want to review the feedback of: \n" | ||
) | ||
print("") | ||
while task_name not in task_names: | ||
print("That task name is not valid\n") | ||
task_name = input( | ||
"Enter the name of the task that you want to review the feedback of: \n" | ||
) | ||
print("") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an aside, this style of task name selection is a pretty common utility, and would likely be a good candidate to abstract into the mephisto.tools.scripts
collection. Can do after #816
@@ -51,6 +51,7 @@ hydra-core = "^1.1.0" | |||
tqdm = "^4.50.2" | |||
websockets = "^10.1" | |||
pyyaml = "^5.4.0" | |||
detoxify = "^0.5.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for organization, can you add this under a # [tool.poetry.group.worker_addons.dependencies]
heading? I'll be toggling these in poetry 1.2.
ℹ️ Feedback submitted without the detoxify dependency has None in its toxicity field. When reviewing this feedback submission filtering by toxicity will have no effect on if it shows or not. 💡 Updated the main comment in review_tips_for_task.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is ready to go. Thanks for the patience here in getting this right @Etesam913!
@pringshia I should probably make the non-headless version of this component be in a shadow-dom right? |
Yep, thanks! |
Summary
Adds feedback component to
mephisto-worker-addons
.Properties for this component are defined in the
mephisto-worker-addons
readme.There is a questions prop that allows for questions to be associated with a feedback textarea when reviewing.
Uses the handleSubmitMetadata() method from
mephisto-task
in the default handleSubmit() of the Feedback component to make submitting feedback very easy. Very similar to how it is done in the Tips componentAdds feedback component to static_react_task_with_tips webapp
Created a reducer to add error checking for both the feedback & tips components.
Added some small changes like new properties for the Tips component.
Test Plan
New video:
#793 (comment)
Old Video:
feedback-demo-with-questions.mov
In the video it should be clear that I write feedback for the two questions. The feedback for the first question is clearly not toxic, while the feedback for the second question clearly is.
Then I ran the review_feedback_for_task.py script where I was first able to filter by the question asked. Then I was able to filter by toxicity & then filter by unreviewed/reviewed feedback.
I ran the script three times.
The first time I reviewed the feedback for the first question. The toxicity of the feedback was < 0.5, so filtering by toxicity would do nothing.
The second time I reviewed the feedback for the other question. I chose to filter by toxicity and the feedback message did not show up as it's toxicity > 0.5.
The third time I reviewed the same question as the second time, but this time I chose not to filter by toxicity. As expected, it showed the message.
TODO: