Skip to content
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

feat: Call LearningAssistantSummary endpoint #68

Merged
merged 9 commits into from
Dec 5, 2024
Merged

Conversation

ilee2u
Copy link
Member

@ilee2u ilee2u commented Nov 26, 2024

Copy link
Member

@varshamenon4 varshamenon4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far! A couple of questions!

src/data/slice.js Outdated Show resolved Hide resolved
@@ -98,7 +99,10 @@ const Sidebar = ({
</div>
)
}
{getMessageForm()}
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this only happening in the case where the user is an audit learner? In other words, where are we handling the logic to check if the learner is audit or verified (since the experience will be different).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up from a standup discussion we had, I removed the gating here as that functionality will be implemented in another ticket.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds great!

@ilee2u
Copy link
Member Author

ilee2u commented Dec 3, 2024

Note for self, this should be the shape of the data returned by the GET endpoint be worked on in edx/learning-assistant#140.

  • message_history will return an empty list if no access
  • audit_trial will return an empty dict if one doesn't exist
{
    "enabled": true,
    "message_history": [
        {
            "role": "user",
            "content": "test message from user",
            "timestamp": "2024-12-02T15:04:17.495928Z"
        },
        {
            "role": "assistant",
            "content": "test message from assistant",
            "timestamp": "2024-12-02T15:04:40.084584Z"
        }
    ],
    "trial": {
        "start_date": "2024-12-02T14:59:16.148236Z",
        "expiration_date": "2024-12-16T14:59:16.148236Z"
    }
}

@ilee2u ilee2u marked this pull request as ready for review December 3, 2024 20:23
@ilee2u ilee2u changed the title feat: Call LearningAssistantAuditTrial endpoint feat: Call LearningAssistantSummary endpoint Dec 3, 2024
src/data/api.js Outdated
async function fetchLearningAssistantMessageHistory(courseId) {
const url = new URL(`${getConfig().CHAT_RESPONSE_URL}/${courseId}/history`);
async function fetchLearningAssistantSummary(courseId) {
const url = new URL(`${getConfig().CHAT_RESPONSE_URL}/${courseId}/summary`);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: This Ticket/PR has been modified such that we're now calling the "summary" endpoint that Michael is working on in his PR: edx/learning-assistant#140.

This endpoint gets all the data for enabled, message_history, and audit_trial all in one GET request.

@@ -124,13 +101,46 @@ export function updateSidebarIsOpen(isOpen) {
};
}

export function getIsEnabled(courseId) {
export function getLearningAssistantSummary(courseId) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced the getLearningAssistantMessageHistory, getIsEnabled , and getAuditTrial thunks with a singular getLearningAssistantSummary thunk.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Could you rename this to getLearningAssistantChatSummary? Marcos had some concerns about confusion between that summary and the unit summary, which we may integrate into Learning Assistant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if I need to revert this, but I removed the message-history hook because I was able to call the summary hook from Xpert.jsx

Copy link
Member

@varshamenon4 varshamenon4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a couple of nits/comments.


const fakeGet = jest.fn(async () => ({
const mockGet = jest.fn(async () => ({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice renaming!

const messageList = rawMessageList
.map(({ timestamp, ...msg }) => ({
...msg,
// NOTE to self: can't store Date() objects in store: https://github.com/reduxjs/redux-toolkit/issues/456
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: would you just store as a string then and parse when needed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, that's what you're doing! My bad. So you can probably remove this comment?

}, [dispatch, courseId]);

// NOTE: This value can be used later on if/when we pass the enrollment mode to this componentn
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
// NOTE: This value can be used later on if/when we pass the enrollment mode to this componentn
// NOTE: This value can be used later on if/when we pass the enrollment mode to this component

Copy link
Member

@MichaelRoytman MichaelRoytman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't merge this pull request until the corresponding backend changes are released, because your changes will go to stage automatically and cause errors. And there is the risk someone will deploy them to production.

@@ -11,6 +11,10 @@ export const initialState = {
disclosureAcknowledged: false,
sidebarIsOpen: false,
isEnabled: false,
auditTrial: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the initial state be {}? The default would be no trial, which would be represented by the empty object.

@@ -124,13 +101,46 @@ export function updateSidebarIsOpen(isOpen) {
};
}

export function getIsEnabled(courseId) {
export function getLearningAssistantSummary(courseId) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Could you rename this to getLearningAssistantChatSummary? Marcos had some concerns about confusion between that summary and the unit summary, which we may integrate into Learning Assistant.

const auditTrial = data.audit_trial;

// If returned audit trial data is not empty
if (Object.keys(auditTrial).length !== 0) { // eslint-disable-line no-undef
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the issue with no-undef here? I don't see what would be undefined here. Do we need this eslint-disable declaration?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If auditTrial data is empty, is there a reason we shouldn't call setAuditTrial. If it's empty, it would just set auditTrial to the empty object. Is there something wrong with that behavior? I think that's a reasonable behavior, as the empty object signifies the absence of a trial.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that's an artifact from when I was using lodash, I'll get rid of this

} catch (error) {
// NOTE: When used to not show if fetching the messages failed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what this comment means? I'm not following.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to use "we" instead of "when", but also I don't think this comment is necessary so I'm removing it.

import ToggleXpert from '../components/ToggleXpertButton';
import Sidebar from '../components/Sidebar';
import { ExperimentsProvider } from '../experiments';
import { useMessageHistory } from '../hooks';
// import { getLearningAssistantData } from '../hooks';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the commented out lines.

}, [dispatch, courseId]);

// NOTE: This value can be used later on if/when we pass the enrollment mode to this component
const isAuditTrialNotExpired = () => { // eslint-disable-line no-unused-vars
const auditTrialExpired = (Date.now() - auditTrial.expirationDate) > 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auditTrial.expirationDate is a string. How is it represented in Redux? If it's just the string representation of the date returned by the backend, which it looks like it is, then it's going to cause a problem. Date.now() - '2024-12-02T14:59:16.148236Z', for example, is going to return NaN.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, that value is stored in Redux as a string, so I'll create a date object from the string here.

Copy link
Member

@MichaelRoytman MichaelRoytman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing my feedback.

I left one comment about the conditional used for determining whether a trial has expired, but since the function is not used yet, I'm not blocking merging the PR.

Also, please squash your commits before/when merging.

I'd like to wait for the backend changes to be deployed and tested before we merge this since deployment to stage will be automatic. Could we check in tomorrow about a good time to merge? Thanks.

const isAuditTrialNotExpired = () => { // eslint-disable-line no-unused-vars
const auditTrialExpirationDate = new Date(auditTrial.expirationDate);

if ((Date.now() - auditTrialExpirationDate) >= 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that if the current time is exactly the expiration date (i.e. Date.now() - auditTrialExpirationDate === 0), then the trial should be expired, so this should be >. What do you think?

@ilee2u ilee2u merged commit f1f690c into main Dec 5, 2024
4 checks passed
@ilee2u ilee2u deleted the ilee2u/audit-trial-get branch December 5, 2024 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants