pplx-zero 1.1.7 → 1.1.8
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 +452 -60
- package/dist/index.js +106 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,102 +1,248 @@
|
|
|
1
1
|
# PPLX‑Zero
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Minimal setup, fast results, and practical flags for files, images, streaming, and batch workflows.
|
|
3
|
+
🚀 **Lightning-fast Perplexity AI in your terminal** — sub‑1s search responses with multimodal support. Built for developers, coding agents, and automation workflows that demand speed and reliability.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
- Ask, research, and stream answers instantly from the CLI with sensible defaults for rapid iteration.
|
|
8
|
-
- Summarize documents and analyze images using a single command with optional model control.
|
|
9
|
-
- Run batch jobs with concurrency and timeouts for agent pipelines and CI flows.
|
|
5
|
+
Perfect for rapid research, document analysis, image understanding, and batch processing with minimal configuration.
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ✨ What Makes PPLX‑Zero Special
|
|
10
|
+
|
|
11
|
+
- **⚡ Blazing Fast**: Get answers in under a second with optimized API calls
|
|
12
|
+
- **🧠 Smart Models**: Choose from Sonar, Sonar‑Pro, Sonar‑Reasoning, and Deep‑Research models
|
|
13
|
+
- **📎 Multimodal**: Analyze documents, images, and combinations seamlessly
|
|
14
|
+
- **🔄 Auto‑Update**: Stay current with simplified update management
|
|
15
|
+
- **⚙️ Developer‑First**: Built for CI/CD, agent pipelines, and programmatic use
|
|
16
|
+
- **🎯 Minimal Setup**: One environment variable and you're ready to go
|
|
17
|
+
|
|
18
|
+
## 📦 Installation
|
|
19
|
+
|
|
20
|
+
Choose the installation method that works best for you:
|
|
21
|
+
|
|
22
|
+
### 🚀 Quick Install (Recommended)
|
|
13
23
|
|
|
14
24
|
```bash
|
|
15
25
|
# npm or bun (global)
|
|
16
26
|
npm install -g pplx-zero
|
|
27
|
+
# or
|
|
28
|
+
bun install -g pplx-zero
|
|
29
|
+
|
|
30
|
+
# Verify installation
|
|
17
31
|
pplx --version
|
|
18
32
|
```
|
|
19
33
|
|
|
34
|
+
### 📦 Binary Download (No Node.js required)
|
|
20
35
|
|
|
21
|
-
|
|
36
|
+
```bash
|
|
37
|
+
# Download the appropriate binary for your platform
|
|
38
|
+
# Linux (x64) - Most servers and desktops
|
|
39
|
+
wget https://github.com/codewithkenzo/pplx-zero/releases/latest/download/pplx-v1.1.7-linux-x64
|
|
40
|
+
chmod +x pplx-v1.1.7-linux-x64
|
|
41
|
+
sudo mv pplx-v1.1.7-linux-x64 /usr/local/bin/pplx
|
|
42
|
+
|
|
43
|
+
# Linux (ARM64) - Raspberry Pi, ARM servers
|
|
44
|
+
wget https://github.com/codewithkenzo/pplx-zero/releases/latest/download/pplx-v1.1.7-linux-arm64
|
|
45
|
+
chmod +x pplx-v1.1.7-linux-arm64
|
|
46
|
+
sudo mv pplx-v1.1.7-linux-arm64 /usr/local/bin/pplx
|
|
47
|
+
|
|
48
|
+
# macOS (Intel) - Macs with Intel processors
|
|
49
|
+
wget https://github.com/codewithkenzo/pplx-zero/releases/latest/download/pplx-v1.1.7-darwin-x64
|
|
50
|
+
chmod +x pplx-v1.1.7-darwin-x64
|
|
51
|
+
sudo mv pplx-v1.1.7-darwin-x64 /usr/local/bin/pplx
|
|
52
|
+
|
|
53
|
+
# macOS (Apple Silicon) - Macs with M1/M2/M3 chips
|
|
54
|
+
wget https://github.com/codewithkenzo/pplx-zero/releases/latest/download/pplx-v1.1.7-darwin-arm64
|
|
55
|
+
chmod +x pplx-v1.1.7-darwin-arm64
|
|
56
|
+
sudo mv pplx-v1.1.7-darwin-arm64 /usr/local/bin/pplx
|
|
57
|
+
|
|
58
|
+
# Windows (x64) - Most Windows computers
|
|
59
|
+
# Download pplx-v1.1.7-windows-x64.exe from GitHub releases
|
|
60
|
+
# Add to your PATH or run directly
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Alternative Installation Script (Linux/macOS):**
|
|
22
64
|
|
|
23
65
|
```bash
|
|
24
|
-
#
|
|
66
|
+
# Automated installation script
|
|
67
|
+
curl -sSL https://github.com/codewithkenzo/pplx-zero/releases/latest/download/pplx-v1.1.7-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/x64/') -o pplx
|
|
68
|
+
chmod +x pplx
|
|
69
|
+
sudo mv pplx /usr/local/bin/pplx
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 🏛️ AUR (Arch Linux)
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Using yay (recommended)
|
|
25
76
|
yay -S pplx-zero
|
|
77
|
+
|
|
78
|
+
# Using paru
|
|
79
|
+
paru -S pplx-zero
|
|
80
|
+
|
|
81
|
+
# Verify installation
|
|
26
82
|
pplx --version
|
|
27
83
|
```
|
|
28
84
|
|
|
29
|
-
|
|
30
|
-
or
|
|
85
|
+
### 🔧 Build from Source
|
|
31
86
|
|
|
32
87
|
```bash
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
88
|
+
# 1) Clone the repository
|
|
89
|
+
git clone https://github.com/codewithkenzo/pplx-zero.git
|
|
90
|
+
cd pplx-zero
|
|
91
|
+
|
|
92
|
+
# 2) Install dependencies and build
|
|
37
93
|
bun install && bun run build
|
|
38
|
-
|
|
94
|
+
|
|
95
|
+
# 3) Link the CLI (system-wide)
|
|
96
|
+
sudo ln -s "$(pwd)/dist/index.js" /usr/local/bin/pplx
|
|
97
|
+
|
|
98
|
+
# 4) Verify installation
|
|
39
99
|
pplx --version
|
|
40
100
|
```
|
|
41
101
|
|
|
102
|
+
---
|
|
42
103
|
|
|
43
|
-
|
|
44
|
-
Set your API key as an environment variable before running commands.
|
|
104
|
+
## ⚙️ Configuration
|
|
45
105
|
|
|
46
|
-
|
|
106
|
+
### API Key Setup
|
|
107
|
+
|
|
108
|
+
Set your Perplexity API key as an environment variable:
|
|
109
|
+
|
|
110
|
+
**Linux/macOS:**
|
|
47
111
|
```bash
|
|
112
|
+
# Temporary (current session)
|
|
48
113
|
export PERPLEXITY_API_KEY="your-api-key"
|
|
114
|
+
|
|
115
|
+
# Permanent (add to ~/.bashrc, ~/.zshrc, etc.)
|
|
116
|
+
echo 'export PERPLEXITY_API_KEY="your-api-key"' >> ~/.bashrc
|
|
117
|
+
source ~/.bashrc
|
|
49
118
|
```
|
|
50
119
|
|
|
120
|
+
**Windows (PowerShell):**
|
|
121
|
+
```powershell
|
|
122
|
+
# Temporary (current session)
|
|
123
|
+
$env:PERPLEXITY_API_KEY = "your-api-key"
|
|
124
|
+
|
|
125
|
+
# Permanent
|
|
126
|
+
[Environment]::SetEnvironmentVariable("PERPLEXITY_API_KEY", "your-api-key", "User")
|
|
127
|
+
```
|
|
51
128
|
|
|
52
|
-
Windows
|
|
129
|
+
**Windows (CMD):**
|
|
53
130
|
```cmd
|
|
131
|
+
# Permanent
|
|
54
132
|
setx PERPLEXITY_API_KEY "your-api-key"
|
|
55
133
|
```
|
|
56
134
|
|
|
135
|
+
> 🔑 **Get your API key** from your [Perplexity account settings](https://www.perplexity.ai/settings/api) and keep it secure. Never share your API key or commit it to version control.
|
|
57
136
|
|
|
58
|
-
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 🔄 Auto‑Update Management
|
|
140
|
+
|
|
141
|
+
PPLX‑Zero includes a simplified auto‑update system that keeps you current with the latest features and security updates.
|
|
142
|
+
|
|
143
|
+
### Basic Update Commands
|
|
59
144
|
|
|
60
|
-
### Quick examples
|
|
61
|
-
Simple search (default model: sonar)
|
|
62
145
|
```bash
|
|
63
|
-
|
|
146
|
+
# Check for available updates
|
|
147
|
+
pplx update --check
|
|
148
|
+
|
|
149
|
+
# Install updates and relaunch automatically
|
|
150
|
+
pplx update --auto
|
|
64
151
|
```
|
|
65
152
|
|
|
153
|
+
### Update Workflow
|
|
154
|
+
|
|
155
|
+
1. **Automatic Notifications**: PPLX‑Zero checks for updates once per day and notifies you when a new version is available
|
|
156
|
+
2. **Smart Installation**: The updater detects your installation method (npm, AUR, binary) and uses the appropriate update mechanism
|
|
157
|
+
3. **Seamless Relaunch**: When using `--auto`, PPLX‑Zero installs the update and relaunches with your original command
|
|
158
|
+
|
|
159
|
+
### Advanced Update Options
|
|
66
160
|
|
|
67
|
-
Deep research or sonar-pro or reasoning when you need more steps or web context
|
|
68
161
|
```bash
|
|
69
|
-
|
|
70
|
-
pplx
|
|
71
|
-
|
|
162
|
+
# Force update check (ignores cache)
|
|
163
|
+
pplx update --check
|
|
164
|
+
|
|
165
|
+
# Update during automation without interaction
|
|
166
|
+
pplx update --auto --quiet
|
|
72
167
|
```
|
|
73
168
|
|
|
169
|
+
### Troubleshooting Updates
|
|
170
|
+
|
|
171
|
+
| Issue | Solution |
|
|
172
|
+
|-------|----------|
|
|
173
|
+
| **Permission denied** | Run with `sudo` or check installation directory permissions |
|
|
174
|
+
| **Network timeout** | Check internet connection and try again |
|
|
175
|
+
| **Update fails** | Manually install using your original installation method |
|
|
176
|
+
| **Lock file error** | Wait for current update to complete or manually remove `~/.pplx-zero/.updating.lock` |
|
|
177
|
+
|
|
178
|
+
The auto‑update system respects your system configuration and won't modify files without proper permissions.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 🚀 Quick Examples
|
|
183
|
+
|
|
184
|
+
### Basic Search
|
|
74
185
|
|
|
75
|
-
Summarize a PDF report quickly
|
|
76
186
|
```bash
|
|
77
|
-
|
|
187
|
+
# Simple search (default model: sonar)
|
|
188
|
+
pplx "python type hints best practices"
|
|
189
|
+
|
|
190
|
+
# Multiple queries in one command
|
|
191
|
+
pplx "React hooks tutorial" "TypeScript generics" "Docker best practices"
|
|
78
192
|
```
|
|
79
193
|
|
|
194
|
+
### Advanced Models
|
|
80
195
|
|
|
81
|
-
Understand an interface from a screenshot
|
|
82
196
|
```bash
|
|
83
|
-
|
|
197
|
+
# Research with Sonar Pro (more detailed analysis)
|
|
198
|
+
pplx -m sonar-pro "React 19 Hooks new features"
|
|
199
|
+
|
|
200
|
+
# Deep research with comprehensive web context
|
|
201
|
+
pplx -m sonar-deep-research "best Rust web frameworks 2025"
|
|
202
|
+
|
|
203
|
+
# Mathematical reasoning and proofs
|
|
204
|
+
pplx -m sonar-reasoning "prove this algorithm runs in O(n log n)"
|
|
84
205
|
```
|
|
85
206
|
|
|
207
|
+
### Document & Image Analysis
|
|
86
208
|
|
|
87
|
-
Combine a doc and an image in one prompt
|
|
88
209
|
```bash
|
|
210
|
+
# Summarize a PDF report quickly
|
|
211
|
+
pplx -f report.pdf "summarize key findings and risks"
|
|
212
|
+
|
|
213
|
+
# Understand an interface from a screenshot
|
|
214
|
+
pplx -i screenshot.png "what is this UI and what are the next steps?"
|
|
215
|
+
|
|
216
|
+
# Combine multiple files in one analysis
|
|
89
217
|
pplx -f data.csv -i chart.png "spot anomalies and explain the chart"
|
|
218
|
+
|
|
219
|
+
# Multiple file attachments
|
|
220
|
+
pplx -f report.pdf --attach data.csv --attach summary.md "analyze all documents"
|
|
221
|
+
|
|
222
|
+
# Multiple documents of same type using --attach
|
|
223
|
+
pplx --attach doc1.pdf --attach doc2.pdf --attach doc3.txt "compare all reports"
|
|
224
|
+
|
|
225
|
+
# Multiple images using --attach-image
|
|
226
|
+
pplx --attach-image screenshot1.png --attach-image screenshot2.png "analyze the UI flow"
|
|
227
|
+
|
|
228
|
+
# Mixed multiple files (documents + images)
|
|
229
|
+
pplx -f main.pdf --attach appendix.md --attach-image chart.png --attach-image diagram.jpg "comprehensive analysis"
|
|
230
|
+
|
|
231
|
+
# Multiple files with positional arguments (all treated as files)
|
|
232
|
+
pplx file1.pdf file2.txt file3.md "what's in these files"
|
|
90
233
|
```
|
|
91
234
|
|
|
235
|
+
### Batch Processing
|
|
92
236
|
|
|
93
|
-
Stream newline‑delimited JSON for agents or UNIX pipes
|
|
94
237
|
```bash
|
|
95
|
-
|
|
96
|
-
|
|
238
|
+
# Stream newline-delimited JSON for agents or UNIX pipes
|
|
239
|
+
pplx -o jsonl "AI trends"
|
|
97
240
|
|
|
241
|
+
# Batch from a JSON file with custom concurrency
|
|
242
|
+
pplx -I queries.json -o jsonl -c 5 -t 30000
|
|
243
|
+
```
|
|
98
244
|
|
|
99
|
-
Batch
|
|
245
|
+
**Batch JSON format:**
|
|
100
246
|
```json
|
|
101
247
|
{
|
|
102
248
|
"version": "1.0.0",
|
|
@@ -108,47 +254,293 @@ Batch from a JSON file (concurrency and timeout shown)
|
|
|
108
254
|
}
|
|
109
255
|
```
|
|
110
256
|
|
|
257
|
+
### Advanced Workflows
|
|
111
258
|
|
|
112
259
|
```bash
|
|
113
|
-
|
|
260
|
+
# Fire-and-forget async with webhook callback
|
|
261
|
+
pplx --async --webhook http://localhost:3000/callback "long research task"
|
|
262
|
+
|
|
263
|
+
# Export results to file
|
|
264
|
+
pplx --export results.json "machine learning trends"
|
|
265
|
+
|
|
266
|
+
# Search with custom result limits
|
|
267
|
+
pplx -n 10 "latest web development frameworks"
|
|
268
|
+
|
|
269
|
+
# Query from stdin (for pipelines)
|
|
270
|
+
echo '{"query": "best practices for API design"}' | pplx -s
|
|
114
271
|
```
|
|
115
272
|
|
|
273
|
+
### Real‑World Scenarios
|
|
116
274
|
|
|
117
|
-
Fire‑and‑forget async with a webhook callback (agent workflows)
|
|
118
275
|
```bash
|
|
119
|
-
|
|
276
|
+
# Security researcher: Analyze vulnerability report
|
|
277
|
+
pplx -f vuln_report.pdf --attach screenshots/ "explain security implications"
|
|
278
|
+
|
|
279
|
+
# Data analyst: Extract insights from datasets
|
|
280
|
+
pplx -f sales_data.csv -i revenue_chart.png "identify growth opportunities"
|
|
281
|
+
|
|
282
|
+
# Developer: Code review and optimization
|
|
283
|
+
pplx -f app.py --attach perf_metrics.json "suggest performance improvements"
|
|
284
|
+
|
|
285
|
+
# Product manager: Competitive analysis
|
|
286
|
+
pplx -f competitor_data.pdf "summarize key differentiators and market position"
|
|
120
287
|
```
|
|
121
288
|
|
|
122
289
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
-
|
|
133
|
-
|
|
134
|
-
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 📋 Command Reference
|
|
293
|
+
|
|
294
|
+
### Main Options
|
|
295
|
+
|
|
296
|
+
| Flag | Short | Description | Example |
|
|
297
|
+
|------|-------|-------------|---------|
|
|
298
|
+
| `--model` | `-m` | AI model to use | `-m sonar-pro` |
|
|
299
|
+
| `--max-results` | `-n` | Max results per query (1-20) | `-n 10` |
|
|
300
|
+
| `--file` | `-f` | Attach document for analysis | `-f report.pdf` |
|
|
301
|
+
| `--image` | `-i` | Attach image for analysis | `-i screenshot.png` |
|
|
302
|
+
| `--format` | `-o` | Output format: json/jsonl | `-o jsonl` |
|
|
303
|
+
| `--query` | `-q` | Search query (alternative to positional) | `-q "search term"` |
|
|
304
|
+
| `--export` | | Export results to file | `--export results.json` |
|
|
305
|
+
| `--input` | `-I` | Read queries from JSON file | `-I batch.json` |
|
|
306
|
+
| `--stdin` | `-s` | Read queries from stdin | `cat query.json \| pplx -s` |
|
|
307
|
+
| `--attach` | | Additional file attachments | `--attach file1.pdf --attach file2.txt` |
|
|
308
|
+
| `--attach-image` | | Additional image attachments | `--attach-image img1.png --attach-image img2.jpg` |
|
|
309
|
+
| `--async` | | Enable async mode for advanced models | `--async` |
|
|
310
|
+
| `--webhook` | | Webhook URL for async results | `--webhook http://localhost:3000` |
|
|
311
|
+
| `--workspace` | | Workspace directory for file operations | `--workspace ./project` |
|
|
312
|
+
| `--use-search-api` | | Use search API (default: true) | `--use-search-api` |
|
|
313
|
+
| `--batch-size` | | Batch size for processing (1-100) | `--batch-size 50` |
|
|
314
|
+
|
|
315
|
+
### Performance & Control
|
|
316
|
+
|
|
317
|
+
| Flag | Description | Default | Range |
|
|
318
|
+
|------|-------------|---------|-------|
|
|
319
|
+
| `--concurrency` | Max parallel requests for batch operations | 5 | 1-20 |
|
|
320
|
+
| `--timeout` | Request timeout in milliseconds | 30000 | 1000-300000 |
|
|
321
|
+
|
|
322
|
+
### Utility Commands
|
|
323
|
+
|
|
324
|
+
| Command | Description | Example |
|
|
325
|
+
|---------|-------------|---------|
|
|
326
|
+
| `update --check` | Check for available updates | `pplx update --check` |
|
|
327
|
+
| `update --auto` | Install updates and relaunch | `pplx update --auto` |
|
|
328
|
+
| `history [limit]` | Show search history | `pplx history 10` |
|
|
329
|
+
| `version` | Show version information | `pplx version` |
|
|
330
|
+
| `--help` | Show help message | `pplx --help` |
|
|
331
|
+
| `--version` | Show version number | `pplx --version` |
|
|
332
|
+
|
|
333
|
+
### Supported File Formats
|
|
334
|
+
|
|
335
|
+
**Documents (up to 50MB):**
|
|
336
|
+
- PDF, DOC, DOCX, TXT, RTF, MD
|
|
337
|
+
- CSV, JSON (structured data)
|
|
338
|
+
- XML, YAML (configuration files)
|
|
339
|
+
|
|
340
|
+
**Images (up to 50MB):**
|
|
341
|
+
- PNG, JPEG, WebP, HEIF/HEIC, GIF
|
|
342
|
+
- BMP, TIFF (legacy formats)
|
|
343
|
+
|
|
344
|
+
### AI Models
|
|
345
|
+
|
|
346
|
+
| Model | Best For | Speed | Detail |
|
|
347
|
+
|-------|----------|-------|--------|
|
|
348
|
+
| `sonar` | Quick answers, general queries | ⚡ Fast | Standard detail |
|
|
349
|
+
| `sonar-pro` | Detailed analysis, research | 🚀 Fast | Enhanced detail |
|
|
350
|
+
| `sonar-reasoning` | Mathematical reasoning, logic | 🐢 Moderate | Step-by-step |
|
|
351
|
+
| `sonar-deep-research` | Comprehensive research with web context | 🐌 Slow | Maximum detail |
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 💻 Programmatic Use
|
|
356
|
+
|
|
357
|
+
### TypeScript API
|
|
135
358
|
|
|
136
|
-
### Programmatic use (optional)
|
|
137
359
|
Use the toolkit directly in TypeScript when embedding into agents or services.
|
|
360
|
+
|
|
138
361
|
```ts
|
|
139
362
|
import { PerplexitySearchTool } from 'pplx-zero';
|
|
140
363
|
|
|
364
|
+
// Initialize the search tool
|
|
141
365
|
const tool = new PerplexitySearchTool();
|
|
142
366
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
367
|
+
// Single search query
|
|
368
|
+
const result = await tool.search({
|
|
369
|
+
query: "TypeScript best practices",
|
|
370
|
+
model: "sonar-pro",
|
|
371
|
+
maxResults: 5
|
|
146
372
|
});
|
|
147
373
|
|
|
148
374
|
console.log(result);
|
|
149
375
|
```
|
|
150
376
|
|
|
377
|
+
### Batch Processing
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
import { PerplexitySearchTool } from 'pplx-zero';
|
|
381
|
+
|
|
382
|
+
const tool = new PerplexitySearchTool();
|
|
383
|
+
|
|
384
|
+
// Batch search with custom configuration
|
|
385
|
+
const batchResult = await tool.runBatch({
|
|
386
|
+
version: "1.0.0",
|
|
387
|
+
requests: [
|
|
388
|
+
{
|
|
389
|
+
op: "search",
|
|
390
|
+
args: {
|
|
391
|
+
query: "TypeScript best practices",
|
|
392
|
+
maxResults: 5,
|
|
393
|
+
model: "sonar-pro"
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
op: "search",
|
|
398
|
+
args: {
|
|
399
|
+
query: "React performance optimization",
|
|
400
|
+
maxResults: 3,
|
|
401
|
+
model: "sonar"
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
],
|
|
405
|
+
options: {
|
|
406
|
+
concurrency: 3,
|
|
407
|
+
timeoutMs: 30000
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
console.log('Batch results:', batchResult);
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Advanced Usage with Error Handling
|
|
415
|
+
|
|
416
|
+
```ts
|
|
417
|
+
import { PerplexitySearchTool } from 'pplx-zero';
|
|
418
|
+
|
|
419
|
+
async function searchWithRetry(query: string, maxRetries = 3) {
|
|
420
|
+
const tool = new PerplexitySearchTool();
|
|
421
|
+
|
|
422
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
423
|
+
try {
|
|
424
|
+
const result = await tool.search({
|
|
425
|
+
query,
|
|
426
|
+
model: "sonar-pro",
|
|
427
|
+
maxResults: 5
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
return result;
|
|
431
|
+
} catch (error) {
|
|
432
|
+
if (attempt === maxRetries) {
|
|
433
|
+
throw new Error(`Search failed after ${maxRetries} attempts: ${error}`);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Exponential backoff
|
|
437
|
+
await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Usage
|
|
443
|
+
searchWithRetry("latest AI trends")
|
|
444
|
+
.then(result => console.log(result))
|
|
445
|
+
.catch(error => console.error(error));
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## 🛠️ Troubleshooting
|
|
451
|
+
|
|
452
|
+
### Common Issues & Solutions
|
|
453
|
+
|
|
454
|
+
#### API Key Problems
|
|
455
|
+
```bash
|
|
456
|
+
# Error: "API key not found"
|
|
457
|
+
export PERPLEXITY_API_KEY="your-api-key"
|
|
458
|
+
|
|
459
|
+
# Verify key is set
|
|
460
|
+
echo $PERPLEXITY_API_KEY
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
#### File Attachment Issues
|
|
464
|
+
```bash
|
|
465
|
+
# Error: "File too large" (files must be < 50MB)
|
|
466
|
+
ls -lh your-file.pdf
|
|
467
|
+
|
|
468
|
+
# Supported formats check
|
|
469
|
+
file your-document.pdf # Should show PDF format
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
#### Network/Timeout Issues
|
|
473
|
+
```bash
|
|
474
|
+
# Increase timeout for complex queries
|
|
475
|
+
pplx -t 60000 "complex research question"
|
|
476
|
+
|
|
477
|
+
# Check internet connectivity
|
|
478
|
+
curl -I https://api.perplexity.ai
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
#### Permission Issues
|
|
482
|
+
```bash
|
|
483
|
+
# Permission denied during installation
|
|
484
|
+
npm install -g pplx-zero --unsafe-perm
|
|
485
|
+
|
|
486
|
+
# Or use npx to avoid global installation
|
|
487
|
+
npx pplx-zero "your query"
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Debug Mode
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
# Enable verbose output for debugging
|
|
494
|
+
DEBUG=pplx:* pplx "your query"
|
|
495
|
+
|
|
496
|
+
# Check configuration
|
|
497
|
+
pplx --version
|
|
498
|
+
pplx update --check
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Performance Tips
|
|
502
|
+
|
|
503
|
+
| Scenario | Recommended Settings |
|
|
504
|
+
|----------|---------------------|
|
|
505
|
+
| **Quick searches** | Default settings (sonar model) |
|
|
506
|
+
| **Deep research** | `-m sonar-deep-research -t 60000` |
|
|
507
|
+
| **Batch processing** | `-c 10 -t 45000` |
|
|
508
|
+
| **File analysis** | `-m sonar-pro -t 60000` |
|
|
509
|
+
| **Real-time queries** | `-m sonar -n 3` |
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
## 📚 Additional Resources
|
|
514
|
+
|
|
515
|
+
- **GitHub Repository**: [github.com/codewithkenzo/pplx-zero](https://github.com/codewithkenzo/pplx-zero)
|
|
516
|
+
- **Bug Reports & Issues**: [GitHub Issues](https://github.com/codewithkenzo/pplx-zero/issues)
|
|
517
|
+
- **Perplexity API Documentation**: [docs.perplexity.ai](https://docs.perplexity.ai)
|
|
518
|
+
- **Model Comparison**: Detailed model comparison in the [AI Models](#ai-models) section above
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
### Quick Reference Commands
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
# Show all available options
|
|
526
|
+
pplx --help
|
|
527
|
+
|
|
528
|
+
# Check for updates
|
|
529
|
+
pplx update --check
|
|
530
|
+
|
|
531
|
+
# Auto-update
|
|
532
|
+
pplx update --auto
|
|
533
|
+
|
|
534
|
+
# Show version
|
|
535
|
+
pplx --version
|
|
536
|
+
|
|
537
|
+
# Search history
|
|
538
|
+
pplx history 10
|
|
539
|
+
|
|
540
|
+
# Quick test
|
|
541
|
+
pplx "test query"
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
---
|
|
151
545
|
|
|
152
|
-
|
|
153
|
-
- Use pplx --help to see all available options and short flags without scanning long docs.
|
|
154
|
-
- Keep output in jsonl for streaming pipelines and agent frameworks that consume line‑by‑line events.*Built with [Bun](https://bun.sh) and [Perplexity AI](https://www.perplexity.ai)**
|
|
546
|
+
*Built with ❤️ using [Bun](https://bun.sh) and powered by [Perplexity AI](https://www.perplexity.ai)*
|
package/dist/index.js
CHANGED
|
@@ -2008,7 +2008,7 @@ function isValidVersion(version) {
|
|
|
2008
2008
|
const semverRegex = /^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9.-]+))?(?:\+([a-zA-Z0-9.-]+))?$/;
|
|
2009
2009
|
return semverRegex.test(version);
|
|
2010
2010
|
}
|
|
2011
|
-
var __filename2, __dirname2, FALLBACK_VERSION = "1.1.
|
|
2011
|
+
var __filename2, __dirname2, FALLBACK_VERSION = "1.1.8", FALLBACK_PACKAGE_INFO, packageJsonCache = null;
|
|
2012
2012
|
var init_version = __esm(() => {
|
|
2013
2013
|
__filename2 = fileURLToPath(import.meta.url);
|
|
2014
2014
|
__dirname2 = dirname3(__filename2);
|
|
@@ -7857,7 +7857,7 @@ ${textContent}`
|
|
|
7857
7857
|
async executeAdvancedModel(query, options = {}) {
|
|
7858
7858
|
const startTime = performance.now();
|
|
7859
7859
|
try {
|
|
7860
|
-
const { model, attachments, webhook } = options;
|
|
7860
|
+
const { model, attachments, webhook, timeout } = options;
|
|
7861
7861
|
if (model === "sonar-pro" || model === "sonar-deep-research" || model === "sonar-reasoning") {
|
|
7862
7862
|
let messages = [];
|
|
7863
7863
|
if (attachments && attachments.length > 0) {
|
|
@@ -7902,12 +7902,13 @@ ${textContent}`
|
|
|
7902
7902
|
{ role: "user", content: query }
|
|
7903
7903
|
];
|
|
7904
7904
|
}
|
|
7905
|
+
const effectiveTimeout = model === "sonar-deep-research" ? Math.max(timeout || 300000, 300000) : timeout || this.config.timeout;
|
|
7905
7906
|
const response = await this.executeWithTimeout(this.client.chat.completions.create({
|
|
7906
7907
|
model,
|
|
7907
7908
|
messages,
|
|
7908
7909
|
max_tokens: options.maxTokens || 4000,
|
|
7909
7910
|
temperature: options.temperature || 0.1
|
|
7910
|
-
}),
|
|
7911
|
+
}), effectiveTimeout);
|
|
7911
7912
|
let content = "";
|
|
7912
7913
|
if (response && response.choices && response.choices.length > 0) {
|
|
7913
7914
|
const choice = response.choices[0];
|
|
@@ -9238,9 +9239,9 @@ async function getCurrentVersion() {
|
|
|
9238
9239
|
try {
|
|
9239
9240
|
const packageJsonPath = join3(process.cwd(), "package.json");
|
|
9240
9241
|
const packageJson = JSON.parse(await fs3.readFile(packageJsonPath, "utf-8"));
|
|
9241
|
-
return packageJson.version || "1.1.
|
|
9242
|
+
return packageJson.version || "1.1.8";
|
|
9242
9243
|
} catch {
|
|
9243
|
-
return "1.1.
|
|
9244
|
+
return "1.1.8";
|
|
9244
9245
|
}
|
|
9245
9246
|
}
|
|
9246
9247
|
function compareVersions(version1, version2) {
|
|
@@ -9325,7 +9326,13 @@ async function parseQueries(options) {
|
|
|
9325
9326
|
metadata = { lineCount };
|
|
9326
9327
|
} else if (options.input) {
|
|
9327
9328
|
source = "file";
|
|
9328
|
-
|
|
9329
|
+
let fileContent;
|
|
9330
|
+
if (typeof Bun !== "undefined") {
|
|
9331
|
+
fileContent = await Bun.file(options.input).text();
|
|
9332
|
+
} else {
|
|
9333
|
+
const fs4 = await import("node:fs");
|
|
9334
|
+
fileContent = await fs4.promises.readFile(options.input, "utf-8");
|
|
9335
|
+
}
|
|
9329
9336
|
const parsed = JSON.parse(fileContent);
|
|
9330
9337
|
if (parsed.queries && Array.isArray(parsed.queries)) {
|
|
9331
9338
|
queries.push(...parsed.queries);
|
|
@@ -9358,7 +9365,8 @@ async function executeSearch(query, options, filePaths = []) {
|
|
|
9358
9365
|
response = await engine.executeAdvancedModel(query, {
|
|
9359
9366
|
model: options.model,
|
|
9360
9367
|
attachments,
|
|
9361
|
-
webhook: options.webhook
|
|
9368
|
+
webhook: options.webhook,
|
|
9369
|
+
timeout: options.timeout
|
|
9362
9370
|
});
|
|
9363
9371
|
result = {
|
|
9364
9372
|
success: true,
|
|
@@ -9599,14 +9607,58 @@ async function handleSearchCommand(options) {
|
|
|
9599
9607
|
positionals: options.positionals
|
|
9600
9608
|
});
|
|
9601
9609
|
const filePaths = [];
|
|
9602
|
-
|
|
9610
|
+
const filesToValidate = [];
|
|
9611
|
+
if (options.file) {
|
|
9603
9612
|
filePaths.push(options.file);
|
|
9604
|
-
|
|
9613
|
+
filesToValidate.push(options.file);
|
|
9614
|
+
}
|
|
9615
|
+
if (options.image) {
|
|
9605
9616
|
filePaths.push(options.image);
|
|
9606
|
-
|
|
9617
|
+
filesToValidate.push(options.image);
|
|
9618
|
+
}
|
|
9619
|
+
if (options.attach) {
|
|
9607
9620
|
filePaths.push(...options.attach);
|
|
9608
|
-
|
|
9621
|
+
filesToValidate.push(...options.attach);
|
|
9622
|
+
}
|
|
9623
|
+
if (options.attachImage) {
|
|
9609
9624
|
filePaths.push(...options.attachImage);
|
|
9625
|
+
filesToValidate.push(...options.attachImage);
|
|
9626
|
+
}
|
|
9627
|
+
if (filesToValidate.length > 0) {
|
|
9628
|
+
const missingFiles = [];
|
|
9629
|
+
for (const filePath of filesToValidate) {
|
|
9630
|
+
try {
|
|
9631
|
+
if (typeof Bun !== "undefined") {
|
|
9632
|
+
const file = Bun.file(filePath);
|
|
9633
|
+
if (!await file.exists()) {
|
|
9634
|
+
missingFiles.push(filePath);
|
|
9635
|
+
} else if (file.size === 0) {
|
|
9636
|
+
throw new Error(`File is empty: ${filePath}`);
|
|
9637
|
+
}
|
|
9638
|
+
} else {
|
|
9639
|
+
const fs4 = await import("node:fs");
|
|
9640
|
+
const stats = await fs4.promises.stat(filePath);
|
|
9641
|
+
if (!stats.isFile()) {
|
|
9642
|
+
missingFiles.push(filePath);
|
|
9643
|
+
} else if (stats.size === 0) {
|
|
9644
|
+
throw new Error(`File is empty: ${filePath}`);
|
|
9645
|
+
}
|
|
9646
|
+
}
|
|
9647
|
+
} catch (error) {
|
|
9648
|
+
if (error instanceof Error && error.message.includes("File is empty")) {
|
|
9649
|
+
throw error;
|
|
9650
|
+
}
|
|
9651
|
+
missingFiles.push(filePath);
|
|
9652
|
+
}
|
|
9653
|
+
}
|
|
9654
|
+
if (missingFiles.length > 0) {
|
|
9655
|
+
const fileList = missingFiles.length === 1 ? `File "${missingFiles[0]}" does not exist or is not readable` : `Files do not exist or are not readable:
|
|
9656
|
+
${missingFiles.map((f) => ` - ${f}`).join(`
|
|
9657
|
+
`)}`;
|
|
9658
|
+
throw new Error(`${fileList}
|
|
9659
|
+
Please check the file paths and try again.`);
|
|
9660
|
+
}
|
|
9661
|
+
}
|
|
9610
9662
|
const searchOptions = {
|
|
9611
9663
|
maxResults,
|
|
9612
9664
|
concurrency,
|
|
@@ -10104,7 +10156,7 @@ class UpdateChecker {
|
|
|
10104
10156
|
return await getVersion2();
|
|
10105
10157
|
} catch (error) {
|
|
10106
10158
|
console.error("Failed to read current version:", error);
|
|
10107
|
-
return "1.1.
|
|
10159
|
+
return "1.1.8";
|
|
10108
10160
|
}
|
|
10109
10161
|
}
|
|
10110
10162
|
async getLatestVersion() {
|
|
@@ -10236,7 +10288,7 @@ async function handleVersionCommand(options) {
|
|
|
10236
10288
|
}
|
|
10237
10289
|
} catch (error) {
|
|
10238
10290
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
10239
|
-
const fallbackVersion = "pplx-zero v1.1.
|
|
10291
|
+
const fallbackVersion = "pplx-zero v1.1.8";
|
|
10240
10292
|
console.log(fallbackVersion);
|
|
10241
10293
|
if (!errorMessage.includes("ENOENT") && !errorMessage.includes("package.json")) {
|
|
10242
10294
|
const formattedError = CliFormatter.formatError(`Warning: ${errorMessage}`);
|
|
@@ -10299,8 +10351,8 @@ function validateVersionOptions(options) {
|
|
|
10299
10351
|
|
|
10300
10352
|
// src/cli/index.ts
|
|
10301
10353
|
var program2 = new Command;
|
|
10302
|
-
program2.name("pplx").description("Fast Perplexity AI search CLI with multi-search, history, and export").version("1.1.
|
|
10303
|
-
program2.option("-m, --model <model>", "AI model: sonar, sonar-pro, sonar-reasoning, sonar-deep-research").option("-n, --max-results <n>", "Maximum results per query (default: 5, range: 1-20)", "5").option("-c, --concurrency <n>", "Concurrency for batch searches (default: 5, range: 1-20)", "5").option("-t, --timeout <ms>", "Request timeout in milliseconds (default: 30000, range: 1000-300000)", "30000").option("-f, --file <file>", "Attach document for analysis").option("-i, --image <file>", "Attach image for analysis").option("-o, --format <format>", "Output format: json|jsonl (default: json)", "json").option("-q, --query <query>", "Search query (alternative to positional queries)").option("--export <filename>", "Export results to file").option("-I, --input <file>", "Read queries from JSON file").option("-s, --stdin", "Read queries from stdin (JSON format)").option("--attach <
|
|
10354
|
+
program2.name("pplx").description("Fast Perplexity AI search CLI with multi-search, history, and export").version("1.1.8", "-v, --version", "Show version information").helpOption("-h, --help", "Show this help message");
|
|
10355
|
+
program2.option("-m, --model <model>", "AI model: sonar, sonar-pro, sonar-reasoning, sonar-deep-research").option("-n, --max-results <n>", "Maximum results per query (default: 5, range: 1-20)", "5").option("-c, --concurrency <n>", "Concurrency for batch searches (default: 5, range: 1-20)", "5").option("-t, --timeout <ms>", "Request timeout in milliseconds (default: 30000, range: 1000-300000)", "30000").option("-f, --file <file>", "Attach document for analysis").option("-i, --image <file>", "Attach image for analysis").option("-o, --format <format>", "Output format: json|jsonl (default: json)", "json").option("-q, --query <query>", "Search query (alternative to positional queries)").option("--export <filename>", "Export results to file").option("-I, --input <file>", "Read queries from JSON file").option("-s, --stdin", "Read queries from stdin (JSON format)").option("--attach <file>", "Additional file attachment (can be used multiple times)").option("--attach-image <file>", "Additional image attachment (can be used multiple times)").option("--async", "Enable async mode for advanced models").option("--webhook <url>", "Webhook URL for async results").option("--workspace <path>", "Workspace directory for file operations").option("--use-search-api", "Use search API (default: true)", true).option("--batch-size <n>", "Batch size for processing (default: 20, range: 1-100)", "20").allowExcessArguments(true).argument("[queries...]", "Search queries (multiple queries enable multi-search)");
|
|
10304
10356
|
program2.command("history").description("Show search history").argument("[limit]", "Number of recent searches to show (max 50)").option("-f, --files", "Show individual search files with query+date naming").option("--query-pattern <pattern>", "Filter search files by query pattern").action(async (limit, options, command) => {
|
|
10305
10357
|
const args = command.parent?.args.slice(command.parent.args.indexOf(command.name()) + 1) || [];
|
|
10306
10358
|
const historyOptions = parseHistoryArgs(args);
|
|
@@ -10388,7 +10440,44 @@ program2.hook("preSubcommand", async (thisCommand) => {
|
|
|
10388
10440
|
process.exit(result.exitCode);
|
|
10389
10441
|
}
|
|
10390
10442
|
});
|
|
10443
|
+
function parseAttachOptions(rawArgs) {
|
|
10444
|
+
const attach = [];
|
|
10445
|
+
const attachImage = [];
|
|
10446
|
+
const remainingArgs = [];
|
|
10447
|
+
let i = 0;
|
|
10448
|
+
while (i < rawArgs.length) {
|
|
10449
|
+
const arg = rawArgs[i];
|
|
10450
|
+
if (arg === "--attach") {
|
|
10451
|
+
if (i + 1 < rawArgs.length && !rawArgs[i + 1].startsWith("-")) {
|
|
10452
|
+
attach.push(rawArgs[i + 1]);
|
|
10453
|
+
i += 2;
|
|
10454
|
+
} else {
|
|
10455
|
+
console.error("Error: --attach requires a file path");
|
|
10456
|
+
process.exit(1);
|
|
10457
|
+
}
|
|
10458
|
+
} else if (arg === "--attach-image") {
|
|
10459
|
+
if (i + 1 < rawArgs.length && !rawArgs[i + 1].startsWith("-")) {
|
|
10460
|
+
attachImage.push(rawArgs[i + 1]);
|
|
10461
|
+
i += 2;
|
|
10462
|
+
} else {
|
|
10463
|
+
console.error("Error: --attach-image requires a file path");
|
|
10464
|
+
process.exit(1);
|
|
10465
|
+
}
|
|
10466
|
+
} else {
|
|
10467
|
+
remainingArgs.push(arg);
|
|
10468
|
+
i += 1;
|
|
10469
|
+
}
|
|
10470
|
+
}
|
|
10471
|
+
return { attach, attachImage, remainingArgs };
|
|
10472
|
+
}
|
|
10473
|
+
var rawArgs = process.argv.slice(2);
|
|
10474
|
+
var { attach: attachFiles, attachImage: attachImages, remainingArgs } = parseAttachOptions(rawArgs);
|
|
10475
|
+
var collectedAttach = attachFiles;
|
|
10476
|
+
var collectedAttachImages = attachImages;
|
|
10477
|
+
var originalArgv = process.argv;
|
|
10478
|
+
process.argv = ["node", originalArgv[1], ...remainingArgs];
|
|
10391
10479
|
program2.action(async (queries, options) => {
|
|
10480
|
+
process.argv = originalArgv;
|
|
10392
10481
|
const result = await handleSearchCommand({
|
|
10393
10482
|
query: options.query,
|
|
10394
10483
|
file: options.file,
|
|
@@ -10402,8 +10491,8 @@ program2.action(async (queries, options) => {
|
|
|
10402
10491
|
useSearchAPI: options.useSearchApi,
|
|
10403
10492
|
stdin: options.stdin,
|
|
10404
10493
|
input: options.input,
|
|
10405
|
-
attach:
|
|
10406
|
-
attachImage:
|
|
10494
|
+
attach: collectedAttach,
|
|
10495
|
+
attachImage: collectedAttachImages,
|
|
10407
10496
|
export: options.export,
|
|
10408
10497
|
async: options.async,
|
|
10409
10498
|
webhook: options.webhook,
|