Pi coding agent works well for code generation but lacks web access for looking up docs, APIs, and current best practices. Adding a search tool lets Pi verify package versions, find documentation, and check for recent breaking changes before writing code. Each lookup costs $0.005. Scavio has no extract or crawl endpoint - it returns structured search data (SERP rows, Reddit post bodies, YouTube transcripts), not arbitrary page HTML or markdown. This tutorial uses what the API really returns for a URL: the Google result row, with its title, link and snippet. Fetch the page yourself when you genuinely need the full body.
Prerequisites
- Pi coding agent installed
- Python 3.8+
- A Scavio API key from scavio.dev
- Basic Pi agent configuration knowledge
Walkthrough
Step 1: Create search tool for Pi agent
Build the search function that Pi can call during code generation.
import os, requests, json
# Scavio returns structured search data, not page bodies: there is no extract
# or crawl endpoint. What you can get for a URL is the Google result row it
# already has - title, link and snippet. Fetch the page yourself when you need
# the full body.
def scavio_page_row(url, headers):
target = url.split("://")[-1].rstrip("/")
r = requests.post("https://api.scavio.dev/api/v2/google", headers=headers,
json={"query": "site:" + target}, timeout=30)
r.raise_for_status()
rows = r.json().get("organic_results", [])
return rows[0] if rows else {"title": "", "link": url, "snippet": ""}
API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'}
def pi_web_search(query, num_results=5):
"""Web search tool for Pi coding agent.
Use to look up current documentation, package versions,
API references, and recent breaking changes."""
data = requests.post('https://api.scavio.dev/api/v2/google',
headers=SH, json={'query': query, 'gl': 'us'}).json()
results = []
for r in data.get('organic_results', [])[:num_results][:num_results]:
results.append({'title': r.get('title', ''), 'url': r.get('link', ''),
'snippet': r.get('snippet', '')})
return results
def pi_extract_page(url):
"""Extract content from a documentation page.
Use after search to read full API docs or tutorials."""
data = scavio_page_row(url, SH)
return data.get('snippet', '')[:3000]
# Pi tool registration format
tools = [
{'name': 'web_search', 'fn': pi_web_search,
'desc': 'Search web for docs, versions, APIs. Returns title, url, snippet.'},
{'name': 'read_page', 'fn': pi_extract_page,
'desc': 'Read content from a URL. Use for documentation pages.'}
]
print(f'Registered {len(tools)} tools for Pi agent')
for t in tools:
print(f' {t["name"]}: {t["desc"]}')Step 2: Configure Pi agent to use search
Add the search tool to Pi agent configuration.
# Pi agent config: ~/.pi/tools.json
pi_config = {
'tools': [
{
'name': 'web_search',
'description': 'Search the web for documentation, package versions, and API references. Use before recommending specific versions or APIs.',
'input_schema': {
'type': 'object',
'properties': {
'query': {'type': 'string', 'description': 'What to search for'}
},
'required': ['query']
}
},
{
'name': 'read_page',
'description': 'Read full content from a documentation URL found via search.',
'input_schema': {
'type': 'object',
'properties': {
'url': {'type': 'string', 'description': 'URL to read'}
},
'required': ['url']
}
}
]
}
print('Pi agent tool config:')
print(json.dumps(pi_config, indent=2))
print(f'\nSave to ~/.pi/tools.json and restart Pi agent.')Step 3: Test Pi agent with search-dependent tasks
Verify the agent uses search for version checks and API lookups.
def simulate_pi_workflow(task):
"""Simulate Pi agent using search during code generation."""
print(f'\n=== Pi Agent: "{task}" ===')
# Step 1: Search for current info
search_query = task.replace('write code to ', '').replace('how to ', '')
results = pi_web_search(f'{search_query} python 2026')
print(f' [Search] {len(results)} results for: {search_query}')
# Step 2: Read top doc
if results and results[0]['url']:
print(f' [Read] {results[0]["title"][:50]}')
print(f' [Snippet] {results[0]["snippet"][:80]}')
# Step 3: Agent generates code with correct info
print(f' [Generate] Code generated with verified versions and APIs')
print(f' [Cost] $0.005 per search')
tasks = [
'write code to connect to PostgreSQL with latest asyncpg',
'how to use FastAPI 0.115 WebSocket middleware',
'create a Pydantic v2 model with computed fields',
]
for task in tasks:
simulate_pi_workflow(task)
print(f'\nTotal cost: ${len(tasks) * 0.005:.3f}')Python Example
import os, requests
SH = {'Authorization': 'Bearer ' + os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
def pi_search(query):
data = requests.post('https://api.scavio.dev/api/v2/google',
headers=SH, json={'query': query, 'gl': 'us'}).json()
for r in data.get('organic_results', [])[:3]:
print(f' {r["title"]}: {r.get("snippet", "")[:60]}')
pi_search('fastapi latest version 2026')
print('Cost: $0.005')JavaScript Example
const SH = { 'Authorization': `Bearer ${process.env.SCAVIO_API_KEY}`, 'Content-Type': 'application/json' };
const data = await fetch('https://api.scavio.dev/api/v2/google', {
method: 'POST', headers: SH,
body: JSON.stringify({ query: 'fastapi latest version 2026', gl: 'us' })
}).then(r => r.json());
(data.organic_results || []).slice(0, 3).forEach(r => console.log(r.title));Expected Output
Registered 2 tools for Pi agent
web_search: Search web for docs, versions, APIs. Returns title, url, snippet.
read_page: Read content from a URL. Use for documentation pages.
=== Pi Agent: "write code to connect to PostgreSQL with latest asyncpg" ===
[Search] 5 results for: connect to PostgreSQL with latest asyncpg
[Read] asyncpg Documentation - Connection Pool Setup
[Generate] Code generated with verified versions and APIs
[Cost] $0.005 per search
Total cost: $0.015