feat: add duckduckgo search component (#3798)
* 🔧 (pyproject.toml): add duckduckgo-search dependency to the project ✨ (DuckDuckGoSearchRun.py): introduce DuckDuckGoSearchComponent for performing web searches using DuckDuckGo search engine ✨ (DuckDuckGo.jsx): add SVG icon for DuckDuckGo ✨ (index.tsx): create DuckDuckGoIcon component for displaying DuckDuckGo icon 🔧 (styleUtils.ts): import DuckDuckGoIcon for nodeIconsLucide in styleUtils * 📝 (DuckDuckGoSearchRun.py): remove unnecessary whitespace to improve code readability and consistency * ✨ (DuckDuckGoSearchRun.py): Add retry logic to DuckDuckGo search component for rate-limited requests 📝 (DuckDuckGoSearchRun.py): Update component description to reflect the addition of retry logic 📝 (DuckDuckGoSearchRun.py): Add new inputs for max_retries and initial_delay to configure retry behavior 📝 (DuckDuckGoSearchRun.py): Update search_response method to use search_with_retry method with retry logic 📝 (DuckDuckGoSearchRun.py): Update format_results method to handle formatted results 📝 (DuckDuckGoSearchRun.py): Add search_with_retry method to handle search with retry logic 📝 (DuckDuckGoSearchRun.py): Update search_response method to use search_with_retry method 📝 (DuckDuckGoSearchRun.py): Update search_response method to set status messages 📝 (DuckDuckGoSearchRun.py): Handle exceptions and set appropriate status messages in search_response method ✨ (duckduckgo.spec.ts): Add integration test for DuckDuckGo search component in frontend * 📝 (DuckDuckGoSearchRun.py): add newline at the end of the file to follow best practices and avoid potential issues with some tools that expect it * [autofix.ci] apply automated fixes * updating duckudckgo * [autofix.ci] apply automated fixes * ✨ (DuckDuckGoSearchRun.py): Refactor DuckDuckGoSearchComponent to use pydantic BaseModel for schema definition and improve code structure for better readability and maintainability. Add support for result limiting in search functionality. * 🔧 (DuckDuckGoSearchRun.py): Remove unnecessary import and update status message for DuckDuckGo Search Tool to improve clarity * [autofix.ci] apply automated fixes * ✨ (duckduckgo.spec.ts): update test selectors for duckduckgo search component to match changes in the frontend code and improve test reliability * 🐛 (linkComponent.spec.ts): fix an issue where the key combination for selecting all text was not working correctly on Mac devices. Updated the key combination to use the correct modifier key based on the user's operating system. * 📝 (frontend): mark is-unicode-supported package as extraneous in package-lock.json * rollback lock file --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
50f9f72f5f
commit
8c8be151e5
9 changed files with 253 additions and 2 deletions
59
src/frontend/src/icons/DuckDuckGo/DuckDuckGo.jsx
Normal file
59
src/frontend/src/icons/DuckDuckGo/DuckDuckGo.jsx
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
const SvgDuckDuckGo = ({ ...props }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 122.88 122.88"
|
||||
{...props}
|
||||
height="1rem"
|
||||
width="1rem"
|
||||
>
|
||||
<defs>
|
||||
<style>{".b{fill:#fff}"}</style>
|
||||
</defs>
|
||||
<title>{"duckduckgo"}</title>
|
||||
<path
|
||||
d="M122.88 61.44a61.44 61.44 0 1 0-61.44 61.44 61.44 61.44 0 0 0 61.44-61.44Z"
|
||||
style={{
|
||||
fill: "#d53",
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d="M114.37 61.44a52.92 52.92 0 1 0-15.5 37.43 52.76 52.76 0 0 0 15.5-37.43Zm-13.12-39.8A56.29 56.29 0 1 1 61.44 5.15a56.12 56.12 0 0 1 39.81 16.49Z"
|
||||
className="b"
|
||||
/>
|
||||
<path
|
||||
d="M43.24 30.15C26.17 34.13 32.43 58 32.43 58l10.81 52.9 4 1.71-4-82.49Zm-4-10.24H34.7l6.3 2.28s-6.26 0-6.26 4C48.36 25.6 54.61 29 54.61 29l-15.36-9.1Zm0 0Z"
|
||||
style={{
|
||||
fill: "#ddd",
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d="M75.66 115.48S62 93.87 62 79.64c0-26.73 17.63-4 17.63-25S62 28.44 62 28.44c-8.53-10.8-25-8.53-25-8.53l4 2.28s-4 1.13-5.12 2.27 10.81-1.7 15.93 2.85C30.72 29 34.13 46.08 34.13 46.08l11.95 68.27 29.58 1.13Zm0 0Z"
|
||||
className="b"
|
||||
/>
|
||||
<path
|
||||
d="m75.66 60.87 21.62-5.69c19.34 2.82-16.5 13.66-18.77 13.09-17.07-2.85-12 11.37 8.53 6.82s5.12 11.38-13.65 5.12c-26.74-7.39-12.52-20.48 2.27-19.34Z"
|
||||
style={{
|
||||
fill: "#fc0",
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d="m70 105.81 1.14-1.7c12.52 4.55 13.09 6.25 12.52-5.12s0-11.38-13.09-1.71c0-2.84-7.39-1.71-8.53 0-11.95-5.12-13.09-6.83-12.52 1.14 1.14 16.5.57 13.65 11.95 8l8.53-.57Zm0 0Z"
|
||||
style={{
|
||||
fill: "#6b5",
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d="M60.87 99.56v6.82c.57 1.14 9.67 1.14 9.67-1.14s-4.55 1.71-7.39.57S62 98.42 62 98.42l-1.14 1.14Zm0 0Z"
|
||||
style={{
|
||||
fill: "#4a4",
|
||||
}}
|
||||
/>
|
||||
<path
|
||||
d="M48.36 43.24c-2.85-3.42-10.24-.57-8.54 4 .57-2.28 4.55-5.69 8.54-4Zm18.2 0c.57-3.42 6.26-4 8-.57a8 8 0 0 0-8 .57Zm-18.77 9.1a1.14 1.14 0 1 1 0 .57v-.57Zm-4.55 2.27a4 4 0 1 0 0-.57v.57Zm29.58-4a1.14 1.14 0 1 1 0 .57v-.57Zm-3.42 2.3a3.42 3.42 0 1 0 0-.57v.57Zm0 0Z"
|
||||
style={{
|
||||
fill: "#148",
|
||||
}}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
export default SvgDuckDuckGo;
|
||||
1
src/frontend/src/icons/DuckDuckGo/duckduckgo-icon.svg
Normal file
1
src/frontend/src/icons/DuckDuckGo/duckduckgo-icon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 122.88 122.88"><defs><style>.a{fill:#d53;}.b{fill:#fff;}.c{fill:#ddd;}.d{fill:#fc0;}.e{fill:#6b5;}.f{fill:#4a4;}.g{fill:#148;}</style></defs><title>duckduckgo</title><path class="a" d="M122.88,61.44a61.44,61.44,0,1,0-61.44,61.44,61.44,61.44,0,0,0,61.44-61.44Z"/><path class="b" d="M114.37,61.44a52.92,52.92,0,1,0-15.5,37.43,52.76,52.76,0,0,0,15.5-37.43Zm-13.12-39.8A56.29,56.29,0,1,1,61.44,5.15a56.12,56.12,0,0,1,39.81,16.49Z"/><path class="c" d="M43.24,30.15C26.17,34.13,32.43,58,32.43,58l10.81,52.9,4,1.71-4-82.49Zm-4-10.24H34.7L41,22.19s-6.26,0-6.26,4C48.36,25.6,54.61,29,54.61,29l-15.36-9.1Zm0,0Z"/><path class="b" d="M75.66,115.48S62,93.87,62,79.64c0-26.73,17.63-4,17.63-25S62,28.44,62,28.44c-8.53-10.8-25-8.53-25-8.53l4,2.28s-4,1.13-5.12,2.27,10.81-1.7,15.93,2.85C30.72,29,34.13,46.08,34.13,46.08l11.95,68.27,29.58,1.13Zm0,0Z"/><path class="d" d="M75.66,60.87l21.62-5.69C116.62,58,80.78,68.84,78.51,68.27c-17.07-2.85-12,11.37,8.53,6.82s5.12,11.38-13.65,5.12c-26.74-7.39-12.52-20.48,2.27-19.34Z"/><path class="e" d="M70,105.81l1.14-1.7c12.52,4.55,13.09,6.25,12.52-5.12s0-11.38-13.09-1.71c0-2.84-7.39-1.71-8.53,0-11.95-5.12-13.09-6.83-12.52,1.14,1.14,16.5.57,13.65,11.95,8l8.53-.57Zm0,0Z"/><path class="f" d="M60.87,99.56v6.82c.57,1.14,9.67,1.14,9.67-1.14s-4.55,1.71-7.39.57S62,98.42,62,98.42l-1.14,1.14Zm0,0Z"/><path class="g" d="M48.36,43.24c-2.85-3.42-10.24-.57-8.54,4,.57-2.28,4.55-5.69,8.54-4Zm18.2,0c.57-3.42,6.26-4,8-.57a8,8,0,0,0-8,.57Zm-18.77,9.1a1.14,1.14,0,1,1,0,.57v-.57Zm-4.55,2.27a4,4,0,1,0,0-.57v.57Zm29.58-4a1.14,1.14,0,1,1,0,.57v-.57ZM69.4,52.91a3.42,3.42,0,1,0,0-.57v.57Zm0,0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
9
src/frontend/src/icons/DuckDuckGo/index.tsx
Normal file
9
src/frontend/src/icons/DuckDuckGo/index.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import React, { forwardRef } from "react";
|
||||
import SvgDuckDuckGo from "./DuckDuckGo";
|
||||
|
||||
export const DuckDuckGoIcon = forwardRef<
|
||||
SVGSVGElement,
|
||||
React.PropsWithChildren<{ color?: string }>
|
||||
>((props, ref) => {
|
||||
return <SvgDuckDuckGo ref={ref} {...props} />;
|
||||
});
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import { AIMLIcon } from "@/icons/AIML";
|
||||
import { DuckDuckGoIcon } from "@/icons/DuckDuckGo";
|
||||
import Perplexity from "@/icons/Perplexity/Perplexity";
|
||||
import { UnstructuredIcon } from "@/icons/Unstructured";
|
||||
import { AthenaIcon } from "@/icons/athena/index";
|
||||
|
|
@ -627,4 +628,5 @@ export const nodeIconsLucide: iconsType = {
|
|||
OptionIcon: OptionIcon,
|
||||
Option: OptionIcon,
|
||||
Perplexity,
|
||||
DuckDuckGo: DuckDuckGoIcon,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ test("user should interact with link component", async ({ context, page }) => {
|
|||
const userAgentInfo = uaParser(getUA);
|
||||
let control = "Control";
|
||||
|
||||
if (userAgentInfo.os.name.includes("Mac")) {
|
||||
control = "Meta";
|
||||
}
|
||||
|
||||
await page.waitForSelector('[data-testid="blank-flow"]', {
|
||||
timeout: 30000,
|
||||
});
|
||||
|
|
@ -80,7 +84,7 @@ test("user should interact with link component", async ({ context, page }) => {
|
|||
LinkInput(name="link", display_name="BUTTON", value="https://www.datastax.com", text="Click me"),`,
|
||||
);
|
||||
|
||||
await page.locator("textarea").last().press(`Meta+a`);
|
||||
await page.locator("textarea").last().press(`${control}+a`);
|
||||
await page.keyboard.press("Backspace");
|
||||
await page.locator("textarea").last().fill(cleanCode);
|
||||
await page.locator('//*[@id="checkAndSaveBtn"]').click();
|
||||
|
|
|
|||
67
src/frontend/tests/extended/integrations/duckduckgo.spec.ts
Normal file
67
src/frontend/tests/extended/integrations/duckduckgo.spec.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test("user should be able to use duckduckgo search component", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/");
|
||||
await page.waitForSelector('[data-testid="mainpage_title"]', {
|
||||
timeout: 30000,
|
||||
});
|
||||
|
||||
await page.waitForSelector('[id="new-project-btn"]', {
|
||||
timeout: 30000,
|
||||
});
|
||||
|
||||
let modalCount = 0;
|
||||
try {
|
||||
const modalTitleElement = await page?.getByTestId("modal-title");
|
||||
if (modalTitleElement) {
|
||||
modalCount = await modalTitleElement.count();
|
||||
}
|
||||
} catch (error) {
|
||||
modalCount = 0;
|
||||
}
|
||||
|
||||
while (modalCount === 0) {
|
||||
await page.getByText("New Project", { exact: true }).click();
|
||||
await page.waitForTimeout(3000);
|
||||
modalCount = await page.getByTestId("modal-title")?.count();
|
||||
}
|
||||
|
||||
await page.getByTestId("blank-flow").click();
|
||||
await page.waitForSelector('[data-testid="extended-disclosure"]', {
|
||||
timeout: 30000,
|
||||
});
|
||||
await page.getByTestId("extended-disclosure").click();
|
||||
await page.getByPlaceholder("Search").click();
|
||||
await page.getByPlaceholder("Search").fill("duck");
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page
|
||||
.locator('//*[@id="toolsDuckDuckGo Search"]')
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
await page.getByTitle("fit view").click();
|
||||
|
||||
await page
|
||||
.getByTestId("popover-anchor-input-input_value")
|
||||
.fill("what is langflow?");
|
||||
|
||||
await page.getByTestId("button_run_duckduckgo search").click();
|
||||
|
||||
await page.getByTitle("fit view").click();
|
||||
|
||||
await page.waitForSelector("text=built successfully", { timeout: 30000 });
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.getByTestId("output-inspection-data").first().click();
|
||||
|
||||
await page.getByRole("gridcell").first().click();
|
||||
|
||||
const searchResults = await page.getByPlaceholder("Empty").inputValue();
|
||||
expect(searchResults.length).toBeGreaterThan(10);
|
||||
expect(searchResults.toLowerCase()).toContain("langflow");
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue