From ab2199114413a4cea11857cc7c054a019498250a Mon Sep 17 00:00:00 2001 From: Greg Hogue Date: Mon, 15 Sep 2025 14:32:58 -0400 Subject: [PATCH 1/7] open links in new tab; fixes #81 --- public/elements/SearchResults.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/public/elements/SearchResults.jsx b/public/elements/SearchResults.jsx index 1106c59..13de9ab 100644 --- a/public/elements/SearchResults.jsx +++ b/public/elements/SearchResults.jsx @@ -16,6 +16,7 @@ const SearchResults = () => {
From 448a3f903e1622bd42fc92ea036f85aee5452ea6 Mon Sep 17 00:00:00 2001 From: Greg Hogue Date: Mon, 15 Sep 2025 14:43:52 -0400 Subject: [PATCH 2/7] links to reactome.org from /chat ; closes #83 --- bin/chat-fastapi.py | 4 +++- config_default.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/chat-fastapi.py b/bin/chat-fastapi.py index 29a74e0..5d34b53 100644 --- a/bin/chat-fastapi.py +++ b/bin/chat-fastapi.py @@ -288,7 +288,9 @@ async def landing_page():

Meet the React-to-Me AI Chatbot!

Your new guide to Reactome. Whether you're looking for specific genes and pathways or just browsing, our AI Chatbot is here to assist you!

