mirror of
https://github.com/dotneet/claude-code-marketplace.git
synced 2026-09-14 14:18:13 +08:00
add research plugin
This commit is contained in:
@@ -24,6 +24,15 @@
|
||||
"name": "Shinji Yamada"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "research",
|
||||
"source": "./research",
|
||||
"description": "research tools for software development.",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Shinji Yamada"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "review-tool",
|
||||
"source": "./review-tool",
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "research",
|
||||
"description": "research tools for software development.",
|
||||
"version": "1.0.0",
|
||||
"homepage": "https://github.com/dotneet/claude-code-marketplace",
|
||||
"repository": "https://github.com/dotneet/claude-code-marketplace",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Shinji Yamada"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
name: context7
|
||||
description: A skill for retrieving the latest library documentation using Context7. Use when the user asks about how to use a library, requests code examples, or instructs to "use context7". Prevents hallucinations based on outdated training data and provides up-to-date API information.
|
||||
---
|
||||
|
||||
# Context7
|
||||
|
||||
## Overview
|
||||
|
||||
Context7 is a service that provides LLMs with the latest library documentation. It prevents hallucinations from outdated training data or non-existent APIs, enabling retrieval of version-specific accurate documentation and code examples.
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill in the following cases:
|
||||
|
||||
1. **Explicit instruction**: When the user instructs "use context7" or "check the latest documentation"
|
||||
2. **Library usage questions**: When asked about how to use a specific library's API, hooks, or functions
|
||||
3. **Code example requests**: When asked for code examples using a specific library
|
||||
4. **Version-specific information**: When library information for a specific version is needed
|
||||
5. **Uncertain API information**: When your knowledge might be outdated and latest information verification is needed
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Resolve Library ID
|
||||
|
||||
First, obtain the Context7 ID for the target library.
|
||||
|
||||
**API call:**
|
||||
```bash
|
||||
curl "https://context7.com/api/v2/libs/search?libraryName=LIBRARY_NAME&query=CONTEXT_QUERY" \
|
||||
-H "Authorization: Bearer $CONTEXT7_API_KEY"
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
# Search for React library
|
||||
curl "https://context7.com/api/v2/libs/search?libraryName=react&query=hooks" \
|
||||
-H "Authorization: Bearer $CONTEXT7_API_KEY"
|
||||
```
|
||||
|
||||
**Criteria for selecting from response:**
|
||||
- `trustScore`: Trust score (higher is better)
|
||||
- `totalSnippets`: Number of available documents (more means richer information)
|
||||
- `versions`: Verify that the required version is included
|
||||
|
||||
### Step 2: Retrieve Documentation
|
||||
|
||||
Use the resolved library ID to retrieve specific documentation.
|
||||
|
||||
**API call:**
|
||||
```bash
|
||||
curl "https://context7.com/api/v2/context?libraryId=LIBRARY_ID&query=SPECIFIC_QUERY" \
|
||||
-H "Authorization: Bearer $CONTEXT7_API_KEY"
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
# Retrieve information about React's useEffect
|
||||
curl "https://context7.com/api/v2/context?libraryId=/facebook/react&query=useEffect cleanup function" \
|
||||
-H "Authorization: Bearer $CONTEXT7_API_KEY"
|
||||
```
|
||||
|
||||
**Query best practices:**
|
||||
- Use specific queries ("useEffect cleanup function" rather than "hooks")
|
||||
- Be clear about the purpose ("authentication middleware", "form validation", etc.)
|
||||
|
||||
### Step 3: Respond to User
|
||||
|
||||
Respond to the user's question based on the retrieved documentation.
|
||||
|
||||
**Information to include in the response:**
|
||||
- Retrieved code examples
|
||||
- API explanations
|
||||
- Documentation source URLs (for reference)
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: React Hook Usage
|
||||
|
||||
**User:** "How do I write a cleanup function with React's useEffect?"
|
||||
|
||||
**Execution steps:**
|
||||
1. Library search: `libraryName=react`, `query=useEffect cleanup`
|
||||
2. Documentation retrieval: `libraryId=/facebook/react`, `query=useEffect cleanup function`
|
||||
3. Respond with the latest code examples and best practices
|
||||
|
||||
### Example 2: Next.js Routing
|
||||
|
||||
**User:** "Use context7 to show me how to implement authentication middleware with Next.js App Router"
|
||||
|
||||
**Execution steps:**
|
||||
1. Library search: `libraryName=next.js`, `query=middleware authentication`
|
||||
2. Documentation retrieval: `libraryId=/vercel/next.js`, `query=middleware authentication route protection`
|
||||
3. Respond with the latest App Router compatible middleware implementation
|
||||
|
||||
### Example 3: Multiple Libraries Combination
|
||||
|
||||
**User:** "How to create a button component using TailwindCSS and shadcn/ui"
|
||||
|
||||
**Execution steps:**
|
||||
1. Resolve IDs for each library
|
||||
2. Retrieve documentation for both
|
||||
3. Respond with a combined implementation example
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error | Solution |
|
||||
|-------|----------|
|
||||
| 404 (Not Found) | Search again with a different library name (e.g., "nextjs" → "next.js") |
|
||||
| 429 (Rate Limit) | Wait a moment and retry |
|
||||
| Empty response | Retry with a more general query |
|
||||
|
||||
## Resources
|
||||
|
||||
For detailed API specifications, see `references/api_reference.md`.
|
||||
|
||||
- Endpoint details
|
||||
- Response field descriptions
|
||||
- Rate limit information
|
||||
- Error code list
|
||||
@@ -0,0 +1,137 @@
|
||||
# Context7 API Reference
|
||||
|
||||
## Overview
|
||||
|
||||
Context7 is a service that provides LLMs with the latest library documentation. It solves the problem of outdated training data and non-existent APIs (hallucinations).
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Base URL
|
||||
```
|
||||
https://context7.com/api/v2
|
||||
```
|
||||
|
||||
### Authentication
|
||||
```
|
||||
Authorization: Bearer CONTEXT7_API_KEY
|
||||
```
|
||||
|
||||
The API key starts with the `ctx7sk-` prefix.
|
||||
|
||||
---
|
||||
|
||||
## 1. Library Search API
|
||||
|
||||
### Endpoint
|
||||
```
|
||||
GET /libs/search
|
||||
```
|
||||
|
||||
### Query Parameters
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| libraryName | string | Yes | Library name to search (e.g., "react", "next.js") |
|
||||
| query | string | No | Additional context query |
|
||||
|
||||
### Response
|
||||
```json
|
||||
{
|
||||
"libraries": [
|
||||
{
|
||||
"id": "/facebook/react",
|
||||
"name": "React",
|
||||
"description": "A JavaScript library for building user interfaces",
|
||||
"totalSnippets": 1250,
|
||||
"trustScore": 9.5,
|
||||
"benchmarkScore": 95,
|
||||
"versions": ["18.2.0", "18.3.0", "19.0.0"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| id | string | Context7 library ID (`/org/project` format) |
|
||||
| name | string | Library display name |
|
||||
| description | string | Library description |
|
||||
| totalSnippets | number | Number of available documentation snippets |
|
||||
| trustScore | number | Trust score (0-10) |
|
||||
| benchmarkScore | number | Benchmark score (0-100) |
|
||||
| versions | string[] | List of available versions |
|
||||
|
||||
### Example
|
||||
```bash
|
||||
curl "https://context7.com/api/v2/libs/search?libraryName=react&query=hooks" \
|
||||
-H "Authorization: Bearer ctx7sk-xxx"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Documentation Retrieval API
|
||||
|
||||
### Endpoint
|
||||
```
|
||||
GET /context
|
||||
```
|
||||
|
||||
### Query Parameters
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| libraryId | string | Yes | Context7 library ID (e.g., "/facebook/react") |
|
||||
| query | string | Yes | Search query (e.g., "useEffect cleanup") |
|
||||
| page | number | No | Page number (1-10, default: 1) |
|
||||
|
||||
### Response
|
||||
```json
|
||||
{
|
||||
"documentation": [
|
||||
{
|
||||
"title": "useEffect Hook",
|
||||
"content": "# useEffect\n\nThe `useEffect` Hook lets you synchronize a component with an external system...",
|
||||
"source": "https://react.dev/reference/react/useEffect"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Response Fields
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| title | string | Documentation title |
|
||||
| content | string | Documentation content in Markdown format |
|
||||
| source | string | Original documentation source URL |
|
||||
|
||||
### Example
|
||||
```bash
|
||||
curl "https://context7.com/api/v2/context?libraryId=/facebook/react&query=useEffect" \
|
||||
-H "Authorization: Bearer ctx7sk-xxx"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rate Limits
|
||||
|
||||
| Tier | Requests/min |
|
||||
|------|--------------|
|
||||
| No API Key | 10 |
|
||||
| Free | 100 |
|
||||
| Pro | 1000 |
|
||||
| Enterprise | Custom |
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 400 | Bad Request - Invalid parameters |
|
||||
| 401 | Unauthorized - Invalid API key |
|
||||
| 404 | Not Found - Library not found |
|
||||
| 429 | Too Many Requests - Rate limit exceeded |
|
||||
| 500 | Internal Server Error |
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always resolve library ID before use**: Don't guess library IDs directly; first obtain the accurate ID through the search API
|
||||
2. **Use specific queries**: Specific queries like "useEffect cleanup function" are more effective than "hooks"
|
||||
3. **Error handling**: When receiving 404, try searching with a different library name
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
name: perplexity-search
|
||||
description: A skill for performing web searches, research, and reasoning using the Perplexity API. Handles real-time web information retrieval, deep research analysis, and advanced reasoning tasks. Use when the user asks for web searches, research, or says things like "look up", "search for", "latest information", "research", or "analyze".
|
||||
---
|
||||
|
||||
# Perplexity Search Skill
|
||||
|
||||
A skill for executing real-time web searches and research using the Perplexity API.
|
||||
|
||||
## Purpose
|
||||
|
||||
This skill provides the following capabilities:
|
||||
|
||||
1. **perplexity_ask** - Answer general questions (using sonar-pro model)
|
||||
2. **perplexity_research** - Deep research and comprehensive reports (using sonar-deep-research model)
|
||||
3. **perplexity_reason** - Advanced reasoning and analysis (using sonar-reasoning-pro model)
|
||||
4. **perplexity_search** - Retrieve web search results
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill in the following situations:
|
||||
|
||||
- User needs up-to-date information
|
||||
- Received a question requiring web search
|
||||
- Asked to perform deep research or investigation
|
||||
- Complex analysis or reasoning is required
|
||||
- Keywords like "look up", "search for", "latest..." are included
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- `PERPLEXITY_API_KEY` environment variable must be set
|
||||
- Internet connection must be available
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Use the `scripts/perplexity_api.py` script to call the API.
|
||||
|
||||
```bash
|
||||
# General questions (ask)
|
||||
python3 scripts/perplexity_api.py ask "your question"
|
||||
|
||||
# Deep research (research)
|
||||
python3 scripts/perplexity_api.py research "research topic"
|
||||
|
||||
# Advanced reasoning (reason)
|
||||
python3 scripts/perplexity_api.py reason "reasoning task"
|
||||
|
||||
# Web search (search)
|
||||
python3 scripts/perplexity_api.py search "search query" [--max-results 10] [--country JP]
|
||||
```
|
||||
|
||||
### Command Options
|
||||
|
||||
#### ask / research / reason
|
||||
- First argument: question, research topic, or reasoning task
|
||||
- `--strip-thinking`: Remove `<think>...</think>` tags to save context tokens (research/reason only)
|
||||
|
||||
#### search
|
||||
- First argument: search query
|
||||
- `--max-results`: Maximum number of results to return (1-20, default: 10)
|
||||
- `--max-tokens-per-page`: Maximum tokens per page (256-2048, default: 1024)
|
||||
- `--country`: ISO code for regional results (e.g., JP, US, GB)
|
||||
|
||||
## Workflow
|
||||
|
||||
### Standard Search Flow
|
||||
|
||||
1. Analyze the user's question and select the appropriate tool
|
||||
- Simple questions → `ask`
|
||||
- Deep research → `research`
|
||||
- Complex analysis → `reason`
|
||||
- Information gathering → `search`
|
||||
|
||||
2. Execute the script to call the API
|
||||
|
||||
3. Present results to the user, citing sources when available
|
||||
|
||||
### Tool Selection Guidelines
|
||||
|
||||
| Use Case | Tool | Description |
|
||||
|----------|------|-------------|
|
||||
| Current weather, news | ask | When quick answers are needed |
|
||||
| Technical topic research | research | When comprehensive analysis is needed |
|
||||
| Complex problem analysis | reason | When logical reasoning is needed |
|
||||
| Collecting sources | search | When URLs or snippets are needed |
|
||||
|
||||
## API Details
|
||||
|
||||
For detailed API specifications, see `references/api_reference.md`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **API Key Error**: Verify the `PERPLEXITY_API_KEY` environment variable
|
||||
- **Timeout**: Increase `PERPLEXITY_TIMEOUT_MS` (default: 300000ms)
|
||||
- **Proxy Issues**: Set `PERPLEXITY_PROXY` or `HTTPS_PROXY`
|
||||
@@ -0,0 +1,143 @@
|
||||
# Perplexity API Reference
|
||||
|
||||
## Overview
|
||||
|
||||
The Perplexity API provides real-time web search and advanced AI reasoning capabilities.
|
||||
|
||||
## Authentication
|
||||
|
||||
All requests require an `Authorization: Bearer <PERPLEXITY_API_KEY>` header.
|
||||
|
||||
## Endpoints
|
||||
|
||||
### Chat Completions
|
||||
|
||||
**URL**: `https://api.perplexity.ai/chat/completions`
|
||||
**Method**: POST
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "sonar-pro",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Your question"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Available Models
|
||||
|
||||
| Model | Description | Use Case |
|
||||
|-------|-------------|----------|
|
||||
| `sonar-pro` | General conversational AI | Everyday questions, quick searches |
|
||||
| `sonar-deep-research` | Deep research model | Comprehensive reports, detailed analysis |
|
||||
| `sonar-reasoning-pro` | Reasoning-focused model | Complex problem-solving, logical analysis |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"choices": [
|
||||
{
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": "Response content"
|
||||
}
|
||||
}
|
||||
],
|
||||
"citations": [
|
||||
"https://example.com/source1",
|
||||
"https://example.com/source2"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Search API
|
||||
|
||||
**URL**: `https://api.perplexity.ai/search`
|
||||
**Method**: POST
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"query": "search query",
|
||||
"max_results": 10,
|
||||
"max_tokens_per_page": 1024,
|
||||
"country": "JP"
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------|
|
||||
| `query` | string | Yes | Search query |
|
||||
| `max_results` | int | No | Maximum number of results (1-20, default: 10) |
|
||||
| `max_tokens_per_page` | int | No | Maximum tokens per page (256-2048, default: 1024) |
|
||||
| `country` | string | No | ISO 3166-1 alpha-2 country code |
|
||||
|
||||
#### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"title": "Page title",
|
||||
"url": "https://example.com/page",
|
||||
"snippet": "Page excerpt...",
|
||||
"date": "2024-01-15"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `PERPLEXITY_API_KEY` | API key (required) | - |
|
||||
| `PERPLEXITY_TIMEOUT_MS` | Timeout (milliseconds) | 300000 |
|
||||
| `PERPLEXITY_PROXY` | Proxy URL | - |
|
||||
| `HTTPS_PROXY` | HTTPS proxy (alternative) | - |
|
||||
| `HTTP_PROXY` | HTTP proxy (alternative) | - |
|
||||
|
||||
## Error Handling
|
||||
|
||||
### HTTP Status Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 200 | Success |
|
||||
| 400 | Bad Request |
|
||||
| 401 | Authentication Error (invalid API key) |
|
||||
| 429 | Rate Limit |
|
||||
| 500 | Server Error |
|
||||
|
||||
### Common Errors
|
||||
|
||||
1. **API Key Error**
|
||||
- Symptom: 401 error
|
||||
- Solution: Verify the `PERPLEXITY_API_KEY` environment variable
|
||||
|
||||
2. **Timeout**
|
||||
- Symptom: Request does not complete
|
||||
- Solution: Increase `PERPLEXITY_TIMEOUT_MS`
|
||||
|
||||
3. **Proxy Error**
|
||||
- Symptom: Network connection failure
|
||||
- Solution: Verify proxy settings (when inside corporate network)
|
||||
|
||||
## Rate Limits
|
||||
|
||||
The API has rate limits. When making many requests, ensure appropriate intervals between them.
|
||||
|
||||
## About Thinking Tokens
|
||||
|
||||
The `sonar-deep-research` and `sonar-reasoning-pro` models may output their thinking process in `<think>...</think>` tags before the answer.
|
||||
|
||||
To save context tokens, use the `--strip-thinking` option to remove these tags.
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Perplexity API Client Script
|
||||
|
||||
Provides command-line access to Perplexity API for:
|
||||
- ask: General conversational AI with web search (sonar-pro)
|
||||
- research: Deep research and analysis (sonar-deep-research)
|
||||
- reason: Advanced reasoning tasks (sonar-reasoning-pro)
|
||||
- search: Web search with ranked results
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.error import HTTPError, URLError
|
||||
|
||||
|
||||
def get_api_key():
|
||||
"""Get API key from environment variable."""
|
||||
api_key = os.environ.get("PERPLEXITY_API_KEY")
|
||||
if not api_key:
|
||||
print("Error: PERPLEXITY_API_KEY environment variable is required", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
return api_key
|
||||
|
||||
|
||||
def get_timeout():
|
||||
"""Get timeout from environment variable (default: 300 seconds)."""
|
||||
timeout_ms = os.environ.get("PERPLEXITY_TIMEOUT_MS", "300000")
|
||||
return int(timeout_ms) / 1000
|
||||
|
||||
|
||||
def strip_thinking_tokens(content: str) -> str:
|
||||
"""Remove <think>...</think> tags from content."""
|
||||
return re.sub(r'<think>[\s\S]*?</think>', '', content).strip()
|
||||
|
||||
|
||||
def make_api_request(url: str, body: dict, api_key: str) -> dict:
|
||||
"""Make a POST request to the Perplexity API."""
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
}
|
||||
|
||||
request = Request(
|
||||
url,
|
||||
data=json.dumps(body).encode("utf-8"),
|
||||
headers=headers,
|
||||
method="POST"
|
||||
)
|
||||
|
||||
timeout = get_timeout()
|
||||
|
||||
try:
|
||||
with urlopen(request, timeout=timeout) as response:
|
||||
return json.loads(response.read().decode("utf-8"))
|
||||
except HTTPError as e:
|
||||
error_body = e.read().decode("utf-8") if e.fp else "No response body"
|
||||
print(f"API Error: {e.code} {e.reason}\n{error_body}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except URLError as e:
|
||||
print(f"Network Error: {e.reason}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except TimeoutError:
|
||||
print(f"Timeout Error: Request did not complete within {timeout}s", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def chat_completion(messages: list, model: str, strip_thinking: bool = False) -> str:
|
||||
"""
|
||||
Perform chat completion using Perplexity API.
|
||||
|
||||
Args:
|
||||
messages: List of message dicts with 'role' and 'content'
|
||||
model: Model to use (sonar-pro, sonar-deep-research, sonar-reasoning-pro)
|
||||
strip_thinking: If True, remove <think>...</think> tags from response
|
||||
|
||||
Returns:
|
||||
Response content with citations appended
|
||||
"""
|
||||
api_key = get_api_key()
|
||||
url = "https://api.perplexity.ai/chat/completions"
|
||||
|
||||
body = {
|
||||
"model": model,
|
||||
"messages": messages,
|
||||
}
|
||||
|
||||
data = make_api_request(url, body, api_key)
|
||||
|
||||
# Extract message content
|
||||
content = data.get("choices", [{}])[0].get("message", {}).get("content", "")
|
||||
|
||||
# Strip thinking tokens if requested
|
||||
if strip_thinking:
|
||||
content = strip_thinking_tokens(content)
|
||||
|
||||
# Append citations if available
|
||||
citations = data.get("citations", [])
|
||||
if citations:
|
||||
content += "\n\nCitations:\n"
|
||||
for i, citation in enumerate(citations, 1):
|
||||
content += f"[{i}] {citation}\n"
|
||||
|
||||
return content
|
||||
|
||||
|
||||
def web_search(query: str, max_results: int = 10, max_tokens_per_page: int = 1024, country: str = None) -> str:
|
||||
"""
|
||||
Perform web search using Perplexity Search API.
|
||||
|
||||
Args:
|
||||
query: Search query string
|
||||
max_results: Maximum number of results (1-20)
|
||||
max_tokens_per_page: Maximum tokens per page (256-2048)
|
||||
country: ISO country code for regional results
|
||||
|
||||
Returns:
|
||||
Formatted search results
|
||||
"""
|
||||
api_key = get_api_key()
|
||||
url = "https://api.perplexity.ai/search"
|
||||
|
||||
body = {
|
||||
"query": query,
|
||||
"max_results": max_results,
|
||||
"max_tokens_per_page": max_tokens_per_page,
|
||||
}
|
||||
|
||||
if country:
|
||||
body["country"] = country
|
||||
|
||||
data = make_api_request(url, body, api_key)
|
||||
|
||||
# Format results
|
||||
results = data.get("results", [])
|
||||
if not results:
|
||||
return "No search results found."
|
||||
|
||||
output = f"Found {len(results)} search results:\n\n"
|
||||
|
||||
for i, result in enumerate(results, 1):
|
||||
output += f"{i}. **{result.get('title', 'No title')}**\n"
|
||||
output += f" URL: {result.get('url', 'N/A')}\n"
|
||||
if result.get("snippet"):
|
||||
output += f" {result['snippet']}\n"
|
||||
if result.get("date"):
|
||||
output += f" Date: {result['date']}\n"
|
||||
output += "\n"
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def cmd_ask(args):
|
||||
"""Handle 'ask' command."""
|
||||
messages = [{"role": "user", "content": args.query}]
|
||||
result = chat_completion(messages, "sonar-pro")
|
||||
print(result)
|
||||
|
||||
|
||||
def cmd_research(args):
|
||||
"""Handle 'research' command."""
|
||||
messages = [{"role": "user", "content": args.query}]
|
||||
result = chat_completion(messages, "sonar-deep-research", args.strip_thinking)
|
||||
print(result)
|
||||
|
||||
|
||||
def cmd_reason(args):
|
||||
"""Handle 'reason' command."""
|
||||
messages = [{"role": "user", "content": args.query}]
|
||||
result = chat_completion(messages, "sonar-reasoning-pro", args.strip_thinking)
|
||||
print(result)
|
||||
|
||||
|
||||
def cmd_search(args):
|
||||
"""Handle 'search' command."""
|
||||
result = web_search(
|
||||
args.query,
|
||||
max_results=args.max_results,
|
||||
max_tokens_per_page=args.max_tokens_per_page,
|
||||
country=args.country
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Perplexity API Client",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
|
||||
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
||||
|
||||
# ask command
|
||||
ask_parser = subparsers.add_parser("ask", help="General question answering with web search")
|
||||
ask_parser.add_argument("query", help="Your question")
|
||||
ask_parser.set_defaults(func=cmd_ask)
|
||||
|
||||
# research command
|
||||
research_parser = subparsers.add_parser("research", help="Deep research and comprehensive analysis")
|
||||
research_parser.add_argument("query", help="Research topic or question")
|
||||
research_parser.add_argument("--strip-thinking", action="store_true",
|
||||
help="Remove <think>...</think> tags from response")
|
||||
research_parser.set_defaults(func=cmd_research)
|
||||
|
||||
# reason command
|
||||
reason_parser = subparsers.add_parser("reason", help="Advanced reasoning and problem-solving")
|
||||
reason_parser.add_argument("query", help="Reasoning task or problem")
|
||||
reason_parser.add_argument("--strip-thinking", action="store_true",
|
||||
help="Remove <think>...</think> tags from response")
|
||||
reason_parser.set_defaults(func=cmd_reason)
|
||||
|
||||
# search command
|
||||
search_parser = subparsers.add_parser("search", help="Web search with ranked results")
|
||||
search_parser.add_argument("query", help="Search query")
|
||||
search_parser.add_argument("--max-results", type=int, default=10,
|
||||
help="Maximum number of results (1-20, default: 10)")
|
||||
search_parser.add_argument("--max-tokens-per-page", type=int, default=1024,
|
||||
help="Maximum tokens per page (256-2048, default: 1024)")
|
||||
search_parser.add_argument("--country", type=str,
|
||||
help="ISO country code for regional results (e.g., JP, US)")
|
||||
search_parser.set_defaults(func=cmd_search)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user