Skip to content

Commit

Permalink
feat(ai-help): show canned answer without sources for off-topic quest…
Browse files Browse the repository at this point in the history
…ions (#10575)

* feat(ai-help): show error for off-topic questions

* refactor(ai-help): extract AIHelpAssistantResponseSources

* feat(ai-help): show canned answer without sources for off-topic question

* fix(ai-help): override content/sources only for off-topic messages

* chore(ai-help): remove unnecessary filter

* chore(ai-help): remove unnecessary wrapper

* refactor(ai-help): reuse ReactMarkdown for off-topic answer for simplicity
  • Loading branch information
caugner authored Mar 1, 2024
1 parent 78a9500 commit fcd236a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 44 deletions.
4 changes: 2 additions & 2 deletions client/src/plus/ai-help/constants.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const SORRY_BACKEND = "Sorry, I don't know how to help with that.";
export const SORRY_BACKEND_PREFIX = "I'm sorry, but I can't";
export const SORRY_FRONTEND =
"Sorry, I don’t know how to help with that.\n\nPlease keep in mind that I am only limited to answer based on the MDN documentation.";
"I'm sorry, but I can't answer questions outside web development.";

export const MESSAGE_SEARCHING = "Searching for MDN content…";
export const MESSAGE_SEARCHED = "Consulted MDN content:";
Expand Down
111 changes: 69 additions & 42 deletions client/src/plus/ai-help/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { useUIStatus } from "../../ui-context";
import { QueueEntry } from "../../types/playground";
import { AIHelpLanding } from "./landing";
import {
SORRY_BACKEND,
SORRY_BACKEND_PREFIX,
SORRY_FRONTEND,
MESSAGE_SEARCHING,
MESSAGE_ANSWERING,
Expand Down Expand Up @@ -288,6 +288,10 @@ function AIHelpAssistantResponse({

let sample = 0;

const isOffTopic =
message.role === MessageRole.Assistant &&
message.content?.startsWith(SORRY_BACKEND_PREFIX);

function messageForStatus(status: MessageStatus) {
switch (status) {
case MessageStatus.Errored:
Expand All @@ -314,33 +318,7 @@ function AIHelpAssistantResponse({

return (
<>
<div
className={[
"ai-help-message-progress",
message.status === MessageStatus.Pending && "active",
]
.filter(Boolean)
.join(" ")}
>
{message.status === MessageStatus.Pending
? MESSAGE_SEARCHING
: MESSAGE_SEARCHED}
</div>
{message.sources && message.sources.length > 0 && (
<ul className="ai-help-message-sources">
{message.sources.map(({ url, title }, index) => (
<li key={index}>
<InternalLink
to={url}
onClick={() => gleanClick(`${AI_HELP}: link source -> ${url}`)}
target="_blank"
>
{title}
</InternalLink>
</li>
))}
</ul>
)}
{!isOffTopic && <AIHelpAssistantResponseSources message={message} />}
{(message.content ||
message.status === MessageStatus.InProgress ||
message.status === MessageStatus.Errored) && (
Expand Down Expand Up @@ -509,34 +487,83 @@ function AIHelpAssistantResponse({
},
}}
>
{message.content?.replace(SORRY_BACKEND, SORRY_FRONTEND)}
{isOffTopic ? SORRY_FRONTEND : message.content}
</ReactMarkdown>
{message.status === "complete" &&
!message.content?.includes(SORRY_BACKEND) && (
<>
<section className="ai-help-feedback">
{(message.status === "complete" || isOffTopic) && (
<>
<section className="ai-help-feedback">
{!isOffTopic && (
<GleanThumbs
feature="ai-help-answer"
featureKey={message.messageId}
question={"Was this answer useful?"}
upLabel={"Yes, this answer was useful."}
downLabel={"No, this answer was not useful."}
/>
<ReportIssueOnGitHubLink
messages={messages}
currentMessage={message}
>
Report an issue with this answer on GitHub
</ReportIssueOnGitHubLink>
</section>
</>
)}
)}
<ReportIssueOnGitHubLink
messages={messages}
currentMessage={{
...message,
...(isOffTopic
? {
content: SORRY_FRONTEND,
sources: [],
}
: {}),
}}
>
Report an issue with this answer on GitHub
</ReportIssueOnGitHubLink>
</section>
</>
)}
</div>
)}
</>
);
}

function AIHelpAssistantResponseSources({
message,
}: {
message: Pick<Message, "status" | "sources">;
}) {
const gleanClick = useGleanClick();

return (
<>
<div
className={[
"ai-help-message-progress",
message.status !== MessageStatus.Pending && "complete",
]
.filter(Boolean)
.join(" ")}
>
{message.status === MessageStatus.Pending
? MESSAGE_SEARCHING
: MESSAGE_SEARCHED}
</div>
{message.sources && message.sources.length > 0 && (
<ul className="ai-help-message-sources">
{message.sources.map(({ url, title }, index) => (
<li key={index}>
<InternalLink
to={url}
onClick={() => gleanClick(`${AI_HELP}: link source -> ${url}`)}
target="_blank"
>
{title}
</InternalLink>
</li>
))}
</ul>
)}
</>
);
}

export function AIHelpInner() {
const formRef = useRef<HTMLFormElement>(null);
const inputRef = useRef<HTMLTextAreaElement>(null);
Expand Down

0 comments on commit fcd236a

Please sign in to comment.