Skip to content

Anytime Questions saveToChatbot#481

Open
AdamFipke wants to merge 5 commits intomainfrom
adam/async-pr-refactor/save-to-chatbot
Open

Anytime Questions saveToChatbot#481
AdamFipke wants to merge 5 commits intomainfrom
adam/async-pr-refactor/save-to-chatbot

Conversation

@AdamFipke
Copy link
Collaborator

@AdamFipke AdamFipke commented Feb 23, 2026

Description

Cannibalized the saveToChatbot feature from #259 and refactored pieces of it due to new changes (and upcoming ones in #416 , i've tried to minimize the changes here to make the merge as small of a headache as possible).

Sister PR on Chatbot repo: https://github.com/ubco-db/chatbot/pull/62

screenshots below

(the checkbox is default enabled)
image

Mobile view
image
Mobile view on that weird edge case where the staff member created their own question (I re-did this)
image

Here this anytime question got split into 4 chunks. Upon updating the response, these chunks are deleted and replaced with new ones. Note that since I posted this screenshot, I've modified the names of the document to say "Previously Asked Anytime Question: {40 characters from the abstract/question}"
image

Note that this doesn't cover when professors delete an Anytime question. Ideally, I think you would add some sort of check asking "this anytime question was inserted into the chatbot's knowledge base, would you like to delete those chunks as well?" but tbh it's probably not worth the effort.

This also doesn't cover if the professor modifies the chunks (right now, it always deletes all chunks associated with the anytime question). I wouldn't even know how to handle this properly from a user perspective, other than maybe to show some kind of warning if they click saveToChatbot and the chunks had been previously modified. This would be a good thing to do but would add a lot of code and should wait until #416 is done anyway (since that one adds lastModifiedAt and firstInsertedAt, which would allow you to tell if any of these chunks were modified).

Closes #250

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • This requires a run of yarn install
  • This change requires an addition/change to the production .env variables. These changes are below:
  • This change requires developers to add new .env variables. The file and variables needed are below:
  • This change requires a database query to update old data on production. This query is below:

How Has This Been Tested?

Did a tiny bit of manual testing:

  • Post response with a large question that doesn't have any preexisting chunks
  • Post response with a large question that does have preexisting chunks

Checklist:

  • I have performed a code review of my own code (under the "Files Changed" tab on github) to ensure nothing is committed that shouldn't be (e.g. leftover console.logs, leftover unused logic, or anything else that was accidentally committed)
  • I have commented my code where needed
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have checked that new and existing tests pass locally with my changes
  • Any work that this PR is dependent on has been merged into the main branch
  • Any UI changes have been checked to work on desktop, tablet, and mobile

…uestion Images PR. Had to refactor some things. Avoided moving over some random changes to make merge with vector store refactor less of a headache. Also added a couple tests, and changed how the buttons look in PostResponseModal (simplified a lot)
Comment on lines +777 to +783
// don't include studentDeleted or TADeleted questions
status: Not(
In([
asyncQuestionStatus.StudentDeleted,
asyncQuestionStatus.TADeleted,
]),
),
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh yeah this was a thing, Apparently all this time TADeleted async questions were being fetched I guess

@AdamFipke AdamFipke requested a review from bhunt02 February 23, 2026 07:05
Copy link
Collaborator

@bhunt02 bhunt02 left a comment

Choose a reason for hiding this comment

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

initial pass: everything looks pretty good. noticed some things so i'll let you review my comments, but i will make some time to manually test if necessary and then approve after pending issues!

loc?: Loc
name: string
type?: string
type?: string // "inserted_question", "inserted_async_question", etc. Will get put into a proper enum in the Vector Store Refactor but it will need to add inserted_async_question to the enum
Copy link
Collaborator

Choose a reason for hiding this comment

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

thus far in that refactor i've been treating them largely the same, but i suppose this distinction is useful. i thought though that with the asyncQuestionId property that would suffice...

Copy link
Collaborator Author

@AdamFipke AdamFipke Feb 24, 2026

Choose a reason for hiding this comment

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

huh right I guess I hadn't really thought of that. Yeah, I think I'll change it back to just be "inserted_question". It could make a data export very slightly more messy, but it's probably not gonna be worth the extra work in your refactor

courseId,
userToken,
);
await this.chatbotApiService.addDocumentChunk(
Copy link
Collaborator

Choose a reason for hiding this comment

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

if this step fails, we should probably revert any changes... maybe keeping this logic on the chatbot side would be preferable rather than performing consecutive http requests?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah that's true, I guess this way was just the most minimal amount of changes required which will make it less of a pain for the vector store refactor me thinks.

Eventually this whole endpoint will be changed a lot once the async question images are redone (since it needs to request the chatbot to get image summaries before prompting the chatbot a second time for the AiAnswer), and that will probably need to wait until after the vector store refactor since I imagine there will be some rather unpleasant and non-trivial merge conflicts, but that's okay.

Also, I think the async question chunks are more disposable. So if it does delete all the chunks and then fails to re-add them, not much is lost.

But yeah I agree, this is certainly something that should be changed in the future

export const ERROR_MESSAGES = {
common: {
pageOutOfBounds: "Can't retrieve out of bounds page.",
noDiskSpace:
Copy link
Collaborator

Choose a reason for hiding this comment

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

hm, we might need to apply this across a few different routes in the future...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah for sure, I sprinkled it everywhere for the async question images, but it should probably also be added to like the chatbot document upload and stuff.

export function setupIntegrationTest(
module: Type<any>,
modifyModule?: ModuleModifier,
modifyModules?: ModuleModifier[],
Copy link
Collaborator

Choose a reason for hiding this comment

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

good change LOL it makes way more sense for it to be possibly multiple. maybe we can set up an overload that will check Array.isArray(modifyModules) for this behaviour so it doesn't always have to be passed as an array

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

true true, i shall do that real quick

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

er I guess I don't really need an overload, I just changed the param type to modifyModules?: ModuleModifier | ModuleModifier[], and then used isArray as you suggested

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.

Optionally auto-convert Anytime Question answers into document chunks

2 participants