nischaypar commited on
Commit
0b10ccb
Β·
1 Parent(s): 4e10e1e

update app

Browse files
Files changed (4) hide show
  1. README.md +82 -0
  2. app.py +61 -26
  3. requirements.txt +1 -1
  4. tool.py +25 -24
README.md CHANGED
@@ -12,4 +12,86 @@ tags:
12
  - tool
13
  ---
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
12
  - tool
13
  ---
14
 
15
+ # πŸ” Linkup Web Search Tool
16
+
17
+ The **Linkup Search Tool** is a [SmolAgents](https://github.com/huggingface/smolagents)–compatible tool that allows agents to search the public and premium web in real-time using the [Linkup API](https://linkup.so).
18
+
19
+ Powered by advanced depth-aware search logic (`standard` vs `deep`), this tool is ideal for retrieving up-to-date insights, articles, and structured search summaries β€” all within your SmolAgents or Python workflows.
20
+
21
+ ---
22
+
23
+ ## πŸš€ Features
24
+
25
+ - 🌐 **Web-wide, real-time search** via Linkup API
26
+ - 🧠 Supports **depth-aware querying** (`standard` or `deep`)
27
+ - πŸ€– Compatible with `smolagents.CodeAgent` and manual usage
28
+
29
+ ---
30
+
31
+ ## πŸ“¦ Installation
32
+
33
+ ```bash
34
+ pip install linkup-sdk smolagents
35
+ ```
36
+
37
+ You’ll also need a [Linkup API key](https://linkup.so) to use the tool. You get $5 credits on signing up to try it out.
38
+
39
+ ---
40
+
41
+ ## πŸ”‘ Setup API Key
42
+
43
+ You can provide the API key:
44
+ - At runtime
45
+ - Or by setting the environment variable:
46
+
47
+ ```bash
48
+ export LINKUP_API_KEY="your-linkup-api-key"
49
+ ```
50
+
51
+ You **must** however pass the `linkup_api_key` as a parameter in the space plug-and-play.
52
+ This ensures safe and personalized access to your Linkup account in public environments.
53
+
54
+ ---
55
+
56
+ ## 🧠 Usage with SmolAgents
57
+
58
+ ```python
59
+ from smolagents import load_tool
60
+
61
+ tool = load_tool("Linkup-Platform/linkup-search-tool", trust_remote_code=True)
62
+
63
+ tool.forward(
64
+ query="What are the latest trends in generative AI?",
65
+ depth="deep",
66
+ )
67
+ ```
68
+ ---
69
+
70
+ ## 🎯 When to Use `standard` vs `deep`
71
+
72
+ | Mode | Best For |
73
+ |------------|-----------------------------------------------|
74
+ | `standard` | Quick factual lookups, direct answers |
75
+ | `deep` | Complex topics, analysis, multiple perspectives, latest news |
76
+
77
+ ---
78
+
79
+ ## πŸ’¬ Example Result (truncated)
80
+
81
+ ```markdown
82
+ **Search Results:**
83
+
84
+ 1. **The State of Generative AI 2024**
85
+ URL: https://venturebeat.com/generative-ai-2024
86
+ Generative AI is reshaping industries, with key players like OpenAI, Anthropic, and Google DeepMind...
87
+
88
+ 2. **AI Trends: What's Coming Next?**
89
+ URL: https://techcrunch.com/ai-trends-2024
90
+ This year we’ll see more foundation model APIs, compliance tooling, and multi-modal agents...
91
+ ```
92
+
93
+ ---
94
+
95
+ For questions or API access, visit [linkup.so](https://linkup.so).
96
+
97
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py CHANGED
@@ -1,39 +1,74 @@
1
  import gradio as gr
2
- from tool import LinkupSearchTool # Assuming this is your tool class
3
 
4
  def run_search(query, depth, api_key):
5
- if not query or not depth or not api_key:
6
  return "❌ All fields are required."
7
-
8
  try:
9
- # Initialize tool ONLY when we have the API key
10
- tool = LinkupSearchTool(linkup_api_key=api_key) # Pass API key to constructor
11
  return tool.forward(query=query, depth=depth)
12
  except Exception as e:
13
  return f"❌ Error: {str(e)}"
14
 
15
- with gr.Blocks() as demo:
16
- gr.Markdown("## πŸ” Linkup Web Search Tool")
17
-
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  with gr.Row():
19
- query_input = gr.Textbox(label="Search Query", placeholder="e.g. AI trends in 2024")
20
- depth_input = gr.Dropdown(label="Search Depth", choices=["standard", "deep"], value="standard")
21
- api_key_input = gr.Textbox(label="Linkup API Key", type="password")
22
-
23
- output = gr.Markdown()
24
- btn = gr.Button("Search", interactive=True)
25
-
26
- btn.click(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  fn=run_search,
28
  inputs=[query_input, depth_input, api_key_input],
29
- outputs=output
 
30
  )
31
-
32
- def enable_submit(q, d, k):
33
- return gr.Button.update(interactive=bool(q.strip() and d and k.strip()))
34
-
35
- query_input.change(enable_submit, [query_input, depth_input, api_key_input], [btn])
36
- depth_input.change(enable_submit, [query_input, depth_input, api_key_input], [btn])
37
- api_key_input.change(enable_submit, [query_input, depth_input, api_key_input], [btn])
38
-
39
- demo.launch()
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ from tool import LinkupSearchTool
3
 
4
  def run_search(query, depth, api_key):
5
+ if not query.strip() or not depth or not api_key.strip():
6
  return "❌ All fields are required."
7
+
8
  try:
9
+ tool = LinkupSearchTool(linkup_api_key=api_key)
 
10
  return tool.forward(query=query, depth=depth)
11
  except Exception as e:
12
  return f"❌ Error: {str(e)}"
13
 
14
+ def enable_submit(q, d, k):
15
+ return gr.Button.update(interactive=bool(q.strip() and d and k.strip()))
16
+
17
+ with gr.Blocks(title="Linkup Web Search Tool") as demo:
18
+ gr.Markdown(
19
+ """
20
+ # πŸ” Linkup Web Search Tool
21
+ Perform real-time web search using [Linkup API](https://linkup.so).
22
+
23
+ 🧠 Supports `standard` and `deep` query depth.
24
+ πŸ” Requires your personal Linkup API key.
25
+ πŸ’‘ Ideal for facts, trends, research, and real-time data discovery.
26
+ """,
27
+ elem_id="header",
28
+ )
29
+
30
  with gr.Row():
31
+ query_input = gr.Textbox(
32
+ label="Search Query",
33
+ placeholder="e.g. AI trends in 2024",
34
+ lines=1,
35
+ )
36
+ depth_input = gr.Dropdown(
37
+ label="Search Depth",
38
+ choices=["standard", "deep"],
39
+ value="standard",
40
+ allow_custom_value=False,
41
+ )
42
+ api_key_input = gr.Textbox(
43
+ label="Linkup API Key",
44
+ placeholder="Paste your Linkup API key here",
45
+ type="password",
46
+ )
47
+
48
+ search_btn = gr.Button("πŸ” Search", interactive=False)
49
+ output = gr.Markdown("πŸ’¬ *Enter a query and click Search to begin.*", elem_id="output")
50
+
51
+ # Loading spinner and search button connection
52
+ search_btn.click(
53
  fn=run_search,
54
  inputs=[query_input, depth_input, api_key_input],
55
+ outputs=output,
56
+ show_progress=True,
57
  )
58
+
59
+ # Dynamic form validation
60
+ query_input.input(enable_submit, [query_input, depth_input, api_key_input], [search_btn])
61
+ depth_input.input(enable_submit, [query_input, depth_input, api_key_input], [search_btn])
62
+ api_key_input.input(enable_submit, [query_input, depth_input, api_key_input], [search_btn])
63
+
64
+ # Footer
65
+ gr.Markdown(
66
+ """
67
+ ---
68
+ βœ… Built with [SmolAgents](https://github.com/huggingface/smolagents) + [Gradio](https://gradio.app)
69
+ πŸ”— Powered by [Linkup](https://linkup.so)
70
+ """,
71
+ elem_id="footer",
72
+ )
73
+
74
+ demo.launch()
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- linkup-sdk
2
  smolagents
3
  gradio
 
1
+ linkup-sdk==0.2.4
2
  smolagents
3
  gradio
tool.py CHANGED
@@ -1,33 +1,37 @@
1
- from typing import Any, Literal, Optional
 
2
  from smolagents.tools import Tool
3
 
4
  class LinkupSearchTool(Tool):
5
  """LinkupSearchTool tool.
6
 
7
- LinkupSearchTool performs web search queries using the Linkup API, which includes results from both
8
- public and premium web sources. It supports two modes of search depth β€” standard and deep β€” allowing
9
- for flexible information retrieval depending on the complexity of the query.
 
 
 
 
 
10
 
11
- Setup:
12
- Make sure your Linkup API key is exported to the environment:
13
 
14
- .. code-block:: bash
 
15
 
16
- pip install linkup-sdk
17
- export LINKUP_API_KEY="your-api-key"
18
 
19
- Example:
20
- from smolagents import load_tool, CodeAgent, InferenceClientModel
 
 
 
21
 
22
- agent = CodeAgent(
23
- tools=[LinkupSearchTool()],
24
- model=InferenceClientModel(),
25
- )
26
- agent.run(query="What was Microsoft's revenue last quarter and was it well perceived by the market?", depth="deep")
27
 
28
- Args:
29
- linkup_api_key (str | None): Optional. If not provided, LinkupClient will check the LINKUP_API_KEY env variable.
30
- """
31
  name = "search_web"
32
  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."
33
  output_type = "string"
@@ -40,7 +44,7 @@ Args:
40
  "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.",
41
  },
42
  }
43
-
44
  def __init__(self, linkup_api_key: str | None = None, **kwargs) -> None:
45
  super().__init__()
46
  try:
@@ -52,10 +56,7 @@ Args:
52
 
53
  self.client = LinkupClient(api_key=linkup_api_key)
54
 
55
- def forward(self, query: str, depth: str) -> str:
56
-
57
- if depth not in ["standard", "deep"]:
58
- raise ValueError("depth must be 'standard' or 'deep'")
59
 
60
  try:
61
  response = self.client.search(
 
1
+ from typing import Literal
2
+
3
  from smolagents.tools import Tool
4
 
5
  class LinkupSearchTool(Tool):
6
  """LinkupSearchTool tool.
7
 
8
+ LinkupSearchTool performs web search queries using the Linkup API, which includes results from both
9
+ public and premium web sources. It supports two modes of search depth β€” standard and deep β€” allowing
10
+ for flexible information retrieval depending on the complexity of the query.
11
+
12
+ Setup:
13
+ Make sure your Linkup API key is exported to the environment:
14
+
15
+ .. code-block:: bash
16
 
17
+ pip install linkup-sdk
18
+ export LINKUP_API_KEY="your-api-key"
19
 
20
+ Example:
21
+ from smolagents import load_tool, CodeAgent, InferenceClientModel
22
 
23
+ linkup_tool = load_tool("Linkup-Platform/linkup-search-tool", trust_remote_code=True)
 
24
 
25
+ agent = CodeAgent(
26
+ tools=[linkup_tool()],
27
+ model=InferenceClientModel(),
28
+ )
29
+ agent.run(query="What was Microsoft's revenue last quarter and was it well perceived by the market?", depth="deep")
30
 
31
+ Args:
32
+ linkup_api_key (str | None): Optional. If not provided, LinkupClient will check the LINKUP_API_KEY env variable.
33
+ """
 
 
34
 
 
 
 
35
  name = "search_web"
36
  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."
37
  output_type = "string"
 
44
  "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.",
45
  },
46
  }
47
+
48
  def __init__(self, linkup_api_key: str | None = None, **kwargs) -> None:
49
  super().__init__()
50
  try:
 
56
 
57
  self.client = LinkupClient(api_key=linkup_api_key)
58
 
59
+ def forward(self, query: str, depth: Literal["standard", "deep"]) -> str:
 
 
 
60
 
61
  try:
62
  response = self.client.search(