Upload SpecStream tool
Browse files- README.md +7 -5
- index.html +1 -19
- requirements.txt +1 -0
- tool.py +50 -0
README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji: 💻
|
| 4 |
-
colorFrom: green
|
| 5 |
-
colorTo: red
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: SpecStream web search
|
|
|
|
|
|
|
|
|
|
| 3 |
sdk: static
|
| 4 |
pinned: false
|
| 5 |
+
tags:
|
| 6 |
+
- smolagents
|
| 7 |
+
- tool
|
| 8 |
---
|
| 9 |
|
| 10 |
+
SpecStream is the live web data engine for teams and agents. One platform to build, search, extract, enrich, map, and monitor data across the entire web. Four tools: `specstream_web_search` (`GET /v1/web-search`, $5 per 1,000 searches), `specstream_extract_pages` (`POST /v1/extract`, $0.80 per 1,000 pages), `specstream_find_web_data` (Deep Search, priced per row) and `specstream_get_rows`. Source URL and read time on every value. Set SPECSTREAM_API_KEY. Start at https://specstream.ai/?utm_source=smolagents
|
| 11 |
+
|
| 12 |
+
Load it with `Tool.from_hub("SpecStreamAI/specstream-web-search", trust_remote_code=True)`.
|
index.html
CHANGED
|
@@ -1,19 +1 @@
|
|
| 1 |
-
<!doctype html>
|
| 2 |
-
<html>
|
| 3 |
-
<head>
|
| 4 |
-
<meta charset="utf-8" />
|
| 5 |
-
<meta name="viewport" content="width=device-width" />
|
| 6 |
-
<title>My static Space</title>
|
| 7 |
-
<link rel="stylesheet" href="style.css" />
|
| 8 |
-
</head>
|
| 9 |
-
<body>
|
| 10 |
-
<div class="card">
|
| 11 |
-
<h1>Welcome to your static Space!</h1>
|
| 12 |
-
<p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
|
| 13 |
-
<p>
|
| 14 |
-
Also don't forget to check the
|
| 15 |
-
<a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
|
| 16 |
-
</p>
|
| 17 |
-
</div>
|
| 18 |
-
</body>
|
| 19 |
-
</html>
|
|
|
|
| 1 |
+
<!doctype html><html><head><meta charset="utf-8"><title>SpecStream web search</title></head><body style="font-family:system-ui;max-width:40rem;margin:3rem auto;padding:0 1rem"><h1>SpecStream web search</h1><p>SpecStream is the live web data engine for teams and agents. One platform to build, search, extract, enrich, map, and monitor data across the entire web. Four tools: `specstream_web_search` (`GET /v1/web-search`, $5 per 1,000 searches), `specstream_extract_pages` (`POST /v1/extract`, $0.80 per 1,000 pages), `specstream_find_web_data` (Deep Search, priced per row) and `specstream_get_rows`. Source URL and read time on every value. Set SPECSTREAM_API_KEY. Start at https://specstream.ai/?utm_source=smolagents</p><p><code>Tool.from_hub("SpecStreamAI/specstream-web-search", trust_remote_code=True)</code></p></body></html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
requirements.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
smolagents
|
tool.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any, Optional
|
| 2 |
+
from smolagents.tools import Tool
|
| 3 |
+
import os
|
| 4 |
+
import urllib
|
| 5 |
+
import json
|
| 6 |
+
|
| 7 |
+
class SpecStreamWebSearch(Tool):
|
| 8 |
+
name = "specstream_web_search"
|
| 9 |
+
description = "Searches the live web in seconds with the SpecStream Search API (GET /v1/web-search, $5 per 1,000 searches, no quote needed). Returns the answer with its source URL and read time, matching rows, ranked sources and optional page passages. Needs SPECSTREAM_API_KEY."
|
| 10 |
+
inputs = {'q': {'type': 'string', 'description': 'The search question or request in everyday words (1 to 2,000 characters).'}, 'passages': {'type': 'boolean', 'description': 'Set True to include the main text passages of the top matching pages.', 'nullable': True}}
|
| 11 |
+
output_type = "string"
|
| 12 |
+
|
| 13 |
+
def forward(self, q: str, passages: bool | None = None) -> str:
|
| 14 |
+
import json
|
| 15 |
+
import os
|
| 16 |
+
from urllib.error import HTTPError, URLError
|
| 17 |
+
from urllib.parse import urlencode
|
| 18 |
+
from urllib.request import Request, urlopen
|
| 19 |
+
|
| 20 |
+
key = os.environ.get("SPECSTREAM_API_KEY", "").strip()
|
| 21 |
+
if not key:
|
| 22 |
+
return "Set SPECSTREAM_API_KEY to a SpecStream API key (https://specstream.ai/workspace?utm_source=smolagents)."
|
| 23 |
+
query = (q or "").strip()
|
| 24 |
+
if not query or len(query) > 2000:
|
| 25 |
+
return "Provide a search query between 1 and 2,000 characters."
|
| 26 |
+
base = os.environ.get("SPECSTREAM_API_BASE", "https://api.specstream.ai").rstrip("/")
|
| 27 |
+
params = {"q": query}
|
| 28 |
+
if passages:
|
| 29 |
+
params["passages"] = "true"
|
| 30 |
+
req = Request(
|
| 31 |
+
base + "/v1/web-search?" + urlencode(params),
|
| 32 |
+
method="GET",
|
| 33 |
+
headers={
|
| 34 |
+
"Authorization": "Bearer " + key,
|
| 35 |
+
"Accept": "application/json",
|
| 36 |
+
"User-Agent": "specstream-smolagents/0.2",
|
| 37 |
+
},
|
| 38 |
+
)
|
| 39 |
+
try:
|
| 40 |
+
with urlopen(req, timeout=60) as resp:
|
| 41 |
+
payload = json.loads(resp.read().decode("utf-8"))
|
| 42 |
+
except HTTPError as exc:
|
| 43 |
+
return "SpecStream answered HTTP %d" % exc.code
|
| 44 |
+
except (URLError, OSError):
|
| 45 |
+
return "SpecStream could not be reached"
|
| 46 |
+
data = payload.get("data") if isinstance(payload, dict) else {}
|
| 47 |
+
return json.dumps(data, ensure_ascii=False)
|
| 48 |
+
|
| 49 |
+
def __init__(self, *args, **kwargs):
|
| 50 |
+
self.is_initialized = False
|