Skip to content

Support "contextual links" in chatbot message #548

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

Open
TamiTakamiya opened this issue May 7, 2025 · 4 comments · May be fixed by #557
Open

Support "contextual links" in chatbot message #548

TamiTakamiya opened this issue May 7, 2025 · 4 comments · May be fixed by #557
Labels
PF6 Applies to only the PF6 version

Comments

@TamiTakamiya
Copy link

Currently, PF chatbot is capable of rendering Markdown outputs from Large Language Model (LLM) and includes static links. However, we would like to introduce a new feature called 'contextual links' for PF Chatbot, which will enable users to click on these links and be taken directly to a specific page within our product UI.

We implement a PoC by updating the HTML anchor ("a") tags dynamically to update its href and onclick elements after PF chatbot completes the rendering. It looks like

  useEffect(() => {
    document?.querySelectorAll("iframe").forEach((item) => {
      const as = item.contentWindow?.document?.body?.querySelectorAll("a");
      as?.forEach(function (element) {
        const link = element.href;
        console.error("PROPOSING LINK FOR " + link);
        // TODO: We can check the original href and see it no host/port is specified, then we can assume it's an internal navigation link.
        if (link.includes("awx")) {
          const pageId = link.substring(link.lastIndexOf("/") + 1);
          console.error("CHANGING LINK FOR " + pageId);
          element.href = "#";
          element.onclick = function (event) {
            console.error("HELLO CLICKED ON " + pageId);
            sendMessage(pageId);
            event.preventDefault();
            event.stopPropagation();
          };
        }
      });
    });
  });

We would like PF chatbot to do these manipulations during parsing a message instead of depending on the post-processing.

@rebeccaalpert
Copy link
Member

Hi @TamiTakamiya - We use react-markdown, which supports rehype and remark plugins. We have a prop called rehypePlugins that will take any custom rehype plugins for the Message component. (We use these plugins already for rendering images a certain way and handling external links, even though we have no way of knowing what the markdown will be.) You'd probably have to write and publish your own plugin, but you can then just pass it to Message. I haven't tried this guide, but Unified has one here: https://unifiedjs.com/learn/guide/create-a-rehype-plugin/. We're already using https://www.npmjs.com/package/rehype-external-links (if you want an existing example) for changing the behavior and appearance of external links in Messages. I imagine you could modify rehype-external-links to look for specific links and change them.

@romartin
Copy link

romartin commented May 7, 2025

I am not really an expert on these plugins, although looks something interesting to look at yes. Anyway, at the end, I would say most important is having the ability to provider our own clickHandlers for some of the links we detect are not pointing to external pages or domains. This way, the handler is agnostic to the concrete environment or framework which it is embeeded into, and so we can implement our own click handler on client side, that performs navigation into AAP pages ,for example.

Thanks!

@rebeccaalpert rebeccaalpert added the PF6 Applies to only the PF6 version label May 14, 2025
@rebeccaalpert
Copy link
Member

rebeccaalpert commented May 15, 2025

I had a look and we already allow onClick events via the linkProps prop on the Message component. Example: linkProps={{onClick: (event) => console.log(event}}. This would apply to every link in the Message, but you should be able to grab the event.target and add your own custom onClick logic based on the innerText or innerHTML of the event.target. For the href, you'd have to write your own custom text logic via a rehype plugin like I outlined above. We can't add specific text matching for products, but the plugin should allow you to change this value based on a specific text string.

An example would be something like (I tested this locally within the extension and its examples - you would update from "react" to your text matcher):

import { visit } from 'unist-util-visit';

export const rehypeLinkHrefUpdater = (options) => (tree) => {
  visit(tree, 'element', (node) => {
    if (node.tagName === 'a' && node.properties) {
      if (node.properties.href.includes('react')) {
        node.properties.href = '#';
      }
    }
  });
};

And then you would pass [rehypeLinkHrefUpdater] to the additionalRehypePlugins prop on Message.

If you have any questions, let me know!

@rebeccaalpert rebeccaalpert linked a pull request May 15, 2025 that will close this issue
@justjais
Copy link

@rebeccaalpert Thanks so much for your suggestion, and I've verified the suggestion and it does seem to work as expected, I've updated the Aap_revised.tsx code as suggested, when you're back can you please check the POC code if that as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PF6 Applies to only the PF6 version
Projects
Status: Needs triage
Development

Successfully merging a pull request may close this issue.

4 participants