---
alwaysApply: true
---
# Rules for Narada Development
You are an AI coding assistant specialized in helping developers build sophisticated web automation workflows and custom agents using the Narada Python SDK. Narada enables intelligent browser automation through AI agents, precise UI interactions, and seamless integrations with external services like Google Sheets.
## Overview and Getting Started
Narada provides a browser window interface that combines AI-powered automation with deterministic controls. Here's a typical workflow pattern:
```python
# Sample starter code, please replace with your own code.
from narada import Agent, LocalBrowserWindow
from pydantic import BaseModel
# Schemas used for structured output below.
class PaperInfo(BaseModel):
title: str
url: str
class Papers(BaseModel):
papers: list[PaperInfo]
# Target the current browser window.
window = LocalBrowserWindow()
# Open a new tab with the given initial URL.
# IMPORTANT: Always use new_tab=True for the first go_to_url call to ensure the workflow runs in a new tab, preventing the current tab (which executes the workflow) from being closed.
await window.go_to_url(url="https://arxiv.org/list/cs.AI/recent", new_tab=True)
# Ask the Generalist agent to extract some information using a specific schema.
resp = await window.agent(
prompt="What are the top 3 AI papers based on the current page?",
agent=Agent.GENERALIST,
output_schema=Papers,
)
papers = resp.structured_output
print("Top 3 AI papers:", papers.model_dump_json(indent=2))
# For each paper we extracted in the previous step, navigate to its arXiv page
# and ask the Operator agent to download its PDF.
for paper in papers.papers:
await window.go_to_url(url=paper.url)
await window.agent(prompt="Click 'View PDF' then download the PDF")
# Print a message in the extension side panel chat.
await window.print_message(message="All done!")
```
### Script Structure and Imports
<Note>
**Remember: Always read the relevant `@Narada` documentation first before writing any code to ensure you have the latest method signatures and examples.**
</Note>
**Always structure your Narada scripts with proper async context management:**
```python
import asyncio
from narada import Narada, Agent # Add other imports as needed
async def main():
async with Narada() as narada:
window = await narada.open_and_initialize_browser_window()
# Your automation code here
if __name__ == "__main__":
asyncio.run(main())
```
## Documentation Access
When the user provides `@Narada` documentation access, you have comprehensive reference materials available including:
- **API Reference** (`api-reference/`): Detailed method signatures, parameters, and examples for each SDK method
- **Development Guides** (`documentation/`): Best practices, patterns, and advanced techniques
Each API reference page contains `#method-signature`, `#parameters`, `#response`, and `#examples` sections with practical implementation patterns.
### Documentation Directory Structure
```
/api-docs/
├── api-reference/ # Python SDK Method Documentation
│ ├── agent.mdx # Core agent execution method
│ ├── agentic-selector.mdx # UI element interaction method
│ ├── go-to-url.mdx # Navigation and page management
│ ├── print-message.mdx # Side panel messaging
│ ├── read-google-sheet.mdx # Google Sheets read operations
│ ├── write-google-sheet.mdx # Google Sheets write operations
│ ├── remote-dispatch.mdx # Remote task execution
│ └── get-task-status.mdx # Task monitoring
├── documentation/ # Development Guides & Best Practices
│ ├── remote-browser-control.mdx # Remote browser setup
│ ├── input-variables.mdx # Dynamic input handling
│ ├── parallel-execution.mdx # Concurrent workflows
│ ├── error-handling.mdx # Error management strategies
│ ├── screenshots.mdx # Visual debugging
│ ├── json-schema.mdx # Structured output validation
│ └── cursor-integration.mdx # This file - Cursor IDE integration
└── docs.json # Navigation configuration
```
**MANDATORY: Before writing ANY Narada code, you MUST first read the relevant documentation to get the most up-to-date information about the SDK.**
The Narada SDK evolves rapidly, and the documentation contains the latest method signatures, parameters, examples, and best practices. Without reading the docs first, you risk providing outdated or incorrect information.
## Core Agent Method
The `agent` method provides a modern, streamlined interface for executing automation tasks in the Narada Python SDK. It returns a simplified `AgentResponse` object with cleaner error handling and better type safety compared to the legacy `dispatch_request` method.
The `agent` method is the heart of Narada - it executes AI-powered tasks with flexible options:
```python
from narada import Agent
# Basic agent call
resp = await window.agent(prompt="Extract the main heading from this page")
# With structured output for reliable data extraction
resp = await window.agent(
prompt="Find all product names and prices",
agent=Agent.GENERALIST,
output_schema=ProductList,
clear_chat=True
)
```
Key parameters include `agent` selection (`Agent.GENERALIST`), `output_schema` for structured data, `clear_chat` for conversation control, `timeout` for complex pages, and `attachment` for file processing.
> **Tip**: With `@Narada` docs enabled, find detailed examples and all parameters in `api-reference/agent.mdx` under `#method-signature`, `#parameters`, and `#examples`.
## Navigation and Page Management
The `go_to_url` method provides a simple, reliable way to navigate browser windows to specific URLs programmatically. Use this method to set up automation workflows that need to start from specific web pages or navigate between different sites during task execution.
Use `go_to_url` to navigate before agent actions, ensuring correct context:
```python
# Always use new_tab=True for the first navigation
await window.go_to_url(url="https://example.com", new_tab=True)
# Navigate to different pages in the same tab
await window.go_to_url(url="https://example.com/products")
```
> **Tip**: See `api-reference/go-to-url.mdx` for navigation patterns and parameters.
## Precise UI Interactions
The `agentic_selector` method attempts to perform actions on web elements using traditional CSS selectors first. If the selectors don't produce a unique element, it falls back to using the Operator agent to perform the action intelligently.
For deterministic clicks and form interactions, use `agentic_selector` with robust selectors and fallback handling:
```python
await window.agentic_selector(
action={"type": "click"},
selectors={"aria_label": "Search"},
fallback_operator_query="click the search button in the header"
)
await window.agentic_selector(
action={"type": "type", "text": "machine learning"},
selectors={"placeholder": "Enter search term"},
fallback_operator_query="type 'machine learning' in the search input field"
)
```
Prefer resilient selectors (ARIA attributes, data-testid) and keep fallback queries instruction-like.
> **Tip**: Find selector strategies and examples in `api-reference/agentic-selector.mdx`.
## Structured Data Extraction
Use Pydantic models with `output_schema` for reliable data extraction:
```python
from pydantic import BaseModel, Field
class CompanyInfo(BaseModel):
name: str
valuation: str
industry: str
resp = await window.agent(
prompt="Extract company information from this page",
output_schema=CompanyInfo
)
company = resp.structured_output
assert company is not None # Always validate structured output
```
Keep models minimal and flat. For lists, use container models (e.g., `Companies` containing `list[CompanyInfo]`).
> **Tip**: Reference `api-reference/agent.mdx` and `documentation/json-schema.mdx` for schema patterns and validation.
## File Handling and Attachments
Upload files for processing without embedding large content in prompts:
```python
with open("financial_report.pdf", "rb") as f:
file = await window.upload_file(file=f)
resp = await window.agent(
prompt="Summarize the key financial metrics from this report",
attachment=file
)
```
Files are temporary (24-hour expiry) and scoped to the uploader. Use `generate_gif=True` for visual debugging.
## Google Sheets Integration
The `read_google_sheet` method reads data from a specified range of cells in a Google Sheet, while the `write_google_sheet` method writes data to a specified range of cells in a Google Sheet. Both methods require that the user has the appropriate Google Sheets permissions configured in their Narada extension.
Read from and write to Google Sheets using A1 notation:
```python
# Read data
companies = await window.read_google_sheet(
spreadsheet_id="your_sheet_id",
range="Companies!A1:C10"
)
# Process and write results
results = []
for company in companies:
# ... process each company
results.append([company.name, company.valuation, company.status])
await window.write_google_sheet(
spreadsheet_id="your_sheet_id",
range="Results!A1:C5",
values=results
)
```
> **Tip**: See `api-reference/read-google-sheet.mdx` and `api-reference/write-google-sheet.mdx` for authentication and range patterns.
## Progress Tracking and Observability
The `print_message` method displays custom messages in the Narada extension's side panel chat. This is different from Python's regular `print()` function - use this method when you want to show messages to end users viewing the chat or inject messages into the chat history for agents to read later.
Use `print_message` for progress updates and debugging:
```python
await window.print_message(message="Starting data extraction...")
# ... perform work
await window.print_message(message=f"Processed {len(results)} companies")
```
Combine with `generate_gif=True` on agent calls for visual audit trails.
> **Tip**: Find messaging patterns in `api-reference/print-message.mdx`.
## Error Handling and Reliability
Handle timeouts and errors gracefully:
```python
from narada import NaradaTimeoutError, NaradaError
try:
resp = await window.agent(
prompt="Complex task on slow page",
timeout=60000 # 60 seconds
)
except NaradaTimeoutError:
# Retry with longer timeout or simpler approach
resp = await window.agent(prompt="Simpler fallback task")
```
Decompose complex workflows into smaller, retryable steps.
> **Tip**: Reference `documentation/error-handling.mdx` for comprehensive error strategies.
## Parallel Execution
For throughput, run multiple agents concurrently:
```python
async def analyze_company(company_url: str):
window = await narada.open_and_initialize_browser_window()
await window.go_to_url(url=company_url, new_tab=True)
return await window.agent(prompt="Extract company valuation data")
# Process multiple companies in parallel
results = await asyncio.gather(*[
analyze_company(url) for url in company_urls
])
```
> **Tip**: See `documentation/parallel-execution.mdx` for advanced concurrency patterns.
## Conversation Management
Control agent context strategically:
```python
# Start fresh conversation
resp = await window.agent(prompt="What's on this page?", clear_chat=True)
# Continue conversation with context
resp = await window.agent(prompt="Focus on the pricing section", clear_chat=False)
```
Use `clear_chat=True` for independent tasks, `clear_chat=False` for multi-step workflows.
## Complex Workflow Examples
**Company Research Pipeline:**
```python
import asyncio
from narada import Narada, Agent
from pydantic import BaseModel, Field
# Schema for extracting valuation from a page
class ValuationInfo(BaseModel):
"""Valuation information for a company."""
valuation: str = Field(description="Example: $1.5 trillion USD")
async def main():
async with Narada() as narada:
window = await narada.open_and_initialize_browser_window()
# Here we are using a publicly readable Google Sheet, but you can use
# any Google Sheet that your Google account has access to.
SPREADSHEET_ID = "1aPe-AV6iyd-S__4EmctymfKVf0AD_He_Kwz1yQTDhiQ"
RANGE = "Sheet1!A2:A6"
# Step 1: Read companies from the Google Sheet.
sheet_data = await window.read_google_sheet(
spreadsheet_id=SPREADSHEET_ID,
range=RANGE,
)
company_names = [row[0] for row in sheet_data.values]
results = []
# Open a new tab at the start.
await window.go_to_url(url="https://www.google.com", new_tab=True)
# Step 2: For each company, search for its valuation.
for company_name in company_names:
# Search the company valuation on Google.
await window.go_to_url(
url=f"https://www.google.com/search?q={company_name}+company+valuation",
)
# Extract valuation from the search results page.
resp = await window.agent(
prompt=f"Extract the most recent valuation for {company_name} on this page",
agent=Agent.GENERALIST,
output_schema=ValuationInfo
)
valuation = resp.structured_output.valuation
results.append({"company": company_name, "valuation": valuation})
# Prints a message in the Narada chat.
await window.print_message(message=f"Company valuations: {results}")
# Prints a message in the console below.
print("Company valuations:", results)
if __name__ == "__main__":
asyncio.run(main())
```
**Academic Paper Download Workflow:**
```python
import asyncio
from narada import Narada, Agent
from pydantic import BaseModel
class PaperInfo(BaseModel):
title: str
arxiv_url: str
class PaperList(BaseModel):
papers: list[PaperInfo]
async def main():
async with Narada() as narada:
window = await narada.open_and_initialize_browser_window()
# Search and download papers
await window.go_to_url(url="https://scholar.google.com", new_tab=True)
await window.agent(prompt="Search for recent machine learning papers", agent=Agent.GENERALIST)
papers = await window.agent(
prompt="Extract top 5 paper titles and their arXiv links",
output_schema=PaperList
)
for paper in papers.papers:
await window.go_to_url(url=paper.arxiv_url)
await window.agent(prompt="Download the PDF of this paper")
await window.print_message(message=f"Downloaded: {paper.title}")
if __name__ == "__main__":
asyncio.run(main())
```
## Final Reminders for Narada Development
### 1. Always Search the Narada Documentation First
- **Read relevant files, images, or URLs** from the Narada documentation.
- **Search for specific methods** you plan to use (e.g., `agent method`, `go_to_url method`)
- **Review method signatures, parameters, and examples** to ensure you have the latest information
- **Never write code without first consulting the documentation**
### 2. Think and Plan Your Approach
- **Use thinking mode** to evaluate alternatives thoroughly:
- "think" - Basic thinking mode
- "think hard" - Extended thinking for complex problems
- "think harder" - Deep analysis for challenging tasks
- "ultrathink" - Maximum thinking budget for the most complex problems
- **Make a clear plan** for how to approach the specific problem
- **Consider different strategies** and choose the best approach
- **Break down complex workflows** into manageable steps
### 3. **Implement your solution in code** following the planned approach
**Remember: Documentation → Think → Implement**