diff --git a/crewai_tools/tools/linkup/README.md b/crewai_tools/tools/linkup/README.md index c51946a..3f0986e 100644 --- a/crewai_tools/tools/linkup/README.md +++ b/crewai_tools/tools/linkup/README.md @@ -8,9 +8,7 @@ The `LinkupSearchTool` is a tool designed for integration with the CrewAI framew ## 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. +- Perform API queries to the Linkup platform using customizable parameters (`query`, `depth`, `output_type`, `structured_output_schema`). --- @@ -26,11 +24,6 @@ The `LinkupSearchTool` is a tool designed for integration with the CrewAI framew 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 @@ -43,56 +36,58 @@ Here is how to use the `LinkupSearchTool` in a CrewAI project: ```python from tools.linkup_tools import LinkupSearchTool import os - from dotenv import load_dotenv + import json - load_dotenv() + os.environ["LINKUP_API_KEY"] = "your_linkup_api_key" + os.environ["OPENAI_API_KEY"] = "your_openai_api_key" + depth = "standard" # or deep + output_type = "sourcedAnswer" # or searchResults or structured - linkup_tool = LinkupSearchTool(api_key=os.getenv("LINKUP_API_KEY")) - ``` + # If output_type = structured, define a structured schema + structured_output_schema = {your schema} -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) - ``` + structured_output_schema_json = json.dumps(structured_output_schema) -### Advanced Configuration + # Initialize the Linkup search tool -You can customize the parameters for the `LinkupSearchTool`: + linkup_tool = LinkupSearchTool( + api_key=os.getenv("LINKUP_API_KEY"), + depth=depth, + output_type=output_type, + structured_output_schema=structured_output_schema_json # ONLY if output_type = structured + ) -- `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 +2. **Set Up an Agent and Task**: + ```python + from crewai import Agent, Task, Crew + + # Create an agent + researcher = Agent( + role="Market Research Analyst", + goal="Provide deep insights using Linkup for AI industry trends.", + backstory="An experienced analyst skilled in using advanced tools for market insights.", + tools=[linkup_tool], + verbose=True, # change to False if you don't want to see execution logs + ) + + # Define a task + research = Task( + description="Research the latest trends in the AI industry using the Linkup tool and provide insights.", + expected_output="A summary of the top 3 trends with context and relevance to the industry.", + agent=researcher, + ) + + + + # Set up and execute the Crew + crew = Crew( + agents=[researcher], + tasks=[research], + verbose=True, + planning=True, # or False if you don't want to see planning logs + ) + crew.kickoff() + + ``` diff --git a/crewai_tools/tools/linkup/assets/icon.png b/crewai_tools/tools/linkup/assets/icon.png deleted file mode 100644 index 4848d4c..0000000 Binary files a/crewai_tools/tools/linkup/assets/icon.png and /dev/null differ diff --git a/crewai_tools/tools/linkup/linkup_search_tool.py b/crewai_tools/tools/linkup/linkup_search_tool.py index 4eb2d82..30f5a9a 100644 --- a/crewai_tools/tools/linkup/linkup_search_tool.py +++ b/crewai_tools/tools/linkup/linkup_search_tool.py @@ -1,73 +1,60 @@ -from typing import Any - +from typing import Any, Type +from pydantic import BaseModel, Field from crewai.tools import BaseTool - try: from linkup import LinkupClient - LINKUP_AVAILABLE = True except ImportError: LINKUP_AVAILABLE = False - LinkupClient = Any # type placeholder when package is not available + LinkupClient = Any -from pydantic import PrivateAttr + +class LinkupSearchToolSchema(BaseModel): + """Input for LinkupBaseTool.""" + + query: str = Field( + ..., description="The query to search for." + ) class LinkupSearchTool(BaseTool): name: str = "Linkup Search Tool" - description: str = ( - "Performs an API call to Linkup to retrieve contextual information." - ) - _client: LinkupClient = PrivateAttr() # type: ignore - description: str = ( - "Performs an API call to Linkup to retrieve contextual information." - ) - _client: LinkupClient = PrivateAttr() # type: ignore + description: str = "A tool to search and retrieve trends or insights using the Linkup API." + args_schema: Type[BaseModel] = LinkupSearchToolSchema - def __init__(self, api_key: str): - """ - Initialize the tool with an API key. - """ - super().__init__() - try: - from linkup import LinkupClient - except ImportError: - import click - if click.confirm( - "You are missing the 'linkup-sdk' package. Would you like to install it?" - ): - import subprocess + def __init__(self, api_key: str, depth: str, output_type: str, structured_output_schema:str = None, **kwargs): + from linkup import LinkupClient - subprocess.run(["uv", "add", "linkup-sdk"], check=True) - from linkup import LinkupClient + super().__init__(**kwargs) + if not LINKUP_AVAILABLE: + raise ImportError( + "The 'linkup' package is required to use the LinkupSearchTool. " + "Please install it with: pip install linkup" + ) - else: - raise ImportError( - "The 'linkup-sdk' package is required to use the LinkupSearchTool. " - "Please install it with: uv add linkup-sdk" - ) self._client = LinkupClient(api_key=api_key) + self._default_depth = depth + self._default_output_type = output_type + self._default_structured_schema = structured_output_schema + + def _run(self, query: str ) : - 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. + :return: 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)} + + api_params = { + "query": query, + "depth": self._default_depth, + "output_type": self._default_output_type, + } + + if self._default_output_type == "structured": + if not self.structured_output_schema: + raise ValueError("structured_output_schema must be provided when output_type is 'structured'.") + api_params["structured_output_schema"] = self._default_structured_schema + return self._client.search(**api_params) diff --git a/pyproject.toml b/pyproject.toml index 57d6bf3..71d9472 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,8 +18,14 @@ dependencies = [ "docker>=7.1.0", "embedchain>=0.1.114", "crewai>=0.95.0", - "click>=8.1.8", - "lancedb>=0.5.4", + "scrapegraph-py>=1.8.0", + "serpapi>=0.1.5", + "weaviate-client>=4.9.6", + "linkup-sdk>=0.2.2", + "spider-client>=0.1.25", + "linkup>=0.1.3", + "patronus>=0.0.16", + "snowflake>=1.0.2" ] [project.urls]