Skip to content

Commit

Permalink
AAP-37349: Ansible Chatbot: Collect referenced documents information …
Browse files Browse the repository at this point in the history
…as well in issues feedback being created from the UI (#1459)

Signed-off-by: romartin <[email protected]>
  • Loading branch information
romartin authored Dec 12, 2024
1 parent ec7e743 commit ef929ba
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 25 deletions.
7 changes: 3 additions & 4 deletions ansible_ai_connect_chatbot/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 59 additions & 9 deletions ansible_ai_connect_chatbot/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,16 @@ describe("App tests", () => {
return error;
};

const mockAxios = (status: number, reject = false, timeout = false) => {
const referencedDocumentExample = [
"https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/html-single/getting_started_with_playbooks/index#ref-create-variables",
];

const mockAxios = (
status: number,
reject = false,
timeout = false,
refDocs: string[] = referencedDocumentExample,
) => {
const spy = vi.spyOn(axios, "post");
if (reject) {
if (timeout) {
Expand All @@ -77,14 +86,10 @@ describe("App tests", () => {
spy.mockResolvedValue({
data: {
conversation_id: "123e4567-e89b-12d3-a456-426614174000",
referenced_documents: [
{
docs_url:
"https://docs.redhat.com/en/documentation/red_hat_ansible_automation_platform/2.5/html-single/" +
"getting_started_with_playbooks/index#ref-create-variables",
title: "Create variables",
},
],
referenced_documents: refDocs.map((d, index) => ({
docs_url: d,
title: "Create variables" + (index > 0 ? index : ""),
})),
response:
"In Ansible, the precedence of variables is determined by the order...",
truncated: false,
Expand Down Expand Up @@ -157,6 +162,7 @@ describe("App tests", () => {
});

it("ThumbsDown icon test", async () => {
const ghIssueLinkSpy = vi.spyOn(global, "open");
mockAxios(200);
renderApp();
const textArea = screen.getByLabelText("Send a message...");
Expand All @@ -175,6 +181,50 @@ describe("App tests", () => {

const sureButton = screen.getByText("Sure!");
await act(async () => fireEvent.click(sureButton));

expect(ghIssueLinkSpy.mock.calls.length).toEqual(1);
expect(ghIssueLinkSpy.mock.calls[0][0]).toContain(
encodeURIComponent(referencedDocumentExample[0]),
);
});

const REF_DOCUMENT_EXAMPLE_REGEXP = new RegExp(
encodeURIComponent(referencedDocumentExample[0]),
"g",
);

it("Too many reference documents for the GU issue creation query param.", async () => {
const ghIssueLinkSpy = vi.spyOn(global, "open");
// Initialize 35 reference documents for this test case, in order to verify that the url
// will not contain more than the max allowed documents (30).
const lotsOfRefDocs = [];
for (let i = 0; i < 35; i++) {
lotsOfRefDocs.push(referencedDocumentExample[0]);
}
mockAxios(200, false, false, lotsOfRefDocs);
renderApp();
const textArea = screen.getByLabelText("Send a message...");
await act(async () => userEvent.type(textArea, "Hello"));
const sendButton = screen.getByLabelText("Send button");
await act(async () => fireEvent.click(sendButton));
expect(
screen.getByText(
"In Ansible, the precedence of variables is determined by the order...",
),
).toBeInTheDocument();
expect(screen.getByText("Create variables")).toBeInTheDocument();

const thumbsDownIcon = screen.getByRole("button", { name: "Bad response" });
await act(async () => fireEvent.click(thumbsDownIcon));

const sureButton = screen.getByText("Sure!");
await act(async () => fireEvent.click(sureButton));

expect(ghIssueLinkSpy.mock.calls.length).toEqual(1);
// Assert the size of the resulting documents in the query parameter is 30,
// as the max defined, instead of the 35 being present.
const url: string | undefined = ghIssueLinkSpy.mock.calls[0][0]?.toString();
expect((url?.match(REF_DOCUMENT_EXAMPLE_REGEXP) || []).length).toEqual(30);
});

it("Chat service returns 500", async () => {
Expand Down
6 changes: 2 additions & 4 deletions ansible_ai_connect_chatbot/src/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,5 @@ export enum Sentiment {
THUMBS_DOWN = 1,
}

export const GITHUB_NEW_ISSUE_URL =
"https://github.com/ansible/ansible-lightspeed-va-feedback/issues/new" +
"?assignees=korenaren&labels=bug%2Ctriage&projects=&template=chatbot_feedback.yml" +
"&title=Chatbot+response+can+be+improved";
export const GITHUB_NEW_ISSUE_BASE_URL =
"https://github.com/ansible/ansible-lightspeed-va-feedback/issues/new";
39 changes: 31 additions & 8 deletions ansible_ai_connect_chatbot/src/useChatbot/useChatbot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import logo from "../assets/lightspeed.svg";
import userLogo from "../assets/user_logo.png";
import {
API_TIMEOUT,
GITHUB_NEW_ISSUE_URL,
GITHUB_NEW_ISSUE_BASE_URL,
Sentiment,
TIMEOUT_MSG,
TOO_MANY_REQUESTS_MSG,
Expand Down Expand Up @@ -82,12 +82,7 @@ export const feedbackMessage = (f: ChatFeedback): MessageProps => ({
content: "Sure!",
id: "response",
onClick: () =>
window
.open(
`${GITHUB_NEW_ISSUE_URL}&conversation_id=${f.response.conversation_id}&prompt=${f.query}&response=${f.response.response}`,
"_blank",
)
?.focus(),
window.open(createGitHubIssueURL(f), "_blank")?.focus(),
},
],
});
Expand All @@ -114,6 +109,32 @@ const INITIAL_NOTICE: AlertMessage = {
variant: "info",
};

const createGitHubIssueURL = (f: ChatFeedback): string => {
const searchParams: URLSearchParams = new URLSearchParams();
searchParams.append("assignees", "korenaren");
searchParams.append("labels", "bug,triage");
searchParams.append("projects", "");
searchParams.append("template", "chatbot_feedback.yml");
searchParams.append("conversation_id", f.response.conversation_id);
searchParams.append("prompt", f.query);
searchParams.append("response", f.response.response);
// Referenced documents may increase as more source documents being ingested,
// so let's be try not to generate long length for query parameter "ref_docs",
// otherwise GH returns 414 URI Too Long error page. Assuming max of 30 docs.
// See https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/creating-an-issue#creating-an-issue-from-a-url-query.
searchParams.append(
"ref_docs",
f.response.referenced_documents
?.slice(0, 30)
.map((doc) => doc.docs_url)
.join("\n"),
);

const url = new URL(GITHUB_NEW_ISSUE_BASE_URL);
url.search = searchParams.toString();
return url.toString();
};

export const useChatbot = () => {
const [messages, setMessages] = useState<ExtendedMessage[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
Expand Down Expand Up @@ -185,7 +206,9 @@ export const useChatbot = () => {
try {
const csrfToken = readCookie("csrftoken");
const resp = await axios.post(
"/api/v0/ai/feedback/",
import.meta.env.PROD
? "/api/v0/ai/chat/"
: "http://localhost:8080/v1/feedback/",
{
chatFeedback: feedbackRequest,
},
Expand Down

0 comments on commit ef929ba

Please sign in to comment.