From 4c5f1962ace1f5ad4fe628f7cb2a33cf19753783 Mon Sep 17 00:00:00 2001 From: juliette_sivan Date: Thu, 19 Dec 2024 14:07:36 +0100 Subject: [PATCH 1/2] add linkup tool --- src/crewai_tools/tools/linkup/README.md | 98 ++++++++++++++++++ src/crewai_tools/tools/linkup/assets/icon.png | Bin 0 -> 32966 bytes .../tools/linkup/linkup_search_tool.py | 36 +++++++ 3 files changed, 134 insertions(+) create mode 100644 src/crewai_tools/tools/linkup/README.md create mode 100644 src/crewai_tools/tools/linkup/assets/icon.png create mode 100644 src/crewai_tools/tools/linkup/linkup_search_tool.py diff --git a/src/crewai_tools/tools/linkup/README.md b/src/crewai_tools/tools/linkup/README.md new file mode 100644 index 000000000..c51946a11 --- /dev/null +++ b/src/crewai_tools/tools/linkup/README.md @@ -0,0 +1,98 @@ +# Linkup Search Tool + +## Description + +The `LinkupSearchTool` is a tool designed for integration with the CrewAI framework. It provides the ability to query the Linkup API for contextual information and retrieve structured results. This tool is ideal for enriching workflows with up-to-date and reliable information from Linkup. + +--- + +## Features + +- Perform API queries to the Linkup platform using customizable parameters (`query`, `depth`, `output_type`). +- Gracefully handles API errors and provides structured feedback. +- Returns well-structured results for seamless integration into CrewAI processes. + +--- + +## Installation + +### Prerequisites + +- Linkup API Key + +### Steps + +1. ```shell + pip install 'crewai[tools]' + ``` + +2. Create a `.env` file in your project root and add your Linkup API Key: + ```plaintext + LINKUP_API_KEY=your_linkup_api_key + ``` + +--- + +## Usage + +### Basic Example + +Here is how to use the `LinkupSearchTool` in a CrewAI project: + +1. **Import and Initialize**: + ```python + from tools.linkup_tools import LinkupSearchTool + import os + from dotenv import load_dotenv + + load_dotenv() + + linkup_tool = LinkupSearchTool(api_key=os.getenv("LINKUP_API_KEY")) + ``` + +2. **Set Up an Agent and Task**: + ```python + from crewai import Agent, Task, Crew + + # Define the agent + research_agent = Agent( + role="Information Researcher", + goal="Fetch relevant results from Linkup.", + backstory="An expert in online information retrieval...", + tools=[linkup_tool], + verbose=True + ) + + # Define the task + search_task = Task( + expected_output="A detailed list of Nobel Prize-winning women in physics with their achievements.", + description="Search for women who have won the Nobel Prize in Physics.", + agent=research_agent + ) + + # Create and run the crew + crew = Crew( + agents=[research_agent], + tasks=[search_task] + ) + + result = crew.kickoff() + print(result) + ``` + +### Advanced Configuration + +You can customize the parameters for the `LinkupSearchTool`: + +- `query`: The search term or phrase. +- `depth`: The search depth (`"standard"` by default). +- `output_type`: The type of output (`"searchResults"` by default). + +Example: +```python +response = linkup_tool._run( + query="Women Nobel Prize Physics", + depth="standard", + output_type="searchResults" +) +``` \ No newline at end of file diff --git a/src/crewai_tools/tools/linkup/assets/icon.png b/src/crewai_tools/tools/linkup/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4848d4c6b19b1da998326dbd6a3efdf3671a48a3 GIT binary patch literal 32966 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 literal 0 HcmV?d00001 diff --git a/src/crewai_tools/tools/linkup/linkup_search_tool.py b/src/crewai_tools/tools/linkup/linkup_search_tool.py new file mode 100644 index 000000000..8ddb81527 --- /dev/null +++ b/src/crewai_tools/tools/linkup/linkup_search_tool.py @@ -0,0 +1,36 @@ +from linkup import LinkupClient +from pydantic import PrivateAttr + +class LinkupSearchTool: + name: str = "Linkup Search Tool" + description: str = "Performs an API call to Linkup to retrieve contextual information." + _client: LinkupClient = PrivateAttr() + + def __init__(self, api_key: str): + """ + Initialize the tool with an API key. + """ + self._client = LinkupClient(api_key=api_key) + + def _run(self, query: str, depth: str = "standard", output_type: str = "searchResults") -> dict: + """ + Executes a search using the Linkup API. + + :param query: The query to search for. + :param depth: Search depth (default is "standard"). + :param output_type: Desired result type (default is "searchResults"). + :return: A dictionary containing the results or an error message. + """ + try: + response = self._client.search( + query=query, + depth=depth, + output_type=output_type + ) + results = [ + {"name": result.name, "url": result.url, "content": result.content} + for result in response.results + ] + return {"success": True, "results": results} + except Exception as e: + return {"success": False, "error": str(e)} From e5c47e46a8fa9b078f13f12f5973955536c4033f Mon Sep 17 00:00:00 2001 From: juliette_sivan Date: Sat, 28 Dec 2024 10:59:06 -0500 Subject: [PATCH 2/2] add import tools --- src/crewai_tools/__init__.py | 1 + src/crewai_tools/tools/__init__.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/crewai_tools/__init__.py b/src/crewai_tools/__init__.py index 12523a214..68e778006 100644 --- a/src/crewai_tools/__init__.py +++ b/src/crewai_tools/__init__.py @@ -17,6 +17,7 @@ from .tools import ( FirecrawlSearchTool, GithubSearchTool, JSONSearchTool, + LinkupSearchTool, LlamaIndexTool, MDXSearchTool, MultiOnTool, diff --git a/src/crewai_tools/tools/__init__.py b/src/crewai_tools/tools/__init__.py index 23565dbea..67c9c79e7 100644 --- a/src/crewai_tools/tools/__init__.py +++ b/src/crewai_tools/tools/__init__.py @@ -20,6 +20,7 @@ from .firecrawl_scrape_website_tool.firecrawl_scrape_website_tool import ( from .firecrawl_search_tool.firecrawl_search_tool import FirecrawlSearchTool from .github_search_tool.github_search_tool import GithubSearchTool from .json_search_tool.json_search_tool import JSONSearchTool +from .linkup_search_tool.linkup_search_tool import LinkupSearchTool from .llamaindex_tool.llamaindex_tool import LlamaIndexTool from .mdx_seach_tool.mdx_search_tool import MDXSearchTool from .multion_tool.multion_tool import MultiOnTool