spectrawl 0.3.11 → 0.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The unified web layer for AI agents. Search, browse, authenticate, and act on platforms — one tool, self-hosted, free.
4
4
 
5
- **Free Tavily alternative** with Google-quality results via Gemini Grounded Search.
5
+ **5,000 free searches/month** with Google-quality results via Gemini Grounded Search. Better answers than Tavily. Self-hosted.
6
6
 
7
7
  ## What It Does
8
8
 
@@ -57,18 +57,23 @@ export GEMINI_API_KEY=your-free-key # Get one at aistudio.google.com
57
57
  const { Spectrawl } = require('spectrawl')
58
58
  const web = new Spectrawl()
59
59
 
60
- // Deep search — like Tavily but free, with better answers
60
+ // Deep search — returns sources for your agent/LLM to process
61
61
  const result = await web.deepSearch('how to build an MCP server in Node.js')
62
- console.log(result.answer) // AI-generated answer with [1] [2] citations
63
62
  console.log(result.sources) // [{ title, url, content, score }]
64
63
 
64
+ // With AI summary (opt-in — uses extra Gemini call)
65
+ const withAnswer = await web.deepSearch('query', { summarize: true })
66
+ console.log(withAnswer.answer) // AI-generated answer with [1] [2] citations
67
+
65
68
  // Fast mode — snippets only, skip scraping
66
69
  const fast = await web.deepSearch('query', { mode: 'fast' })
67
70
 
68
- // Basic search — raw results, no AI
71
+ // Basic search — raw results
69
72
  const basic = await web.search('query')
70
73
  ```
71
74
 
75
+ > **Why no summary by default?** Your agent already has an LLM. If we summarize AND your agent summarizes, you're paying two LLMs for one answer. We return rich sources — your agent does the rest.
76
+
72
77
  ## vs Tavily
73
78
 
74
79
  | | Tavily | Spectrawl |
@@ -77,7 +82,7 @@ const basic = await web.search('query')
77
82
  | Answer quality | Generic (3 items) | **Detailed** (12+ items) ✅ |
78
83
  | Inline citations | ❌ | **[1] [2] [3]** ✅ |
79
84
  | Results per query | 10 | **12-19** ✅ |
80
- | Cost | $0.01/query | **Free** ✅ |
85
+ | Cost | $0.01/query | **Free** (5K/mo) ✅ |
81
86
  | Self-hosted | No | **Yes** ✅ |
82
87
  | Source ranking | No | **Domain trust scoring** ✅ |
83
88
  | Stealth scraping | No | **Yes** ✅ |
@@ -110,7 +115,7 @@ Query → Gemini Grounded + DDG (parallel)
110
115
  → Merge & deduplicate (12-19 results)
111
116
  → Source quality ranking (boost GitHub/SO/Reddit, penalize SEO spam)
112
117
  → Parallel scraping (Jina → readability → Playwright fallback)
113
- AI summarization with [1] [2] citations (gemini-2.5-flash)
118
+ Returns sources to your agent (AI summary opt-in with summarize: true)
114
119
  ```
115
120
 
116
121
  ### What you get without any keys
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spectrawl",
3
- "version": "0.3.11",
3
+ "version": "0.3.12",
4
4
  "description": "The unified web layer for AI agents. Search (6 engines), stealth browse (Camoufox + Playwright), auth (cookies, multi-account), act (24 adapters, 30+ platforms), proxy rotation. Self-hosted, free.",
5
5
  "main": "src/index.js",
6
6
  "types": "index.d.ts",
@@ -188,16 +188,18 @@ class SearchEngine {
188
188
  }
189
189
  }
190
190
 
191
- // Step 6: Summarize with citations
191
+ // Step 6: Summarize with citations (opt-in — most agents have their own LLM)
192
192
  let answer = null
193
- const summarizer = this.summarizer || (this.reranker ? new Summarizer({
194
- provider: 'gemini',
195
- model: 'gemini-2.5-flash',
196
- apiKey: process.env.GEMINI_API_KEY
197
- }) : null)
193
+ if (opts.summarize === true) {
194
+ const summarizer = this.summarizer || (process.env.GEMINI_API_KEY ? new Summarizer({
195
+ provider: 'gemini',
196
+ model: 'gemini-2.5-flash',
197
+ apiKey: process.env.GEMINI_API_KEY
198
+ }) : null)
198
199
 
199
- if (summarizer) {
200
- answer = await summarizer.summarize(query, results)
200
+ if (summarizer) {
201
+ answer = await summarizer.summarize(query, results)
202
+ }
201
203
  }
202
204
 
203
205
  const response = {