SpecStream commited on
Commit
ab6600f
·
verified ·
1 Parent(s): 35ddeeb

Upload SpecStream tool

Browse files
Files changed (4) hide show
  1. README.md +7 -5
  2. index.html +1 -19
  3. requirements.txt +1 -0
  4. tool.py +66 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Specstream Get Rows
3
- emoji: 🏢
4
- colorFrom: blue
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ title: SpecStream get rows
 
 
 
3
  sdk: static
4
  pinned: false
5
+ tags:
6
+ - smolagents
7
+ - tool
8
  ---
9
 
10
+ SpecStream reads the live web and hands back every match with its source, so an agent can ask for data no one sells in plain words. Tool one shows the reading and the maximum price, and runs only after the person approves that maximum. Tool two reads the rows with their source URLs. Set SPECSTREAM_API_KEY. Start at https://specstream.ai/?utm_source=smolagents
11
+
12
+ Load it with `Tool.from_hub("SpecStreamAI/specstream-get-rows", 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 get rows</title></head><body style="font-family:system-ui;max-width:40rem;margin:3rem auto;padding:0 1rem"><h1>SpecStream get rows</h1><p>SpecStream reads the live web and hands back every match with its source, so an agent can ask for data no one sells in plain words. Tool one shows the reading and the maximum price, and runs only after the person approves that maximum. Tool two reads the rows with their source URLs. Set SPECSTREAM_API_KEY. Start at https://specstream.ai/?utm_source=smolagents</p><p><code>Tool.from_hub("SpecStreamAI/specstream-get-rows", trust_remote_code=True)</code></p></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ smolagents
tool.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Optional
2
+ from smolagents.tools import Tool
3
+ import json
4
+ import urllib
5
+ import os
6
+
7
+ class SpecStreamGetRows(Tool):
8
+ name = "specstream_get_rows"
9
+ description = "Reads the results of a SpecStream run by find_id, each value with the URL of the page it came from. Also says whether the run is still going. Reading costs nothing. Needs SPECSTREAM_API_KEY."
10
+ inputs = {'find_id': {'type': 'string', 'description': 'The find_id returned by specstream_find_web_data.'}, 'limit': {'type': 'integer', 'description': 'How many rows to read, 1 to 100. Default 25.', 'nullable': True}, 'cursor': {'type': 'string', 'description': 'The next_cursor from a previous call, to read the next page.', 'nullable': True}}
11
+ output_type = "string"
12
+
13
+ def forward(self, find_id: str, limit: int | None = None, cursor: str | None = None) -> str:
14
+ import json
15
+ import os
16
+ from urllib.error import HTTPError, URLError
17
+ from urllib.parse import quote as urlquote, 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
+ base = os.environ.get("SPECSTREAM_API_BASE", "https://api.specstream.ai").rstrip("/")
24
+ size = 25 if limit is None else max(1, min(int(limit), 100))
25
+ query = {"limit": str(size)}
26
+ if cursor:
27
+ query["cursor"] = cursor
28
+ path = "/v1/finds/%s/rows?%s" % (urlquote(find_id, safe=""), urlencode(query))
29
+ req = Request(
30
+ base + path,
31
+ headers={
32
+ "Authorization": "Bearer " + key,
33
+ "Accept": "application/json",
34
+ "User-Agent": "specstream-smolagents/0.1",
35
+ },
36
+ )
37
+ try:
38
+ with urlopen(req, timeout=120) as resp:
39
+ payload = json.loads(resp.read().decode("utf-8"))
40
+ except HTTPError as exc:
41
+ return "SpecStream answered HTTP %d for that find_id." % exc.code
42
+ except (URLError, OSError):
43
+ return "SpecStream could not be reached."
44
+ page = payload.get("data") if isinstance(payload, dict) else None
45
+ if not isinstance(page, dict):
46
+ return "SpecStream returned no rows page."
47
+ rows = page.get("rows") or []
48
+ lines = ["status: %s, accepted rows: %s" % (page.get("status"), page.get("accepted_count"))]
49
+ for number, row in enumerate(rows, 1):
50
+ parts = []
51
+ for cell in row.get("cells") or []:
52
+ shown = cell.get("display")
53
+ if shown in (None, ""):
54
+ continue
55
+ source = (cell.get("provenance") or {}).get("source_url")
56
+ parts.append("%s: %s%s" % (cell.get("label"), shown, " (source: %s)" % source if source else ""))
57
+ lines.append("%d. %s" % (number, "; ".join(parts)))
58
+ if not rows:
59
+ lines.append("No rows yet. If the status is still running, call again in a minute.")
60
+ cursor_next = page.get("next_cursor")
61
+ if cursor_next:
62
+ lines.append("next_cursor: %s" % cursor_next)
63
+ return "\n".join(lines)
64
+
65
+ def __init__(self, *args, **kwargs):
66
+ self.is_initialized = False