@mastra/perplexity 0.0.0
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/CHANGELOG.md +7 -0
- package/README.md +79 -0
- package/dist/client.d.ts +38 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/index.cjs +115 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/search.d.ts +27 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/tools.d.ts +20 -0
- package/dist/tools.d.ts.map +1 -0
- package/package.json +64 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# @mastra/perplexity
|
|
2
|
+
|
|
3
|
+
Web search tool for [Mastra](https://mastra.ai) agents, backed by the [Perplexity Search API](https://docs.perplexity.ai/docs/search/quickstart).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @mastra/perplexity zod
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Agent } from '@mastra/core/agent';
|
|
15
|
+
import { createPerplexitySearchTool } from '@mastra/perplexity';
|
|
16
|
+
|
|
17
|
+
const agent = new Agent({
|
|
18
|
+
id: 'research-agent',
|
|
19
|
+
name: 'Research Agent',
|
|
20
|
+
model: 'anthropic/claude-sonnet-4-6',
|
|
21
|
+
instructions:
|
|
22
|
+
'You are a research assistant. Use the perplexity-search tool to find up-to-date information from the web before answering.',
|
|
23
|
+
tools: {
|
|
24
|
+
search: createPerplexitySearchTool(),
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The tool reads `PERPLEXITY_API_KEY` (or `PPLX_API_KEY` as a fallback) from the environment. Pass `{ apiKey }` explicitly to override.
|
|
30
|
+
|
|
31
|
+
## Filtering
|
|
32
|
+
|
|
33
|
+
The Search API supports filtering by domain and date. All filters are optional.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
const tool = createPerplexitySearchTool();
|
|
37
|
+
|
|
38
|
+
await tool.execute!({
|
|
39
|
+
query: 'recent papers on agent evaluation',
|
|
40
|
+
maxResults: 10,
|
|
41
|
+
searchRecencyFilter: 'month',
|
|
42
|
+
searchDomainFilter: ['arxiv.org', 'openreview.net'],
|
|
43
|
+
}, {} as any);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
To exclude domains, prefix them with `-`. Don't mix allow- and deny-list entries in the same call.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
searchDomainFilter: ['-pinterest.com', '-quora.com'];
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Using Perplexity as a Model Provider
|
|
53
|
+
|
|
54
|
+
Perplexity is also a first-class model provider in Mastra's model router. To chat with Perplexity models (separate from this search tool), set `PERPLEXITY_API_KEY` and reference the model directly:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { Agent } from '@mastra/core/agent';
|
|
58
|
+
|
|
59
|
+
const agent = new Agent({
|
|
60
|
+
id: 'agent-api',
|
|
61
|
+
name: 'Perplexity Agent',
|
|
62
|
+
model: 'perplexity-agent/openai/gpt-5',
|
|
63
|
+
instructions: 'You are a research assistant powered by the Perplexity Agent API.',
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
See the [Perplexity provider docs](https://mastra.ai/models/providers/perplexity) and [Perplexity Agent provider docs](https://mastra.ai/models/providers/perplexity-agent).
|
|
68
|
+
|
|
69
|
+
## Configuration
|
|
70
|
+
|
|
71
|
+
| Option | Type | Default | Description |
|
|
72
|
+
|--------|------|---------|-------------|
|
|
73
|
+
| `apiKey` | `string` | `PERPLEXITY_API_KEY` → `PPLX_API_KEY` | Perplexity API key. |
|
|
74
|
+
| `baseUrl` | `string` | `https://api.perplexity.ai` | Override the API base URL (useful for proxies and tests). |
|
|
75
|
+
| `fetch` | `typeof fetch` | global `fetch` | Inject a custom `fetch` implementation. |
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
Apache-2.0
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const DEFAULT_BASE_URL = "https://api.perplexity.ai";
|
|
2
|
+
export type PerplexityClientOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* Perplexity API key. Falls back to `PERPLEXITY_API_KEY` then `PPLX_API_KEY`
|
|
5
|
+
* environment variables when not provided.
|
|
6
|
+
*/
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Override the API base URL. Defaults to `https://api.perplexity.ai`.
|
|
10
|
+
*/
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional `fetch` implementation. Useful for tests, retries, or instrumentation.
|
|
14
|
+
* Defaults to the global `fetch`.
|
|
15
|
+
*/
|
|
16
|
+
fetch?: typeof fetch;
|
|
17
|
+
};
|
|
18
|
+
export type PerplexitySearchResultItem = {
|
|
19
|
+
title: string;
|
|
20
|
+
url: string;
|
|
21
|
+
snippet: string;
|
|
22
|
+
date?: string;
|
|
23
|
+
};
|
|
24
|
+
export type PerplexitySearchResponse = {
|
|
25
|
+
id?: string;
|
|
26
|
+
results: PerplexitySearchResultItem[];
|
|
27
|
+
};
|
|
28
|
+
export type PerplexitySearchRequest = {
|
|
29
|
+
query: string;
|
|
30
|
+
max_results?: number;
|
|
31
|
+
max_tokens_per_page?: number;
|
|
32
|
+
search_domain_filter?: string[];
|
|
33
|
+
search_recency_filter?: 'hour' | 'day' | 'week' | 'month' | 'year';
|
|
34
|
+
search_after_date_filter?: string;
|
|
35
|
+
search_before_date_filter?: string;
|
|
36
|
+
};
|
|
37
|
+
export declare function perplexitySearchRequest(body: PerplexitySearchRequest, options?: PerplexityClientOptions): Promise<PerplexitySearchResponse>;
|
|
38
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAE5D,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,0BAA0B,EAAE,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACnE,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAYF,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,uBAAuB,EAC7B,OAAO,CAAC,EAAE,uBAAuB,GAChC,OAAO,CAAC,wBAAwB,CAAC,CA6BnC"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tools = require('@mastra/core/tools');
|
|
4
|
+
var zod = require('zod');
|
|
5
|
+
|
|
6
|
+
// src/client.ts
|
|
7
|
+
var DEFAULT_BASE_URL = "https://api.perplexity.ai";
|
|
8
|
+
function resolveApiKey(explicit) {
|
|
9
|
+
const key = explicit ?? process.env.PERPLEXITY_API_KEY ?? process.env.PPLX_API_KEY;
|
|
10
|
+
if (!key) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
"Perplexity API key is required. Pass { apiKey } or set the PERPLEXITY_API_KEY (or PPLX_API_KEY) environment variable."
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
return key;
|
|
16
|
+
}
|
|
17
|
+
async function perplexitySearchRequest(body, options) {
|
|
18
|
+
const apiKey = resolveApiKey(options?.apiKey);
|
|
19
|
+
const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
|
|
20
|
+
const fetchImpl = options?.fetch ?? fetch;
|
|
21
|
+
const response = await fetchImpl(`${baseUrl.replace(/\/$/, "")}/search`, {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
Authorization: `Bearer ${apiKey}`
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify(body)
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
const rawText = await response.text().catch(() => "");
|
|
31
|
+
const MAX_ERROR_BODY = 1e3;
|
|
32
|
+
const text = rawText.length > MAX_ERROR_BODY ? `${rawText.slice(0, MAX_ERROR_BODY)}\u2026` : rawText;
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Perplexity Search request failed with status ${response.status}${text ? `: ${text}` : ""}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const json = await response.json();
|
|
38
|
+
return {
|
|
39
|
+
id: json.id,
|
|
40
|
+
results: Array.isArray(json.results) ? json.results : []
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
var inputSchema = zod.z.object({
|
|
44
|
+
query: zod.z.string().describe("The search query."),
|
|
45
|
+
maxResults: zod.z.number().int().min(1).max(20).optional().describe("Maximum number of results to return (1-20). Defaults to the API default."),
|
|
46
|
+
searchDomainFilter: zod.z.array(zod.z.string()).optional().refine(
|
|
47
|
+
(domains) => {
|
|
48
|
+
if (!domains || domains.length === 0) return true;
|
|
49
|
+
const hasAllow = domains.some((d) => !d.startsWith("-"));
|
|
50
|
+
const hasDeny = domains.some((d) => d.startsWith("-"));
|
|
51
|
+
return !(hasAllow && hasDeny);
|
|
52
|
+
},
|
|
53
|
+
{ message: "searchDomainFilter cannot mix allow and deny domain entries in the same call." }
|
|
54
|
+
).describe(
|
|
55
|
+
"Restrict (or exclude) results by domain. Prefix a domain with `-` to exclude it (e.g. `-pinterest.com`). Do not mix allow and deny entries in the same call."
|
|
56
|
+
),
|
|
57
|
+
searchRecencyFilter: zod.z.enum(["hour", "day", "week", "month", "year"]).optional().describe("Only return results from within the given recency window."),
|
|
58
|
+
searchAfterDateFilter: zod.z.string().optional().describe("Only return results published on or after this date. Format: m/d/yyyy (e.g. 1/1/2025)."),
|
|
59
|
+
searchBeforeDateFilter: zod.z.string().optional().describe("Only return results published on or before this date. Format: m/d/yyyy (e.g. 12/31/2025).")
|
|
60
|
+
});
|
|
61
|
+
var outputSchema = zod.z.object({
|
|
62
|
+
query: zod.z.string(),
|
|
63
|
+
results: zod.z.array(
|
|
64
|
+
zod.z.object({
|
|
65
|
+
title: zod.z.string(),
|
|
66
|
+
url: zod.z.string(),
|
|
67
|
+
snippet: zod.z.string(),
|
|
68
|
+
date: zod.z.string().optional()
|
|
69
|
+
})
|
|
70
|
+
)
|
|
71
|
+
});
|
|
72
|
+
function createPerplexitySearchTool(config) {
|
|
73
|
+
return tools.createTool({
|
|
74
|
+
id: "perplexity-search",
|
|
75
|
+
description: "Search the web for up-to-date information using the Perplexity Search API. Returns ranked results with titles, URLs, snippets, and optional publication dates. Supports filtering by domain, recency, and date range.",
|
|
76
|
+
inputSchema,
|
|
77
|
+
outputSchema,
|
|
78
|
+
execute: async (input) => {
|
|
79
|
+
const response = await perplexitySearchRequest(
|
|
80
|
+
{
|
|
81
|
+
query: input.query,
|
|
82
|
+
max_results: input.maxResults,
|
|
83
|
+
search_domain_filter: input.searchDomainFilter,
|
|
84
|
+
search_recency_filter: input.searchRecencyFilter,
|
|
85
|
+
search_after_date_filter: input.searchAfterDateFilter,
|
|
86
|
+
search_before_date_filter: input.searchBeforeDateFilter
|
|
87
|
+
},
|
|
88
|
+
config
|
|
89
|
+
);
|
|
90
|
+
return {
|
|
91
|
+
query: input.query,
|
|
92
|
+
results: response.results.map((r) => ({
|
|
93
|
+
title: r.title,
|
|
94
|
+
url: r.url,
|
|
95
|
+
snippet: r.snippet,
|
|
96
|
+
date: r.date
|
|
97
|
+
}))
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/tools.ts
|
|
104
|
+
function createPerplexityTools(config) {
|
|
105
|
+
return {
|
|
106
|
+
perplexitySearch: createPerplexitySearchTool(config)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL;
|
|
111
|
+
exports.createPerplexitySearchTool = createPerplexitySearchTool;
|
|
112
|
+
exports.createPerplexityTools = createPerplexityTools;
|
|
113
|
+
exports.perplexitySearchRequest = perplexitySearchRequest;
|
|
114
|
+
//# sourceMappingURL=index.cjs.map
|
|
115
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/search.ts","../src/tools.ts"],"names":["z","createTool"],"mappings":"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","file":"index.cjs","sourcesContent":["export const DEFAULT_BASE_URL = 'https://api.perplexity.ai';\n\nexport type PerplexityClientOptions = {\n /**\n * Perplexity API key. Falls back to `PERPLEXITY_API_KEY` then `PPLX_API_KEY`\n * environment variables when not provided.\n */\n apiKey?: string;\n /**\n * Override the API base URL. Defaults to `https://api.perplexity.ai`.\n */\n baseUrl?: string;\n /**\n * Optional `fetch` implementation. Useful for tests, retries, or instrumentation.\n * Defaults to the global `fetch`.\n */\n fetch?: typeof fetch;\n};\n\nexport type PerplexitySearchResultItem = {\n title: string;\n url: string;\n snippet: string;\n date?: string;\n};\n\nexport type PerplexitySearchResponse = {\n id?: string;\n results: PerplexitySearchResultItem[];\n};\n\nexport type PerplexitySearchRequest = {\n query: string;\n max_results?: number;\n max_tokens_per_page?: number;\n search_domain_filter?: string[];\n search_recency_filter?: 'hour' | 'day' | 'week' | 'month' | 'year';\n search_after_date_filter?: string;\n search_before_date_filter?: string;\n};\n\nfunction resolveApiKey(explicit?: string): string {\n const key = explicit ?? process.env.PERPLEXITY_API_KEY ?? process.env.PPLX_API_KEY;\n if (!key) {\n throw new Error(\n 'Perplexity API key is required. Pass { apiKey } or set the PERPLEXITY_API_KEY (or PPLX_API_KEY) environment variable.',\n );\n }\n return key;\n}\n\nexport async function perplexitySearchRequest(\n body: PerplexitySearchRequest,\n options?: PerplexityClientOptions,\n): Promise<PerplexitySearchResponse> {\n const apiKey = resolveApiKey(options?.apiKey);\n const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;\n const fetchImpl = options?.fetch ?? fetch;\n\n const response = await fetchImpl(`${baseUrl.replace(/\\/$/, '')}/search`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const rawText = await response.text().catch(() => '');\n const MAX_ERROR_BODY = 1000;\n const text =\n rawText.length > MAX_ERROR_BODY ? `${rawText.slice(0, MAX_ERROR_BODY)}…` : rawText;\n throw new Error(\n `Perplexity Search request failed with status ${response.status}${text ? `: ${text}` : ''}`,\n );\n }\n\n const json = (await response.json()) as Partial<PerplexitySearchResponse>;\n return {\n id: json.id,\n results: Array.isArray(json.results) ? json.results : [],\n };\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { perplexitySearchRequest } from './client.js';\nimport type { PerplexityClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n query: z.string().describe('The search query.'),\n maxResults: z\n .number()\n .int()\n .min(1)\n .max(20)\n .optional()\n .describe('Maximum number of results to return (1-20). Defaults to the API default.'),\n searchDomainFilter: z\n .array(z.string())\n .optional()\n .refine(\n domains => {\n if (!domains || domains.length === 0) return true;\n const hasAllow = domains.some(d => !d.startsWith('-'));\n const hasDeny = domains.some(d => d.startsWith('-'));\n return !(hasAllow && hasDeny);\n },\n { message: 'searchDomainFilter cannot mix allow and deny domain entries in the same call.' },\n )\n .describe(\n 'Restrict (or exclude) results by domain. Prefix a domain with `-` to exclude it (e.g. `-pinterest.com`). Do not mix allow and deny entries in the same call.',\n ),\n searchRecencyFilter: z\n .enum(['hour', 'day', 'week', 'month', 'year'])\n .optional()\n .describe('Only return results from within the given recency window.'),\n searchAfterDateFilter: z\n .string()\n .optional()\n .describe('Only return results published on or after this date. Format: m/d/yyyy (e.g. 1/1/2025).'),\n searchBeforeDateFilter: z\n .string()\n .optional()\n .describe('Only return results published on or before this date. Format: m/d/yyyy (e.g. 12/31/2025).'),\n});\n\nconst outputSchema = z.object({\n query: z.string(),\n results: z.array(\n z.object({\n title: z.string(),\n url: z.string(),\n snippet: z.string(),\n date: z.string().optional(),\n }),\n ),\n});\n\n/**\n * Creates a tool that searches the web using the Perplexity Search API.\n *\n * Returns ranked web results with titles, URLs, snippets, and optional\n * publication dates. Supports filtering by domain (allow- or deny-list),\n * recency, and explicit date ranges.\n *\n * @see https://docs.perplexity.ai/docs/search/quickstart\n */\nexport function createPerplexitySearchTool(config?: PerplexityClientOptions) {\n return createTool({\n id: 'perplexity-search',\n description:\n 'Search the web for up-to-date information using the Perplexity Search API. Returns ranked results with titles, URLs, snippets, and optional publication dates. Supports filtering by domain, recency, and date range.',\n inputSchema,\n outputSchema,\n execute: async input => {\n const response = await perplexitySearchRequest(\n {\n query: input.query,\n max_results: input.maxResults,\n search_domain_filter: input.searchDomainFilter,\n search_recency_filter: input.searchRecencyFilter,\n search_after_date_filter: input.searchAfterDateFilter,\n search_before_date_filter: input.searchBeforeDateFilter,\n },\n config,\n );\n\n return {\n query: input.query,\n results: response.results.map(r => ({\n title: r.title,\n url: r.url,\n snippet: r.snippet,\n date: r.date,\n })),\n };\n },\n });\n}\n","import type { PerplexityClientOptions } from './client.js';\nimport { createPerplexitySearchTool } from './search.js';\n\nexport function createPerplexityTools(config?: PerplexityClientOptions) {\n return {\n perplexitySearch: createPerplexitySearchTool(config),\n };\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { perplexitySearchRequest, DEFAULT_BASE_URL, type PerplexityClientOptions, type PerplexitySearchRequest, type PerplexitySearchResponse, type PerplexitySearchResultItem, } from './client.js';
|
|
2
|
+
export { createPerplexitySearchTool } from './search.js';
|
|
3
|
+
export { createPerplexityTools } from './tools.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createTool } from '@mastra/core/tools';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// src/client.ts
|
|
5
|
+
var DEFAULT_BASE_URL = "https://api.perplexity.ai";
|
|
6
|
+
function resolveApiKey(explicit) {
|
|
7
|
+
const key = explicit ?? process.env.PERPLEXITY_API_KEY ?? process.env.PPLX_API_KEY;
|
|
8
|
+
if (!key) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"Perplexity API key is required. Pass { apiKey } or set the PERPLEXITY_API_KEY (or PPLX_API_KEY) environment variable."
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return key;
|
|
14
|
+
}
|
|
15
|
+
async function perplexitySearchRequest(body, options) {
|
|
16
|
+
const apiKey = resolveApiKey(options?.apiKey);
|
|
17
|
+
const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
|
|
18
|
+
const fetchImpl = options?.fetch ?? fetch;
|
|
19
|
+
const response = await fetchImpl(`${baseUrl.replace(/\/$/, "")}/search`, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers: {
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
Authorization: `Bearer ${apiKey}`
|
|
24
|
+
},
|
|
25
|
+
body: JSON.stringify(body)
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
const rawText = await response.text().catch(() => "");
|
|
29
|
+
const MAX_ERROR_BODY = 1e3;
|
|
30
|
+
const text = rawText.length > MAX_ERROR_BODY ? `${rawText.slice(0, MAX_ERROR_BODY)}\u2026` : rawText;
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Perplexity Search request failed with status ${response.status}${text ? `: ${text}` : ""}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const json = await response.json();
|
|
36
|
+
return {
|
|
37
|
+
id: json.id,
|
|
38
|
+
results: Array.isArray(json.results) ? json.results : []
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
var inputSchema = z.object({
|
|
42
|
+
query: z.string().describe("The search query."),
|
|
43
|
+
maxResults: z.number().int().min(1).max(20).optional().describe("Maximum number of results to return (1-20). Defaults to the API default."),
|
|
44
|
+
searchDomainFilter: z.array(z.string()).optional().refine(
|
|
45
|
+
(domains) => {
|
|
46
|
+
if (!domains || domains.length === 0) return true;
|
|
47
|
+
const hasAllow = domains.some((d) => !d.startsWith("-"));
|
|
48
|
+
const hasDeny = domains.some((d) => d.startsWith("-"));
|
|
49
|
+
return !(hasAllow && hasDeny);
|
|
50
|
+
},
|
|
51
|
+
{ message: "searchDomainFilter cannot mix allow and deny domain entries in the same call." }
|
|
52
|
+
).describe(
|
|
53
|
+
"Restrict (or exclude) results by domain. Prefix a domain with `-` to exclude it (e.g. `-pinterest.com`). Do not mix allow and deny entries in the same call."
|
|
54
|
+
),
|
|
55
|
+
searchRecencyFilter: z.enum(["hour", "day", "week", "month", "year"]).optional().describe("Only return results from within the given recency window."),
|
|
56
|
+
searchAfterDateFilter: z.string().optional().describe("Only return results published on or after this date. Format: m/d/yyyy (e.g. 1/1/2025)."),
|
|
57
|
+
searchBeforeDateFilter: z.string().optional().describe("Only return results published on or before this date. Format: m/d/yyyy (e.g. 12/31/2025).")
|
|
58
|
+
});
|
|
59
|
+
var outputSchema = z.object({
|
|
60
|
+
query: z.string(),
|
|
61
|
+
results: z.array(
|
|
62
|
+
z.object({
|
|
63
|
+
title: z.string(),
|
|
64
|
+
url: z.string(),
|
|
65
|
+
snippet: z.string(),
|
|
66
|
+
date: z.string().optional()
|
|
67
|
+
})
|
|
68
|
+
)
|
|
69
|
+
});
|
|
70
|
+
function createPerplexitySearchTool(config) {
|
|
71
|
+
return createTool({
|
|
72
|
+
id: "perplexity-search",
|
|
73
|
+
description: "Search the web for up-to-date information using the Perplexity Search API. Returns ranked results with titles, URLs, snippets, and optional publication dates. Supports filtering by domain, recency, and date range.",
|
|
74
|
+
inputSchema,
|
|
75
|
+
outputSchema,
|
|
76
|
+
execute: async (input) => {
|
|
77
|
+
const response = await perplexitySearchRequest(
|
|
78
|
+
{
|
|
79
|
+
query: input.query,
|
|
80
|
+
max_results: input.maxResults,
|
|
81
|
+
search_domain_filter: input.searchDomainFilter,
|
|
82
|
+
search_recency_filter: input.searchRecencyFilter,
|
|
83
|
+
search_after_date_filter: input.searchAfterDateFilter,
|
|
84
|
+
search_before_date_filter: input.searchBeforeDateFilter
|
|
85
|
+
},
|
|
86
|
+
config
|
|
87
|
+
);
|
|
88
|
+
return {
|
|
89
|
+
query: input.query,
|
|
90
|
+
results: response.results.map((r) => ({
|
|
91
|
+
title: r.title,
|
|
92
|
+
url: r.url,
|
|
93
|
+
snippet: r.snippet,
|
|
94
|
+
date: r.date
|
|
95
|
+
}))
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/tools.ts
|
|
102
|
+
function createPerplexityTools(config) {
|
|
103
|
+
return {
|
|
104
|
+
perplexitySearch: createPerplexitySearchTool(config)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export { DEFAULT_BASE_URL, createPerplexitySearchTool, createPerplexityTools, perplexitySearchRequest };
|
|
109
|
+
//# sourceMappingURL=index.js.map
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/search.ts","../src/tools.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const DEFAULT_BASE_URL = 'https://api.perplexity.ai';\n\nexport type PerplexityClientOptions = {\n /**\n * Perplexity API key. Falls back to `PERPLEXITY_API_KEY` then `PPLX_API_KEY`\n * environment variables when not provided.\n */\n apiKey?: string;\n /**\n * Override the API base URL. Defaults to `https://api.perplexity.ai`.\n */\n baseUrl?: string;\n /**\n * Optional `fetch` implementation. Useful for tests, retries, or instrumentation.\n * Defaults to the global `fetch`.\n */\n fetch?: typeof fetch;\n};\n\nexport type PerplexitySearchResultItem = {\n title: string;\n url: string;\n snippet: string;\n date?: string;\n};\n\nexport type PerplexitySearchResponse = {\n id?: string;\n results: PerplexitySearchResultItem[];\n};\n\nexport type PerplexitySearchRequest = {\n query: string;\n max_results?: number;\n max_tokens_per_page?: number;\n search_domain_filter?: string[];\n search_recency_filter?: 'hour' | 'day' | 'week' | 'month' | 'year';\n search_after_date_filter?: string;\n search_before_date_filter?: string;\n};\n\nfunction resolveApiKey(explicit?: string): string {\n const key = explicit ?? process.env.PERPLEXITY_API_KEY ?? process.env.PPLX_API_KEY;\n if (!key) {\n throw new Error(\n 'Perplexity API key is required. Pass { apiKey } or set the PERPLEXITY_API_KEY (or PPLX_API_KEY) environment variable.',\n );\n }\n return key;\n}\n\nexport async function perplexitySearchRequest(\n body: PerplexitySearchRequest,\n options?: PerplexityClientOptions,\n): Promise<PerplexitySearchResponse> {\n const apiKey = resolveApiKey(options?.apiKey);\n const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;\n const fetchImpl = options?.fetch ?? fetch;\n\n const response = await fetchImpl(`${baseUrl.replace(/\\/$/, '')}/search`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const rawText = await response.text().catch(() => '');\n const MAX_ERROR_BODY = 1000;\n const text =\n rawText.length > MAX_ERROR_BODY ? `${rawText.slice(0, MAX_ERROR_BODY)}…` : rawText;\n throw new Error(\n `Perplexity Search request failed with status ${response.status}${text ? `: ${text}` : ''}`,\n );\n }\n\n const json = (await response.json()) as Partial<PerplexitySearchResponse>;\n return {\n id: json.id,\n results: Array.isArray(json.results) ? json.results : [],\n };\n}\n","import { createTool } from '@mastra/core/tools';\nimport { z } from 'zod';\n\nimport { perplexitySearchRequest } from './client.js';\nimport type { PerplexityClientOptions } from './client.js';\n\nconst inputSchema = z.object({\n query: z.string().describe('The search query.'),\n maxResults: z\n .number()\n .int()\n .min(1)\n .max(20)\n .optional()\n .describe('Maximum number of results to return (1-20). Defaults to the API default.'),\n searchDomainFilter: z\n .array(z.string())\n .optional()\n .refine(\n domains => {\n if (!domains || domains.length === 0) return true;\n const hasAllow = domains.some(d => !d.startsWith('-'));\n const hasDeny = domains.some(d => d.startsWith('-'));\n return !(hasAllow && hasDeny);\n },\n { message: 'searchDomainFilter cannot mix allow and deny domain entries in the same call.' },\n )\n .describe(\n 'Restrict (or exclude) results by domain. Prefix a domain with `-` to exclude it (e.g. `-pinterest.com`). Do not mix allow and deny entries in the same call.',\n ),\n searchRecencyFilter: z\n .enum(['hour', 'day', 'week', 'month', 'year'])\n .optional()\n .describe('Only return results from within the given recency window.'),\n searchAfterDateFilter: z\n .string()\n .optional()\n .describe('Only return results published on or after this date. Format: m/d/yyyy (e.g. 1/1/2025).'),\n searchBeforeDateFilter: z\n .string()\n .optional()\n .describe('Only return results published on or before this date. Format: m/d/yyyy (e.g. 12/31/2025).'),\n});\n\nconst outputSchema = z.object({\n query: z.string(),\n results: z.array(\n z.object({\n title: z.string(),\n url: z.string(),\n snippet: z.string(),\n date: z.string().optional(),\n }),\n ),\n});\n\n/**\n * Creates a tool that searches the web using the Perplexity Search API.\n *\n * Returns ranked web results with titles, URLs, snippets, and optional\n * publication dates. Supports filtering by domain (allow- or deny-list),\n * recency, and explicit date ranges.\n *\n * @see https://docs.perplexity.ai/docs/search/quickstart\n */\nexport function createPerplexitySearchTool(config?: PerplexityClientOptions) {\n return createTool({\n id: 'perplexity-search',\n description:\n 'Search the web for up-to-date information using the Perplexity Search API. Returns ranked results with titles, URLs, snippets, and optional publication dates. Supports filtering by domain, recency, and date range.',\n inputSchema,\n outputSchema,\n execute: async input => {\n const response = await perplexitySearchRequest(\n {\n query: input.query,\n max_results: input.maxResults,\n search_domain_filter: input.searchDomainFilter,\n search_recency_filter: input.searchRecencyFilter,\n search_after_date_filter: input.searchAfterDateFilter,\n search_before_date_filter: input.searchBeforeDateFilter,\n },\n config,\n );\n\n return {\n query: input.query,\n results: response.results.map(r => ({\n title: r.title,\n url: r.url,\n snippet: r.snippet,\n date: r.date,\n })),\n };\n },\n });\n}\n","import type { PerplexityClientOptions } from './client.js';\nimport { createPerplexitySearchTool } from './search.js';\n\nexport function createPerplexityTools(config?: PerplexityClientOptions) {\n return {\n perplexitySearch: createPerplexitySearchTool(config),\n };\n}\n"]}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PerplexityClientOptions } from './client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a tool that searches the web using the Perplexity Search API.
|
|
4
|
+
*
|
|
5
|
+
* Returns ranked web results with titles, URLs, snippets, and optional
|
|
6
|
+
* publication dates. Supports filtering by domain (allow- or deny-list),
|
|
7
|
+
* recency, and explicit date ranges.
|
|
8
|
+
*
|
|
9
|
+
* @see https://docs.perplexity.ai/docs/search/quickstart
|
|
10
|
+
*/
|
|
11
|
+
export declare function createPerplexitySearchTool(config?: PerplexityClientOptions): import("@mastra/core/tools").Tool<{
|
|
12
|
+
query: string;
|
|
13
|
+
maxResults?: number | undefined;
|
|
14
|
+
searchDomainFilter?: string[] | undefined;
|
|
15
|
+
searchRecencyFilter?: "hour" | "day" | "week" | "month" | "year" | undefined;
|
|
16
|
+
searchAfterDateFilter?: string | undefined;
|
|
17
|
+
searchBeforeDateFilter?: string | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
query: string;
|
|
20
|
+
results: {
|
|
21
|
+
title: string;
|
|
22
|
+
url: string;
|
|
23
|
+
snippet: string;
|
|
24
|
+
date?: string | undefined;
|
|
25
|
+
}[];
|
|
26
|
+
}, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "perplexity-search", unknown>;
|
|
27
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAoD3D;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,CAAC,EAAE,uBAAuB;;;;;;;;;;;;;;;iIA+B1E"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PerplexityClientOptions } from './client.js';
|
|
2
|
+
export declare function createPerplexityTools(config?: PerplexityClientOptions): {
|
|
3
|
+
perplexitySearch: import("@mastra/core/tools").Tool<{
|
|
4
|
+
query: string;
|
|
5
|
+
maxResults?: number | undefined;
|
|
6
|
+
searchDomainFilter?: string[] | undefined;
|
|
7
|
+
searchRecencyFilter?: "hour" | "day" | "week" | "month" | "year" | undefined;
|
|
8
|
+
searchAfterDateFilter?: string | undefined;
|
|
9
|
+
searchBeforeDateFilter?: string | undefined;
|
|
10
|
+
}, {
|
|
11
|
+
query: string;
|
|
12
|
+
results: {
|
|
13
|
+
title: string;
|
|
14
|
+
url: string;
|
|
15
|
+
snippet: string;
|
|
16
|
+
date?: string | undefined;
|
|
17
|
+
}[];
|
|
18
|
+
}, unknown, unknown, import("@mastra/core/tools").ToolExecutionContext<unknown, unknown, unknown>, "perplexity-search", unknown>;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAG3D,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,uBAAuB;;;;;;;;;;;;;;;;;EAIrE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mastra/perplexity",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Perplexity Search tool for Mastra agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"CHANGELOG.md"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"require": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"default": "./dist/index.cjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build:lib": "tsup --silent --config tsup.config.ts",
|
|
27
|
+
"build:watch": "pnpm build:lib --watch",
|
|
28
|
+
"lint": "eslint .",
|
|
29
|
+
"test": "vitest run"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"mastra",
|
|
33
|
+
"perplexity",
|
|
34
|
+
"web-search",
|
|
35
|
+
"tools",
|
|
36
|
+
"ai-agent"
|
|
37
|
+
],
|
|
38
|
+
"license": "Apache-2.0",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/mastra-ai/mastra.git",
|
|
42
|
+
"directory": "integrations/perplexity"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/mastra-ai/mastra/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://mastra.ai",
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=22.13.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"@mastra/core": ">=1.0.0-0 <2.0.0-0",
|
|
53
|
+
"zod": ">=3.0.0 || >=4.0.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@internal/lint": "workspace:*",
|
|
57
|
+
"@internal/types-builder": "workspace:*",
|
|
58
|
+
"@mastra/core": "workspace:*",
|
|
59
|
+
"tsup": "^8.5.1",
|
|
60
|
+
"typescript": "catalog:",
|
|
61
|
+
"vitest": "catalog:",
|
|
62
|
+
"zod": "catalog:"
|
|
63
|
+
}
|
|
64
|
+
}
|