Files
pi-perplexity/README.md
T
2026-02-18 08:06:19 +00:00

132 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pi-perplexity
A [pi](https://github.com/nickarrow/pi-coding-agent) extension that provides web search via a Perplexity Pro/Max subscription. Uses your existing subscription — no API credits consumed.
## Installation
```bash
pi install pi-perplexity
```
## Usage
Once installed, the agent gains a `perplexity_search` tool it can call automatically when it needs to look something up. You can also trigger a search by asking the agent to search for something.
### Tool Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `query` | string | yes | Search query |
| `recency` | string | no | Filter by age: `hour`, `day`, `week`, `month`, `year` |
| `limit` | number | no | Max sources to return (150) |
### Slash Command
```
/perplexity-login # Authenticate and save token
/perplexity-login --force # Clear cached token and re-authenticate
```
## Authentication
The extension tries two auth methods in order:
1. **macOS Desktop App** (automatic) — Borrows the JWT from the Perplexity macOS app if installed and signed in. Zero interaction required.
2. **Email OTP** (interactive fallback) — Prompts for your Perplexity email, sends a one-time code, and prompts for the code.
The token is cached at `~/.config/pi-perplexity/auth.json` (permissions `0600`). On HTTP 401/403, the cached token is automatically cleared so the next search re-authenticates.
### Environment Variables
| Variable | Description |
|----------|-------------|
| `PI_AUTH_NO_BORROW=1` | Skip macOS desktop app token extraction |
| `PI_PERPLEXITY_EMAIL` | Email for OTP auth (skips interactive prompt) |
| `PI_PERPLEXITY_OTP` | OTP code for non-interactive auth |
## How It Works
The extension calls Perplexity's internal SSE endpoint (`perplexity_ask`) with your subscription credentials. Responses stream as incremental events that are merged into a final result containing an answer and sources.
All queries use `is_incognito: true` — nothing appears in your Perplexity search history.
### Output Format
The tool returns structured text the agent can reason over:
```
## Answer
<synthesized answer with inline citations>
## Sources
3 sources
[1] Example Article (2d ago)
https://example.com/article
Brief snippet of the source content...
[2] Another Source (5h ago)
https://example.com/other
Another snippet preview...
## Meta
Provider: perplexity (oauth)
Model: pplx_pro_upgraded
```
## Development
### Prerequisites
- [Bun](https://bun.sh) runtime
- pi coding agent (`@mariozechner/pi-coding-agent`)
### Commands
```bash
bun install # Install dev dependencies
bun test # Run tests (29 tests across 5 files)
bunx tsc --noEmit # Type check
```
### Project Structure
```
src/
index.ts # Extension entry — registers tool and commands
auth/
login.ts # macOS app extraction + email OTP flow
storage.ts # Token persistence (~/.config/pi-perplexity/auth.json)
commands/
login.ts # /perplexity-login slash command
search/
types.ts # Type definitions (StreamEvent, SearchResult, errors)
client.ts # HTTP POST to SSE endpoint, event merging, result extraction
stream.ts # SSE line parser + incremental event merging
format.ts # SearchResult → LLM-readable text output
render/
call.ts # TUI component for tool call display
result.ts # TUI component for tool result display
util.ts # Shared render utilities
```
### Zero Runtime Dependencies
This extension has **no npm dependencies**. Everything uses platform globals:
- `fetch` — HTTP requests
- `crypto.randomUUID()` — request IDs
- `ReadableStream` — SSE parsing
- `Intl.DateTimeFormat` — timezone detection
Only peer dependencies (`@sinclair/typebox`, `@mariozechner/pi-tui`, `@mariozechner/pi-ai`) are used, provided by pi at runtime.
## Requirements
- Perplexity **Pro** or **Max** subscription
- macOS (for desktop app token extraction) or interactive terminal (for email OTP)
## License
Private — not published.