Initial commit with translated description
This commit is contained in:
32
SKILL.md
Normal file
32
SKILL.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: perplexity
|
||||||
|
description: "通过Perplexity API搜索网页获取AI驱动的答案。"
|
||||||
|
homepage: https://docs.perplexity.ai
|
||||||
|
metadata: {"clawdbot":{"emoji":"🔮","requires":{"bins":["node"],"env":["PERPLEXITY_API_KEY"]},"primaryEnv":"PERPLEXITY_API_KEY"}}
|
||||||
|
---
|
||||||
|
|
||||||
|
# Perplexity Search
|
||||||
|
|
||||||
|
AI-powered web search that returns grounded answers with citations.
|
||||||
|
|
||||||
|
## Search
|
||||||
|
|
||||||
|
Single query:
|
||||||
|
```bash
|
||||||
|
node {baseDir}/scripts/search.mjs "what's happening in AI today"
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple queries (batch):
|
||||||
|
```bash
|
||||||
|
node {baseDir}/scripts/search.mjs "What is Perplexity?" "Latest AI news" "Best coffee in NYC"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
- `--json`: Output raw JSON response
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Requires `PERPLEXITY_API_KEY` environment variable
|
||||||
|
- Responses include citations when available
|
||||||
|
- Batch queries are processed in a single API call
|
||||||
6
_meta.json
Normal file
6
_meta.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"ownerId": "kn7evq0dm74etz8yf5w8513q8x7ys8hs",
|
||||||
|
"slug": "perplexity",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"publishedAt": 1767791468185
|
||||||
|
}
|
||||||
119
scripts/search.mjs
Normal file
119
scripts/search.mjs
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
|
||||||
|
// Parse args
|
||||||
|
const queries = [];
|
||||||
|
let jsonOutput = false;
|
||||||
|
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
const arg = args[i];
|
||||||
|
if (arg === "--json") {
|
||||||
|
jsonOutput = true;
|
||||||
|
} else if (!arg.startsWith("-")) {
|
||||||
|
queries.push(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queries.length === 0) {
|
||||||
|
console.error("Usage: search.mjs <query> [query2] [query3...] [--json]");
|
||||||
|
console.error("Example: search.mjs 'What is Perplexity?' 'Latest AI news'");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiKey = process.env.PERPLEXITY_API_KEY;
|
||||||
|
if (!apiKey) {
|
||||||
|
console.error("Error: PERPLEXITY_API_KEY environment variable not set");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function search(queries) {
|
||||||
|
const response = await fetch("https://api.perplexity.ai/search", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${apiKey}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
query: queries,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const error = await response.text();
|
||||||
|
throw new Error(`Perplexity API error (${response.status}): ${error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatResult(result, query) {
|
||||||
|
const lines = [];
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
lines.push(`## ${query}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle array of search results
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
for (const item of result.slice(0, 5)) { // Top 5 results
|
||||||
|
if (item.title) lines.push(`**${item.title}**`);
|
||||||
|
if (item.url) lines.push(item.url);
|
||||||
|
if (item.snippet) {
|
||||||
|
// Clean up snippet - take first paragraph
|
||||||
|
const clean = item.snippet.split('\n')[0].slice(0, 300);
|
||||||
|
lines.push(clean + (item.snippet.length > 300 ? '...' : ''));
|
||||||
|
}
|
||||||
|
lines.push('');
|
||||||
|
}
|
||||||
|
} else if (result.results) {
|
||||||
|
// Nested results format
|
||||||
|
for (const item of result.results.slice(0, 5)) {
|
||||||
|
if (item.title) lines.push(`**${item.title}**`);
|
||||||
|
if (item.url) lines.push(item.url);
|
||||||
|
if (item.snippet) {
|
||||||
|
const clean = item.snippet.split('\n')[0].slice(0, 300);
|
||||||
|
lines.push(clean + (item.snippet.length > 300 ? '...' : ''));
|
||||||
|
}
|
||||||
|
lines.push('');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unknown format, dump it
|
||||||
|
lines.push(JSON.stringify(result, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await search(queries);
|
||||||
|
|
||||||
|
if (jsonOutput) {
|
||||||
|
console.log(JSON.stringify(result, null, 2));
|
||||||
|
} else {
|
||||||
|
// The API returns an object with results array
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
// Multiple queries might return array
|
||||||
|
result.forEach((r, i) => {
|
||||||
|
console.log(formatResult(r, queries.length > 1 ? queries[i] : null));
|
||||||
|
});
|
||||||
|
} else if (result.results) {
|
||||||
|
// Single query with results
|
||||||
|
console.log(formatResult(result.results, queries[0]));
|
||||||
|
} else {
|
||||||
|
// Fallback - show top-level items if they look like search results
|
||||||
|
const items = Object.values(result).filter(v =>
|
||||||
|
v && typeof v === 'object' && (v.title || v.url || v.snippet)
|
||||||
|
);
|
||||||
|
if (items.length > 0) {
|
||||||
|
console.log(formatResult(items, queries[0]));
|
||||||
|
} else {
|
||||||
|
// Just dump it nicely
|
||||||
|
console.log(JSON.stringify(result, null, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error: ${error.message}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user