File size: 3,311 Bytes
c4d30a5
e922dc7
 
27a73b6
 
e922dc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47ebf49
 
 
 
 
 
 
 
 
490f993
e922dc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from typing import Any, Literal, Optional
from smolagents.tools import Tool

import linkup

class LinkupSearchTool(Tool):
    """LinkupSearchTool tool.

LinkupSearchTool performs web search queries using the Linkup API, which includes results from both
public and premium web sources. It supports two modes of search depth β€” standard and deep β€” allowing
for flexible information retrieval depending on the complexity of the query.

Setup:
    Make sure your Linkup API key is exported to the environment:

    .. code-block:: bash

        pip install linkup-sdk
        export LINKUP_API_KEY="your-api-key"

Example:
        from smolagents import load_tool, CodeAgent, InferenceClientModel

        agent = CodeAgent(
            tools=[LinkupSearchTool()],
            model=InferenceClientModel(),
        )
        agent.run(query="What was Microsoft's revenue last quarter and was it well perceived by the market?", depth="deep")

Args:
    linkup_api_key (str | None): Optional. If not provided, LinkupClient will check the LINKUP_API_KEY env variable.
"""
    name = "search_web"
    description = "Performs an online search using Linkup search engine and retrieves the top results as a string. This function is useful for accessing real-time information, including news, articles, and other relevant web content."
    output_type = "string"

    inputs = {
        "query": {"type": "string", "description": "The search query to perform."},
        "depth": {
            "type": "string",
            "enum": ["standard", "deep"],
            "description": "The search depth to perform. Use 'standard' for straightforward queries with likely direct answers (e.g., facts, definitions, simple explanations). Use 'deep' for: 1) complex queries requiring comprehensive analysis or information synthesis, 2) queries containing uncommon terms, specialized jargon, or abbreviations that may need additional context, or 3) questions likely requiring up-to-date or specialized web search results to answer effectively.",
        },
    }
    
    def __init__(self, linkup_api_key: str | None = None, **kwargs) -> None:
        super().__init__()
        try:
            from linkup import LinkupClient
        except ImportError as e:
            raise ImportError(
                "You must install package `linkup-sdk` to run this tool: for instance run `pip install linkup-sdk`."
            ) from e

        self.client = LinkupClient(api_key=linkup_api_key)

    def forward(self, query: str, depth: str) -> str:

        if depth not in ["standard", "deep"]:
            raise ValueError("depth must be 'standard' or 'deep'")

        try:
            response = self.client.search(
                query=query, depth=depth, output_type="searchResults"
            )

            results = getattr(response, "results", [{"content": "No answer provided."}])

        except Exception as e:
            return f"Error occurred during Linkup search: {str(e)}"

        formatted_results = []
        for i, doc in enumerate(results, start=1):
            formatted_results.append(
                f"{i}. **{doc.name or 'Untitled'}**\n URL: {doc.url or 'N/A'}\n {doc.content or ''}"
            )

        formatted = "\n".join(formatted_results)
        return f"**Search Results:**\n\n{formatted}"