smartchats-tools
Shared helpers for the agent’s web tools: Serper web search and URL fetch
with Readability text extraction. The local server’s /tools/search and
/tools/fetchUrl routes and the matching cloud functions all call these.
The helpers take keys and options as arguments and return data. They read no environment variables and do no auth or billing. Each host adds those.
serperSearch
import { serperSearch, normalizeOrganic } from 'smartchats-tools';
const r = await serperSearch({ apiKey, query: 'surrealdb hnsw index', numResults: 5 });
r.organic; // Serper's organic results ({ title, link, snippet, ... })
r.costUsd; // credits × $0.001
const results = normalizeOrganic(r.organic); // SearchResult[]: { title, url, snippet, extra? }| Option | Notes |
|---|---|
apiKey | Serper key. Required |
query | Required, non-empty |
numResults | Default 10 |
signal | Optional abort |
The result (SerperSearchResult) has organic, optional knowledgeGraph
and answerBox, credits (1 when Serper doesn’t report it) and costUsd.
Other Serper fields are dropped.
A missing key, an empty query or a non-2xx response throws SerperError
(with status for HTTP errors). Network failures and aborts throw the
underlying error.
normalizeOrganic maps results to the SearchResult shape from
smartchats-backend, keeping unknown fields under extra.
extractReadableText
import { extractReadableText } from 'smartchats-tools';
const { title, text, htmlBytes, readabilitySucceeded } =
await extractReadableText('https://example.com/post', { maxChars: 20000 });| Option | Default | Notes |
|---|---|---|
maxChars | none | Text longer than this is cut and ends with [truncated] |
timeoutMs | 15000 | Fetch timeout. Ignored when signal is given |
userAgent | Mozilla/5.0 (compatible; SmartChats/1.0; +https://smartchats.ai) | |
signal | Replaces the timeout signal |
It fetches the page (following redirects), parses it with linkedom, adds a
<base href> so relative links resolve, and runs Mozilla Readability. When
Readability finds no article it falls back to the body text and
readabilitySucceeded is false. A page with no text returns empty strings
rather than throwing.
An empty URL, a non-2xx response, a network failure or a parse failure
throws ExtractError (status for HTTP errors, cause for the original
error).
See also
- smartchats-backend, whose
ToolsAPI(search,fetchUrl) these back - Source:
packages/smartchats-tools/src/index.ts