Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clever-pens-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-llama": patch
---

Add DuckDuckGo search tool
23 changes: 23 additions & 0 deletions helpers/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,29 @@ export const supportedTools: Tool[] = [
},
],
},
{
// For python app, we will use a local DuckDuckGo search tool (instead of DuckDuckGo search tool in LlamaHub)
// to get the same results as the TS app.
display: "DuckDuckGo Search",
name: "duckduckgo",
dependencies: [
{
name: "duckduckgo-search",
version: "6.1.7",
},
],
supportedFrameworks: ["fastapi", "nextjs", "express"],
type: ToolType.LOCAL,
envVars: [
{
name: TOOL_SYSTEM_PROMPT_ENV_VAR,
description: "System prompt for DuckDuckGo search tool.",
value: `You are a DuckDuckGo search agent.
You can use the duckduckgo search tool to get information from the web to answer user questions.
For better results, you can specify the region parameter to get results from a specific region but it's optional.`,
},
],
},
{
display: "Wikipedia",
name: "wikipedia.WikipediaToolSpec",
Expand Down
36 changes: 36 additions & 0 deletions templates/components/engines/python/agent/tools/duckduckgo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from llama_index.core.tools.function_tool import FunctionTool


def duckduckgo_search(
query: str,
region: str = "wt-wt",
max_results: int = 10,
):
"""
Use this function to search for any query in DuckDuckGo.
Args:
query (str): The query to search in DuckDuckGo.
region Optional(str): The region to be used for the search in [country-language] convention, ex us-en, uk-en, ru-ru, etc...
max_results Optional(int): The maximum number of results to be returned. Default is 10.
"""
try:
from duckduckgo_search import DDGS
except ImportError:
raise ImportError(
"duckduckgo_search package is required to use this function."
"Please install it by running: `poetry add duckduckgo_search` or `pip install duckduckgo_search`"
)

params = {
"keywords": query,
"region": region,
"max_results": max_results,
}
results = []
with DDGS() as ddg:
results = list(ddg.text(**params))
return results


def get_tools():
return [FunctionTool.from_defaults(duckduckgo_search)]
61 changes: 61 additions & 0 deletions templates/components/engines/typescript/agent/tools/duckduckgo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { JSONSchemaType } from "ajv";
import { search } from "duck-duck-scrape";
import { BaseTool, ToolMetadata } from "llamaindex";

export type DuckDuckGoParameter = {
query: string;
region?: string;
};

export type DuckDuckGoToolParams = {
metadata?: ToolMetadata<JSONSchemaType<DuckDuckGoParameter>>;
};

const DEFAULT_META_DATA: ToolMetadata<JSONSchemaType<DuckDuckGoParameter>> = {
name: "duckduckgo",
description: "Use this function to search for any query in DuckDuckGo.",
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: "The query to search in DuckDuckGo.",
},
region: {
type: "string",
description:
"Optional, The region to be used for the search in [country-language] convention, ex us-en, uk-en, ru-ru, etc...",
nullable: true,
},
},
required: ["query"],
},
};

type DuckDuckGoSearchResult = {
title: string;
description: string;
url: string;
};

export class DuckDuckGoSearchTool implements BaseTool<DuckDuckGoParameter> {
metadata: ToolMetadata<JSONSchemaType<DuckDuckGoParameter>>;

constructor(params: DuckDuckGoToolParams) {
this.metadata = params.metadata ?? DEFAULT_META_DATA;
}

async call(input: DuckDuckGoParameter) {
const { query, region } = input;
const options = region ? { region } : {};
const searchResults = await search(query, options);

return searchResults.results.map((result) => {
return {
title: result.title,
description: result.description,
url: result.url,
} as DuckDuckGoSearchResult;
});
}
}
4 changes: 4 additions & 0 deletions templates/components/engines/typescript/agent/tools/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BaseToolWithCall } from "llamaindex";
import { ToolsFactory } from "llamaindex/tools/ToolsFactory";
import { DuckDuckGoSearchTool, DuckDuckGoToolParams } from "./duckduckgo";
import { InterpreterTool, InterpreterToolParams } from "./interpreter";
import { OpenAPIActionTool } from "./openapi-action";
import { WeatherTool, WeatherToolParams } from "./weather";
Expand Down Expand Up @@ -35,6 +36,9 @@ const toolFactory: Record<string, ToolCreator> = {
);
return await openAPIActionTool.toToolFunctions();
},
duckduckgo: async (config: unknown) => {
return [new DuckDuckGoSearchTool(config as DuckDuckGoToolParams)];
},
};

async function createLocalTools(
Expand Down
1 change: 1 addition & 0 deletions templates/types/streaming/express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"ai": "^3.0.21",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"duck-duck-scrape": "^2.2.5",
"express": "^4.18.2",
"llamaindex": "0.3.16",
"pdf2json": "3.0.5",
Expand Down
1 change: 1 addition & 0 deletions templates/types/streaming/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"dotenv": "^16.3.1",
"duck-duck-scrape": "^2.2.5",
"llamaindex": "0.3.16",
"lucide-react": "^0.294.0",
"next": "^14.0.3",
Expand Down