diff --git a/config_default.yml b/config_default.yml index 6831216..a5e6ca0 100644 --- a/config_default.yml +++ b/config_default.yml @@ -18,7 +18,7 @@ messages: welcome: message: |- - Welcome to {chat_profile}, your interactive chatbot for exploring Reactome! + Welcome to {chat_profile}, your interactive chatbot for exploring **[Reactome](https://reactome.org/)**! Ask me about biological pathways and processes. trigger: event: on_chat_start From e08b1ef62ab9ccae9c385dcf86bbb4923162d7d0 Mon Sep 17 00:00:00 2001 From: Greg Hogue Date: Mon, 15 Sep 2025 14:51:45 -0400 Subject: [PATCH 3/7] remove survey, direct to help email; closes #84 --- bin/chat-fastapi.py | 2 +- config_default.yml | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/bin/chat-fastapi.py b/bin/chat-fastapi.py index 5d34b53..82dda31 100644 --- a/bin/chat-fastapi.py +++ b/bin/chat-fastapi.py @@ -298,7 +298,7 @@ async def landing_page():

Choose Guest Access to try the chatbot out. Log In will give an increased query allowance and securely stores your chat history so you can save and continue conversations.

diff --git a/config_default.yml b/config_default.yml index a5e6ca0..e53055a 100644 --- a/config_default.yml +++ b/config_default.yml @@ -23,12 +23,6 @@ messages: trigger: event: on_chat_start - survey_message: - message: |- - We hope you're enjoying your experience with React-to-me! We'd love to hear your feedback to make it even better. Please take a few minutes to fill out our [survey](https://forms.gle/Rvzb8EA73yZs7wd38). - trigger: - after_messages: 3 - demo-message: message: |- Hello! From 391608a639e6c656c679981c83773117bc295ce8 Mon Sep 17 00:00:00 2001 From: Greg Hogue Date: Mon, 15 Sep 2025 14:55:17 -0400 Subject: [PATCH 4/7] avert KeyError for unused embeddings bundles; fixes #86 --- .dockerignore | 1 + src/util/embedding_environment.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index 57688a2..5b3c643 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ +data/ embeddings/ embeddings_bak/ csv_files/ diff --git a/src/util/embedding_environment.py b/src/util/embedding_environment.py index 7d34048..ab4a43f 100644 --- a/src/util/embedding_environment.py +++ b/src/util/embedding_environment.py @@ -27,8 +27,11 @@ def get_dict(cls) -> dict[str, Path]: return cls._get().embeddings @classmethod - def get_dir(cls, key: str) -> Path: - return EM_ARCHIVE / cls._get().embeddings[key] + def get_dir(cls, key: str) -> Path | None: + if key in cls._get().embeddings: + return EM_ARCHIVE / cls._get().embeddings[key] + else: + return None @classmethod def get_model(cls, key: str) -> str: From 8dd0a690ee4842932966f60191aa6e69e09ee1aa Mon Sep 17 00:00:00 2001 From: Greg Hogue Date: Mon, 15 Sep 2025 14:56:29 -0400 Subject: [PATCH 5/7] add disclaimers; closes #80 --- chainlit.md | 7 +++++++ config_default.yml | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/chainlit.md b/chainlit.md index 73653c6..908001a 100644 --- a/chainlit.md +++ b/chainlit.md @@ -35,3 +35,10 @@ Explore pathways such as: Happy exploring with React-to-me! +## _Disclaimer_ + +_This chatbot uses large language model (LLM) technology to assist with questions about the Reactome Knowledgebase. Responses are generated automatically and may contain inaccuracies, outdated information or speculative language._ + +_The information you provide may be retained in accordance with Reactome’s AI provider’s retention policy, which is located [here](https://openai.com/enterprise-privacy/). Do not share sensitive, personal or confidential information._ + +_The chatbot does not substitute for expert curation or peer-reviewed sources and is not a suitable resource for clinical decisions. Users are responsible for validating any output before using it for research, publication, or medical decisions. Any use of this chatbot is subject to Reactome’s [disclaimer](https://reactome.org/about/disclaimer)._ diff --git a/config_default.yml b/config_default.yml index e53055a..e0727a2 100644 --- a/config_default.yml +++ b/config_default.yml @@ -16,6 +16,23 @@ usage_limits: messages: + disclaimer-guests: + message: |- + _**Disclaimer:** Our chatbot uses AI to assist you. Responses are generated automatically and may not always be accurate. Do not share sensitive, personal or confidential information. For more information, please click on the “Readme” icon at the top-right of this window._ + recipients: + - guests + trigger: + event: on_chat_start + + disclaimer-logged_in: + message: |- + _**Disclaimer:** Our chatbot uses AI to assist you. Responses are generated automatically and may not always be accurate. Do not share sensitive, personal or confidential information. For more information, please click on the “Readme” icon at the top-right of this window._ + recipients: + - logged_in + trigger: + event: on_chat_start + freq_max: 1w + welcome: message: |- Welcome to {chat_profile}, your interactive chatbot for exploring **[Reactome](https://reactome.org/)**! From 55f939f0f8299230e16380398868d4119f8c00df Mon Sep 17 00:00:00 2001 From: Greg Hogue Date: Mon, 15 Sep 2025 15:33:50 -0400 Subject: [PATCH 6/7] replace favicon with SVG; fixes #82 --- public/favicon.ico | Bin 583 -> 0 bytes public/favicon.svg | 1 + 2 files changed, 1 insertion(+) delete mode 100644 public/favicon.ico create mode 100644 public/favicon.svg diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index ee97eb74c68beb8d7da3bfa008da105cae36fb7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 583 zcmV-N0=WH&P)srp=RHV3-Sw!uUa{_am8A1gSYyI74}_wk zI|4-z0Lt~&GVrvNU)jHJV2oBow1QF*qzFPc2r1WFuYsSy20-bcktrQC7Gr}Ww_N}# z!zD!oxUS>wf*+_>OS222ScH-FljUV19860*cMOb zr!ZukA05G2m`JfOVUsouM8Gs;tol%l58{p*RDrdVD}Os}nTQCc2y?c@(quX|P{l{t z1+wM!TrDs}Fx}g7@WTxvlbg&KVuqSY4VM?t~hUEv>HX zMv4#gfj0^Hjv)@QlwWa2_;Reactome_Isotype_Positive \ No newline at end of file From 8a47532db54df008417dd6f13dbd91ffb767d987 Mon Sep 17 00:00:00 2001 From: Greg Hogue Date: Mon, 15 Sep 2025 17:12:18 -0400 Subject: [PATCH 7/7] disclaimer as footer --- .chainlit/config.toml | 2 +- config_default.yml | 17 ------------ public/custom.js | 64 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 public/custom.js diff --git a/.chainlit/config.toml b/.chainlit/config.toml index bb57df8..be10a3b 100644 --- a/.chainlit/config.toml +++ b/.chainlit/config.toml @@ -74,7 +74,7 @@ github = "https://github.com/reactome/reactome_chatbot/issues" # Specify a Javascript file that can be used to customize the user interface. # The Javascript file can be served from the public directory. -# custom_js = "/public/test.js" +custom_js = "/public/custom.js" # Specify a custom meta image url. # custom_meta_image_url = "https://chainlit-cloud.s3.eu-west-3.amazonaws.com/logo/chainlit_banner.png" diff --git a/config_default.yml b/config_default.yml index e0727a2..e53055a 100644 --- a/config_default.yml +++ b/config_default.yml @@ -16,23 +16,6 @@ usage_limits: messages: - disclaimer-guests: - message: |- - _**Disclaimer:** Our chatbot uses AI to assist you. Responses are generated automatically and may not always be accurate. Do not share sensitive, personal or confidential information. For more information, please click on the “Readme” icon at the top-right of this window._ - recipients: - - guests - trigger: - event: on_chat_start - - disclaimer-logged_in: - message: |- - _**Disclaimer:** Our chatbot uses AI to assist you. Responses are generated automatically and may not always be accurate. Do not share sensitive, personal or confidential information. For more information, please click on the “Readme” icon at the top-right of this window._ - recipients: - - logged_in - trigger: - event: on_chat_start - freq_max: 1w - welcome: message: |- Welcome to {chat_profile}, your interactive chatbot for exploring **[Reactome](https://reactome.org/)**! diff --git a/public/custom.js b/public/custom.js new file mode 100644 index 0000000..67abcde --- /dev/null +++ b/public/custom.js @@ -0,0 +1,64 @@ +/* + * Replace the contents of the Chainlit watermark/footer + */ +(function () { + const CUSTOM_FOOTER_HTML = ` +
+ + + Disclaimer: + Our chatbot uses AI to assist you. + Responses are generated automatically and may not always be accurate. + Do not share sensitive, personal or confidential information. + For more information, please click on the “Readme” icon at the top-right of this window. + + +
+ `.trim(); + + const WATERMARK_SELECTOR = 'a.watermark'; + const APPLIED_ATTR = 'data-custom-watermark'; + + function replaceFooterContents(root = document) { + const nodes = root instanceof Element + ? root.querySelectorAll(WATERMARK_SELECTOR) + : document.querySelectorAll(WATERMARK_SELECTOR); + + nodes.forEach((el) => { + if (!(el instanceof HTMLElement)) return; + if (el.getAttribute(APPLIED_ATTR) === '1') return; + + el.innerHTML = CUSTOM_FOOTER_HTML; + + // disable the link behaviour + el.removeAttribute('href'); + el.removeAttribute('target'); + el.style.pointerEvents = 'none'; + + el.setAttribute(APPLIED_ATTR, '1'); + }); + } + + // Initial run (in case the element is already present). + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => replaceFooterContents(document)); + } else { + replaceFooterContents(document); + } + + // Re-apply on future UI updates (SPA re-renders). + const mo = new MutationObserver((mutations) => { + for (const m of mutations) { + for (const node of m.addedNodes) { + if (node instanceof Element) { + // If the watermark itself is added or its parent subtree changes, update. + if (node.matches?.(WATERMARK_SELECTOR) || node.querySelector?.(WATERMARK_SELECTOR)) { + replaceFooterContents(node); + } + } + } + } + }); + + mo.observe(document.documentElement, { childList: true, subtree: true }); +})();