@parallel-web/ai-sdk-tools 0.1.6 → 0.2.1
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 +145 -130
- package/dist/index.cjs +120 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -25
- package/dist/index.d.ts +114 -25
- package/dist/index.js +119 -102
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ pnpm add ai @parallel-web/ai-sdk-tools
|
|
|
12
12
|
yarn add ai @parallel-web/ai-sdk-tools
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
> **Note:** This package requires AI SDK v5.
|
|
15
|
+
> **Note:** This package requires AI SDK v5. For AI SDK v4, use `parameters` instead of `inputSchema` when defining tools manually with the `parallel-web` SDK.
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
@@ -20,17 +20,26 @@ Add `PARALLEL_API_KEY` obtained from [Parallel Platform](https://platform.parall
|
|
|
20
20
|
|
|
21
21
|
### Search Tool
|
|
22
22
|
|
|
23
|
-
`searchTool` uses [Parallel's
|
|
23
|
+
`searchTool` uses [Parallel's Search API](https://docs.parallel.ai/api-reference/search-beta/search) to perform web searches and return LLM-optimized results.
|
|
24
|
+
|
|
25
|
+
**Input schema:**
|
|
26
|
+
- `objective` (required): Natural-language description of what the web search is trying to find
|
|
27
|
+
- `search_queries` (optional): List of keyword search queries (1-6 words each)
|
|
28
|
+
- `mode` (optional): `'agentic'` (default) for concise results in agentic loops, or `'one-shot'` for comprehensive single-response results
|
|
24
29
|
|
|
25
30
|
### Extract Tool
|
|
26
31
|
|
|
27
|
-
`extractTool` uses [Parallel's
|
|
32
|
+
`extractTool` uses [Parallel's Extract API](https://docs.parallel.ai/api-reference/extract-beta/extract) to fetch and extract relevant content from specific URLs.
|
|
33
|
+
|
|
34
|
+
**Input schema:**
|
|
35
|
+
- `urls` (required): List of URLs to extract content from (max 10)
|
|
36
|
+
- `objective` (optional): Natural-language description of what information you're looking for
|
|
28
37
|
|
|
29
38
|
### Basic Example
|
|
30
39
|
|
|
31
40
|
```typescript
|
|
32
41
|
import { openai } from '@ai-sdk/openai';
|
|
33
|
-
import { streamText
|
|
42
|
+
import { streamText } from 'ai';
|
|
34
43
|
import { searchTool, extractTool } from '@parallel-web/ai-sdk-tools';
|
|
35
44
|
|
|
36
45
|
const result = streamText({
|
|
@@ -49,13 +58,48 @@ const result = streamText({
|
|
|
49
58
|
return result.toUIMessageStreamResponse();
|
|
50
59
|
```
|
|
51
60
|
|
|
52
|
-
|
|
61
|
+
## Factory Functions
|
|
62
|
+
|
|
63
|
+
For more control over the tool configuration, use the factory functions to create tools with custom defaults.
|
|
64
|
+
|
|
65
|
+
> **Note:** Both factory functions accept an optional `apiKey` parameter. If not provided, they fall back to the `PARALLEL_API_KEY` environment variable.
|
|
53
66
|
|
|
54
|
-
|
|
67
|
+
### createSearchTool
|
|
68
|
+
|
|
69
|
+
Create a search tool with custom defaults for mode, max_results, excerpts, source_policy, or fetch_policy.
|
|
55
70
|
|
|
56
71
|
```typescript
|
|
57
|
-
import {
|
|
58
|
-
|
|
72
|
+
import { createSearchTool } from '@parallel-web/ai-sdk-tools';
|
|
73
|
+
|
|
74
|
+
const myCustomSearchTool = createSearchTool({
|
|
75
|
+
mode: 'one-shot', // 'one-shot' returns more comprehensive results and longer excerpts to answer questions from a single response.
|
|
76
|
+
max_results: 5, // Limit to 5 results
|
|
77
|
+
apiKey: 'your-api-key', // Optional: pass an API key, falls back to PARALLEL_API_KEY env variable
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### createExtractTool
|
|
82
|
+
|
|
83
|
+
Create an extract tool with custom defaults for excerpts, full_content, or fetch_policy.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { createExtractTool } from '@parallel-web/ai-sdk-tools';
|
|
87
|
+
|
|
88
|
+
const myExtractTool = createExtractTool({
|
|
89
|
+
full_content: true, // Include full page content
|
|
90
|
+
excerpts: {
|
|
91
|
+
max_chars_per_result: 10000,
|
|
92
|
+
},
|
|
93
|
+
apiKey: 'your-api-key', // Optional: pass an API key, falls back to PARALLEL_API_KEY env variable
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Direct API Usage
|
|
98
|
+
|
|
99
|
+
You can also use the `parallel-web` SDK directly for maximum flexibility:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { tool } from 'ai';
|
|
59
103
|
import { z } from 'zod';
|
|
60
104
|
import { Parallel } from 'parallel-web';
|
|
61
105
|
|
|
@@ -64,149 +108,120 @@ const parallel = new Parallel({
|
|
|
64
108
|
});
|
|
65
109
|
|
|
66
110
|
const webSearch = tool({
|
|
67
|
-
description: '
|
|
111
|
+
description: 'Search the web for information.',
|
|
68
112
|
inputSchema: z.object({
|
|
69
|
-
|
|
70
|
-
usersQuestion: z.string().describe("The user's question"),
|
|
113
|
+
query: z.string().describe("The user's question"),
|
|
71
114
|
}),
|
|
72
|
-
execute: async ({
|
|
73
|
-
const
|
|
74
|
-
objective:
|
|
75
|
-
|
|
76
|
-
max_results:
|
|
77
|
-
max_chars_per_result: 1000,
|
|
115
|
+
execute: async ({ query }) => {
|
|
116
|
+
const result = await parallel.beta.search({
|
|
117
|
+
objective: query,
|
|
118
|
+
mode: 'agentic',
|
|
119
|
+
max_results: 5,
|
|
78
120
|
});
|
|
79
|
-
return
|
|
121
|
+
return result;
|
|
80
122
|
},
|
|
81
123
|
});
|
|
82
124
|
```
|
|
83
125
|
|
|
84
|
-
##
|
|
126
|
+
## API Reference
|
|
85
127
|
|
|
86
|
-
|
|
128
|
+
- [Search API Documentation](https://docs.parallel.ai/search/search-quickstart)
|
|
129
|
+
- [Extract API Documentation](https://docs.parallel.ai/extract/extract-quickstart)
|
|
130
|
+
- [Search API Best Practices](https://docs.parallel.ai/search/best-practices)
|
|
87
131
|
|
|
88
|
-
|
|
132
|
+
## Response Format
|
|
133
|
+
|
|
134
|
+
Both tools return the raw API response from Parallel:
|
|
135
|
+
|
|
136
|
+
### Search Response
|
|
89
137
|
|
|
90
138
|
```typescript
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
139
|
+
{
|
|
140
|
+
search_id: string;
|
|
141
|
+
results: Array<{
|
|
142
|
+
url: string;
|
|
143
|
+
title?: string;
|
|
144
|
+
publish_date?: string;
|
|
145
|
+
excerpts: string[];
|
|
146
|
+
}>;
|
|
147
|
+
usage?: Array<{ name: string; count: number }>;
|
|
148
|
+
warnings?: Array<{ code: string; message: string }>;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
94
151
|
|
|
95
|
-
|
|
96
|
-
apiKey: process.env.PARALLEL_API_KEY,
|
|
97
|
-
});
|
|
152
|
+
### Extract Response
|
|
98
153
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
};
|
|
118
|
-
case 'list':
|
|
119
|
-
default:
|
|
120
|
-
return {
|
|
121
|
-
max_results: 20,
|
|
122
|
-
max_chars_per_result: 1500
|
|
123
|
-
};
|
|
124
|
-
}
|
|
154
|
+
```typescript
|
|
155
|
+
{
|
|
156
|
+
extract_id: string;
|
|
157
|
+
results: Array<{
|
|
158
|
+
url: string;
|
|
159
|
+
title?: string;
|
|
160
|
+
excerpts?: string[];
|
|
161
|
+
full_content?: string;
|
|
162
|
+
publish_date?: string;
|
|
163
|
+
}>;
|
|
164
|
+
errors: Array<{
|
|
165
|
+
url: string;
|
|
166
|
+
error_type: string;
|
|
167
|
+
http_status_code?: number;
|
|
168
|
+
content?: string;
|
|
169
|
+
}>;
|
|
170
|
+
usage?: Array<{ name: string; count: number }>;
|
|
171
|
+
warnings?: Array<{ code: string; message: string }>;
|
|
125
172
|
}
|
|
173
|
+
```
|
|
126
174
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
.optional()
|
|
144
|
-
.describe('List of keyword search queries of 1-6 words.'),
|
|
145
|
-
include_domains: z
|
|
146
|
-
.array(z.string())
|
|
147
|
-
.optional()
|
|
148
|
-
.describe('List of valid URL domains to restrict search results.'),
|
|
149
|
-
}),
|
|
150
|
-
execute: async (
|
|
151
|
-
{ ...args },
|
|
152
|
-
{ abortSignal }: { abortSignal?: AbortSignal }
|
|
153
|
-
) => {
|
|
154
|
-
const results = const results = await search(
|
|
155
|
-
{ ...args, ...getSearchParams(args.search_type) },
|
|
156
|
-
{ abortSignal }
|
|
157
|
-
);
|
|
158
|
-
return {
|
|
159
|
-
searchParams: { objective, search_type, search_queries, include_domains },
|
|
160
|
-
answer: results,
|
|
161
|
-
};
|
|
162
|
-
},
|
|
175
|
+
## Migration from v0.1.x
|
|
176
|
+
|
|
177
|
+
Version 0.2.0 introduces an updated API that conforms with Parallel's Search and Extract MCP tools:
|
|
178
|
+
|
|
179
|
+
### searchTool changes
|
|
180
|
+
|
|
181
|
+
- **Input schema changed**: Removed `search_type` and `include_domains`. Added `mode` parameter.
|
|
182
|
+
- **Return value changed**: Now returns raw API response (`{ search_id, results, ... }`) instead of `{ searchParams, answer }`.
|
|
183
|
+
|
|
184
|
+
**Before (v0.1.x):**
|
|
185
|
+
```typescript
|
|
186
|
+
const result = await searchTool.execute({
|
|
187
|
+
objective: 'Find TypeScript info',
|
|
188
|
+
search_type: 'list',
|
|
189
|
+
search_queries: ['TypeScript'],
|
|
190
|
+
include_domains: ['typescriptlang.org'],
|
|
163
191
|
});
|
|
192
|
+
console.log(result.answer.results);
|
|
164
193
|
```
|
|
165
194
|
|
|
166
|
-
|
|
167
|
-
|
|
195
|
+
**After (v0.2.0):**
|
|
168
196
|
```typescript
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
197
|
+
const result = await searchTool.execute({
|
|
198
|
+
objective: 'Find TypeScript info',
|
|
199
|
+
search_queries: ['TypeScript'],
|
|
200
|
+
mode: 'agentic', // optional, defaults to 'agentic'
|
|
201
|
+
});
|
|
202
|
+
console.log(result.results);
|
|
203
|
+
```
|
|
172
204
|
|
|
173
|
-
|
|
174
|
-
|
|
205
|
+
### extractTool changes
|
|
206
|
+
|
|
207
|
+
- **Input schema changed**: `urls` is now first, `objective` is optional.
|
|
208
|
+
- **Return value changed**: Now returns raw API response (`{ extract_id, results, errors, ... }`) instead of `{ searchParams, answer }`.
|
|
209
|
+
|
|
210
|
+
**Before (v0.1.x):**
|
|
211
|
+
```typescript
|
|
212
|
+
const result = await extractTool.execute({
|
|
213
|
+
objective: 'Extract content',
|
|
214
|
+
urls: ['https://example.com'],
|
|
215
|
+
search_queries: ['keyword'],
|
|
175
216
|
});
|
|
217
|
+
console.log(result.answer.results);
|
|
218
|
+
```
|
|
176
219
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
- Exploring URLs returned by a web search in greater depth`,
|
|
183
|
-
parameters: z.object({
|
|
184
|
-
// v4 uses parameters instead of inputSchema
|
|
185
|
-
objective: z
|
|
186
|
-
.string()
|
|
187
|
-
.describe(
|
|
188
|
-
"Natural-language description of what information you're looking for from the URLs."
|
|
189
|
-
),
|
|
190
|
-
urls: z
|
|
191
|
-
.array(z.string())
|
|
192
|
-
.describe(
|
|
193
|
-
'List of URLs to extract content from. Maximum 10 URLs per request.'
|
|
194
|
-
),
|
|
195
|
-
search_queries: z
|
|
196
|
-
.array(z.string())
|
|
197
|
-
.optional()
|
|
198
|
-
.describe('Optional keyword search queries related to the objective.'),
|
|
199
|
-
}),
|
|
200
|
-
execute: async ({ objective, urls, search_queries }) => {
|
|
201
|
-
const results = await parallel.beta.extract({
|
|
202
|
-
objective,
|
|
203
|
-
urls,
|
|
204
|
-
search_queries,
|
|
205
|
-
});
|
|
206
|
-
return {
|
|
207
|
-
searchParams: { objective, urls, search_queries },
|
|
208
|
-
answer: results,
|
|
209
|
-
};
|
|
210
|
-
},
|
|
220
|
+
**After (v0.2.0):**
|
|
221
|
+
```typescript
|
|
222
|
+
const result = await extractTool.execute({
|
|
223
|
+
urls: ['https://example.com'],
|
|
224
|
+
objective: 'Extract content', // optional
|
|
211
225
|
});
|
|
226
|
+
console.log(result.results);
|
|
212
227
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -10,7 +10,10 @@ var parallelClient = new Proxy({}, {
|
|
|
10
10
|
get(_target, prop) {
|
|
11
11
|
if (!_parallelClient) {
|
|
12
12
|
_parallelClient = new parallelWeb.Parallel({
|
|
13
|
-
apiKey: process.env["PARALLEL_API_KEY"]
|
|
13
|
+
apiKey: process.env["PARALLEL_API_KEY"],
|
|
14
|
+
defaultHeaders: {
|
|
15
|
+
"X-Tool-Calling-Package": `npm:@parallel-web/ai-sdk-tools/v${"0.2.1"}`
|
|
16
|
+
}
|
|
14
17
|
});
|
|
15
18
|
}
|
|
16
19
|
return _parallelClient[prop];
|
|
@@ -18,90 +21,77 @@ var parallelClient = new Proxy({}, {
|
|
|
18
21
|
});
|
|
19
22
|
|
|
20
23
|
// src/tools/search.ts
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
case "general":
|
|
26
|
-
return { max_results: 10, max_chars_per_result: 9e3 };
|
|
27
|
-
case "single_page":
|
|
28
|
-
return { max_results: 2, max_chars_per_result: 3e4 };
|
|
29
|
-
case "list":
|
|
30
|
-
default:
|
|
31
|
-
return { max_results: 20, max_chars_per_result: 1500 };
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
var search = async (searchArgs, { abortSignal }) => {
|
|
35
|
-
return await parallelClient.beta.search(
|
|
36
|
-
{
|
|
37
|
-
...searchArgs
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
signal: abortSignal,
|
|
41
|
-
headers: { "parallel-beta": "search-extract-2025-10-10" }
|
|
42
|
-
}
|
|
43
|
-
);
|
|
44
|
-
};
|
|
24
|
+
var objectiveDescription = `Natural-language description of what the web search is trying to find.
|
|
25
|
+
Try to make the search objective atomic, looking for a specific piece of information. May include guidance about preferred sources or freshness.`;
|
|
26
|
+
var searchQueriesDescription = `(optional) List of keyword search queries of 1-6 words, which may include search operators. The search queries should be related to the objective. Limited to 5 entries of 200 characters each.`;
|
|
27
|
+
var modeDescription = `Presets default values for different use cases. "one-shot" returns more comprehensive results and longer excerpts to answer questions from a single response, while "agentic" returns more concise, token-efficient results for use in an agentic loop. Defaults to "agentic".`;
|
|
45
28
|
var searchTool = ai.tool({
|
|
46
|
-
description: `
|
|
47
|
-
web_search_parallel tool returns ranked, extended web excerpts optimized for LLMs.
|
|
48
|
-
Intelligently scale the number of web_search_parallel tool calls to get more information
|
|
49
|
-
when needed, from a single call for simple factual questions to five or more calls for
|
|
50
|
-
complex research questions.
|
|
29
|
+
description: `Purpose: Perform web searches and return results in an LLM-friendly format.
|
|
51
30
|
|
|
52
|
-
|
|
53
|
-
queries and medium context, then add words to narrow results or use high context
|
|
54
|
-
if needed.
|
|
55
|
-
* Include broader context about what the search is trying to accomplish in the
|
|
56
|
-
\`objective\` field. This helps the search engine understand the user's intent and
|
|
57
|
-
provide relevant results and excerpts.
|
|
58
|
-
* Never repeat similar search queries - make every query unique. If initial results are
|
|
59
|
-
insufficient, reformulate queries to obtain new and better results.
|
|
60
|
-
|
|
61
|
-
How to use:
|
|
62
|
-
- For simple queries, a one-shot call to depth is usually sufficient.
|
|
63
|
-
- For complex multi-hop queries, first try to use breadth to narrow down sources. Then
|
|
64
|
-
use other search types with include_domains to get more detailed results.`,
|
|
31
|
+
Use the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`,
|
|
65
32
|
inputSchema: zod.z.object({
|
|
66
|
-
objective: zod.z.string().describe(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
freshness guidance here. Limit to 200 characters. This should reflect the end goal so
|
|
70
|
-
that the tool can better understand the intent and return the best results. Do not
|
|
71
|
-
dump long texts.`
|
|
72
|
-
),
|
|
73
|
-
search_type: zod.z.enum(["list", "general", "single_page", "targeted"]).describe(
|
|
74
|
-
`Can be "list", "general", "single_page" or "targeted".
|
|
75
|
-
"list" should be used for searching for data broadly, like aggregating data or
|
|
76
|
-
considering multiple sources or doing broad initial research. "targeted" should be
|
|
77
|
-
used for searching for data from a specific source set. "general" is a catch all case
|
|
78
|
-
if there is no specific use case from list or targeted. "single_page" extracts data
|
|
79
|
-
from a single page - extremely targeted. If there is a specific webpage you want the
|
|
80
|
-
data from, use "single_page" and mention the URL in the objective.
|
|
81
|
-
Use search_type appropriately.`
|
|
82
|
-
).optional().default("list"),
|
|
83
|
-
search_queries: zod.z.array(zod.z.string()).optional().describe(
|
|
84
|
-
`(optional) List of keyword search queries of 1-6
|
|
85
|
-
words, which may include search operators. The search queries should be related to the
|
|
86
|
-
objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are
|
|
87
|
-
ideal.`
|
|
88
|
-
),
|
|
89
|
-
include_domains: zod.z.array(zod.z.string()).optional().describe(`(optional) List of valid URL domains to explicitly
|
|
90
|
-
focus on for the search. This will restrict all search results to only include results
|
|
91
|
-
from the provided list. This is useful when you want to only use a specific set of
|
|
92
|
-
sources. example: ["google.com", "wikipedia.org"]. Maximum 10 entries.`)
|
|
33
|
+
objective: zod.z.string().describe(objectiveDescription),
|
|
34
|
+
search_queries: zod.z.array(zod.z.string()).optional().describe(searchQueriesDescription),
|
|
35
|
+
mode: zod.z.enum(["agentic", "one-shot"]).optional().default("agentic").describe(modeDescription)
|
|
93
36
|
}),
|
|
94
|
-
execute: async function({
|
|
95
|
-
|
|
96
|
-
{
|
|
97
|
-
|
|
37
|
+
execute: async function({ objective, search_queries, mode }, { abortSignal }) {
|
|
38
|
+
return await parallelClient.beta.search(
|
|
39
|
+
{
|
|
40
|
+
objective,
|
|
41
|
+
search_queries,
|
|
42
|
+
mode
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
signal: abortSignal
|
|
46
|
+
}
|
|
98
47
|
);
|
|
99
|
-
return {
|
|
100
|
-
searchParams: args,
|
|
101
|
-
answer: results
|
|
102
|
-
};
|
|
103
48
|
}
|
|
104
49
|
});
|
|
50
|
+
var defaultSearchDescription = `Purpose: Perform web searches and return results in an LLM-friendly format.
|
|
51
|
+
|
|
52
|
+
Use the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`;
|
|
53
|
+
function createSearchTool(options = {}) {
|
|
54
|
+
const {
|
|
55
|
+
apiKey,
|
|
56
|
+
mode: defaultMode = "agentic",
|
|
57
|
+
max_results,
|
|
58
|
+
excerpts,
|
|
59
|
+
source_policy,
|
|
60
|
+
fetch_policy,
|
|
61
|
+
description = defaultSearchDescription
|
|
62
|
+
} = options;
|
|
63
|
+
const client = apiKey ? new parallelWeb.Parallel({
|
|
64
|
+
apiKey,
|
|
65
|
+
defaultHeaders: {
|
|
66
|
+
"X-Tool-Calling-Package": `npm:@parallel-web/ai-sdk-tools/v${"0.2.1"}`
|
|
67
|
+
}
|
|
68
|
+
}) : parallelClient;
|
|
69
|
+
return ai.tool({
|
|
70
|
+
description,
|
|
71
|
+
inputSchema: zod.z.object({
|
|
72
|
+
objective: zod.z.string().describe(objectiveDescription),
|
|
73
|
+
search_queries: zod.z.array(zod.z.string()).optional().describe(searchQueriesDescription)
|
|
74
|
+
}),
|
|
75
|
+
execute: async function({ objective, search_queries }, { abortSignal }) {
|
|
76
|
+
return await client.beta.search(
|
|
77
|
+
{
|
|
78
|
+
objective,
|
|
79
|
+
search_queries,
|
|
80
|
+
mode: defaultMode,
|
|
81
|
+
max_results,
|
|
82
|
+
excerpts,
|
|
83
|
+
source_policy,
|
|
84
|
+
fetch_policy
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
signal: abortSignal
|
|
88
|
+
}
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
var urlsDescription = `List of URLs to extract content from. Must be valid HTTP/HTTPS URLs. Maximum 10 URLs per request.`;
|
|
94
|
+
var objectiveDescription2 = `Natural-language description of what information you're looking for from the URLs.`;
|
|
105
95
|
var extractTool = ai.tool({
|
|
106
96
|
description: `Purpose: Fetch and extract relevant content from specific web URLs.
|
|
107
97
|
|
|
@@ -109,36 +99,65 @@ Ideal Use Cases:
|
|
|
109
99
|
- Extracting content from specific URLs you've already identified
|
|
110
100
|
- Exploring URLs returned by a web search in greater depth`,
|
|
111
101
|
inputSchema: zod.z.object({
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Limit to 200 characters.`
|
|
115
|
-
),
|
|
116
|
-
urls: zod.z.array(zod.z.string()).describe(
|
|
117
|
-
`List of URLs to extract content from. Must be valid
|
|
118
|
-
HTTP/HTTPS URLs. Maximum 10 URLs per request.`
|
|
119
|
-
),
|
|
120
|
-
search_queries: zod.z.array(zod.z.string()).optional().describe(
|
|
121
|
-
`(optional) List of keyword search queries of 1-6
|
|
122
|
-
words, which may include search operators. The search queries should be related to the
|
|
123
|
-
objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are
|
|
124
|
-
ideal.`
|
|
125
|
-
)
|
|
102
|
+
urls: zod.z.array(zod.z.string()).describe(urlsDescription),
|
|
103
|
+
objective: zod.z.string().optional().describe(objectiveDescription2)
|
|
126
104
|
}),
|
|
127
|
-
execute: async function({
|
|
128
|
-
|
|
129
|
-
{
|
|
105
|
+
execute: async function({ urls, objective }, { abortSignal }) {
|
|
106
|
+
return await parallelClient.beta.extract(
|
|
107
|
+
{
|
|
108
|
+
urls,
|
|
109
|
+
objective
|
|
110
|
+
},
|
|
130
111
|
{
|
|
131
|
-
signal: abortSignal
|
|
132
|
-
headers: { "parallel-beta": "search-extract-2025-10-10" }
|
|
112
|
+
signal: abortSignal
|
|
133
113
|
}
|
|
134
114
|
);
|
|
135
|
-
return {
|
|
136
|
-
searchParams: args,
|
|
137
|
-
answer: results
|
|
138
|
-
};
|
|
139
115
|
}
|
|
140
116
|
});
|
|
117
|
+
var defaultExtractDescription = `Purpose: Fetch and extract relevant content from specific web URLs.
|
|
118
|
+
|
|
119
|
+
Ideal Use Cases:
|
|
120
|
+
- Extracting content from specific URLs you've already identified
|
|
121
|
+
- Exploring URLs returned by a web search in greater depth`;
|
|
122
|
+
function createExtractTool(options = {}) {
|
|
123
|
+
const {
|
|
124
|
+
apiKey,
|
|
125
|
+
excerpts,
|
|
126
|
+
full_content,
|
|
127
|
+
fetch_policy,
|
|
128
|
+
description = defaultExtractDescription
|
|
129
|
+
} = options;
|
|
130
|
+
const client = apiKey ? new parallelWeb.Parallel({
|
|
131
|
+
apiKey,
|
|
132
|
+
defaultHeaders: {
|
|
133
|
+
"X-Tool-Calling-Package": `npm:@parallel-web/ai-sdk-tools/v${"0.2.1"}`
|
|
134
|
+
}
|
|
135
|
+
}) : parallelClient;
|
|
136
|
+
return ai.tool({
|
|
137
|
+
description,
|
|
138
|
+
inputSchema: zod.z.object({
|
|
139
|
+
urls: zod.z.array(zod.z.string()).describe(urlsDescription),
|
|
140
|
+
objective: zod.z.string().optional().describe(objectiveDescription2)
|
|
141
|
+
}),
|
|
142
|
+
execute: async function({ urls, objective }, { abortSignal }) {
|
|
143
|
+
return await client.beta.extract(
|
|
144
|
+
{
|
|
145
|
+
urls,
|
|
146
|
+
objective,
|
|
147
|
+
excerpts,
|
|
148
|
+
full_content,
|
|
149
|
+
fetch_policy
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
signal: abortSignal
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
141
158
|
|
|
159
|
+
exports.createExtractTool = createExtractTool;
|
|
160
|
+
exports.createSearchTool = createSearchTool;
|
|
142
161
|
exports.extractTool = extractTool;
|
|
143
162
|
exports.searchTool = searchTool;
|
|
144
163
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/tools/search.ts","../src/tools/extract.ts"],"names":["Parallel","tool","z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Shared Parallel Web client instance\n */\n\nimport { Parallel } from 'parallel-web';\n\nlet _parallelClient: Parallel | null = null;\n\nexport const parallelClient = new Proxy({} as Parallel, {\n get(_target, prop) {\n if (!_parallelClient) {\n _parallelClient = new Parallel({\n apiKey: process.env['PARALLEL_API_KEY'],\n });\n }\n return (_parallelClient as any)[prop];\n },\n});\n","/**\n * Search tool for Parallel Web\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { BetaSearchParams } from 'parallel-web/resources/beta/beta.mjs';\nimport { parallelClient } from '../client.js';\n\nfunction getSearchParams(\n search_type: 'list' | 'targeted' | 'general' | 'single_page'\n): Pick<BetaSearchParams, 'max_results' | 'max_chars_per_result'> {\n switch (search_type) {\n case 'targeted':\n return { max_results: 5, max_chars_per_result: 16000 };\n case 'general':\n return { max_results: 10, max_chars_per_result: 9000 };\n case 'single_page':\n return { max_results: 2, max_chars_per_result: 30000 };\n case 'list':\n default:\n return { max_results: 20, max_chars_per_result: 1500 };\n }\n}\n\nconst search = async (\n searchArgs: BetaSearchParams,\n { abortSignal }: { abortSignal: AbortSignal | undefined }\n) => {\n return await parallelClient.beta.search(\n {\n ...searchArgs,\n },\n {\n signal: abortSignal,\n headers: { 'parallel-beta': 'search-extract-2025-10-10' },\n }\n );\n};\n\nexport const searchTool = tool({\n description: `Use the web_search_parallel tool to access information from the web. The\nweb_search_parallel tool returns ranked, extended web excerpts optimized for LLMs.\nIntelligently scale the number of web_search_parallel tool calls to get more information\nwhen needed, from a single call for simple factual questions to five or more calls for\ncomplex research questions.\n\n* Keep queries concise - 1-6 words for best results. Start broad with very short\n queries and medium context, then add words to narrow results or use high context\n if needed.\n* Include broader context about what the search is trying to accomplish in the\n \\`objective\\` field. This helps the search engine understand the user's intent and\n provide relevant results and excerpts.\n* Never repeat similar search queries - make every query unique. If initial results are\n insufficient, reformulate queries to obtain new and better results.\n\nHow to use:\n- For simple queries, a one-shot call to depth is usually sufficient.\n- For complex multi-hop queries, first try to use breadth to narrow down sources. Then\nuse other search types with include_domains to get more detailed results.`,\n inputSchema: z.object({\n objective: z.string().describe(\n `Natural-language description of what the web research goal\n is. Specify the broad intent of the search query here. Also include any source or\n freshness guidance here. Limit to 200 characters. This should reflect the end goal so\n that the tool can better understand the intent and return the best results. Do not\n dump long texts.`\n ),\n search_type: z\n .enum(['list', 'general', 'single_page', 'targeted'])\n .describe(\n `Can be \"list\", \"general\", \"single_page\" or \"targeted\".\n \"list\" should be used for searching for data broadly, like aggregating data or\n considering multiple sources or doing broad initial research. \"targeted\" should be\n used for searching for data from a specific source set. \"general\" is a catch all case\n if there is no specific use case from list or targeted. \"single_page\" extracts data\n from a single page - extremely targeted. If there is a specific webpage you want the\n data from, use \"single_page\" and mention the URL in the objective.\n Use search_type appropriately.`\n )\n .optional()\n .default('list'),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(\n `(optional) List of keyword search queries of 1-6\n words, which may include search operators. The search queries should be related to the\n objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are\n ideal.`\n ),\n include_domains: z.array(z.string()).optional()\n .describe(`(optional) List of valid URL domains to explicitly\n focus on for the search. This will restrict all search results to only include results\n from the provided list. This is useful when you want to only use a specific set of\n sources. example: [\"google.com\", \"wikipedia.org\"]. Maximum 10 entries.`),\n }),\n\n execute: async function ({ ...args }, { abortSignal }) {\n const results = await search(\n { ...args, ...getSearchParams(args.search_type) },\n { abortSignal }\n );\n\n return {\n searchParams: args,\n answer: results,\n };\n },\n});\n","/**\n * Extract tool for Parallel Web\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { parallelClient } from '../client.js';\n\nexport const extractTool = tool({\n description: `Purpose: Fetch and extract relevant content from specific web URLs.\n\nIdeal Use Cases:\n- Extracting content from specific URLs you've already identified\n- Exploring URLs returned by a web search in greater depth`,\n inputSchema: z.object({\n objective: z.string().describe(\n `Natural-language description of what information you're looking for from the URLs. \n Limit to 200 characters.`\n ),\n\n urls: z.array(z.string()).describe(\n `List of URLs to extract content from. Must be valid\nHTTP/HTTPS URLs. Maximum 10 URLs per request.`\n ),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(\n `(optional) List of keyword search queries of 1-6\n words, which may include search operators. The search queries should be related to the\n objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are\n ideal.`\n ),\n }),\n\n execute: async function ({ ...args }, { abortSignal }) {\n const results = await parallelClient.beta.extract(\n { ...args },\n {\n signal: abortSignal,\n headers: { 'parallel-beta': 'search-extract-2025-10-10' },\n }\n );\n\n return {\n searchParams: args,\n answer: results,\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/tools/search.ts","../src/tools/extract.ts"],"names":["Parallel","tool","z","objectiveDescription"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Shared Parallel Web client instance\n */\n\ndeclare const __PACKAGE_VERSION__: string;\n\nimport { Parallel } from 'parallel-web';\n\nlet _parallelClient: Parallel | null = null;\n\nexport const parallelClient = new Proxy({} as Parallel, {\n get(_target, prop: keyof Parallel) {\n if (!_parallelClient) {\n _parallelClient = new Parallel({\n apiKey: process.env['PARALLEL_API_KEY'],\n defaultHeaders: {\n 'X-Tool-Calling-Package': `npm:@parallel-web/ai-sdk-tools/v${__PACKAGE_VERSION__ ?? '0.0.0'}`,\n },\n });\n }\n return _parallelClient[prop];\n },\n});\n","/**\n * Search tool for Parallel Web\n */\n\ndeclare const __PACKAGE_VERSION__: string;\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { Parallel } from 'parallel-web';\nimport type {\n ExcerptSettings,\n FetchPolicy,\n} from 'parallel-web/resources/beta/beta.mjs';\nimport type { SourcePolicy } from 'parallel-web/resources/shared.mjs';\nimport { parallelClient } from '../client.js';\n\n/**\n * Options for creating a custom search tool with code-supplied defaults.\n */\nexport interface CreateSearchToolOptions {\n /**\n * API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY\n * environment variable.\n */\n apiKey?: string;\n\n /**\n * Default mode for search. 'agentic' returns concise, token-efficient results\n * for multi-step workflows. 'one-shot' returns comprehensive results with\n * longer excerpts. Defaults to 'agentic'.\n */\n mode?: 'agentic' | 'one-shot';\n\n /**\n * Maximum number of search results to return. Defaults to 10.\n */\n max_results?: number;\n\n /**\n * Excerpt settings for controlling excerpt length.\n */\n excerpts?: ExcerptSettings;\n\n /**\n * Source policy for controlling which domains to include/exclude and freshness.\n */\n source_policy?: SourcePolicy | null;\n\n /**\n * Fetch policy for controlling cached vs fresh content.\n */\n fetch_policy?: FetchPolicy | null;\n\n /**\n * Custom tool description. If not provided, uses the default description.\n */\n description?: string;\n}\n\nconst objectiveDescription = `Natural-language description of what the web search is trying to find.\nTry to make the search objective atomic, looking for a specific piece of information. May include guidance about preferred sources or freshness.`;\n\nconst searchQueriesDescription = `(optional) List of keyword search queries of 1-6 words, which may include search operators. The search queries should be related to the objective. Limited to 5 entries of 200 characters each.`;\n\nconst modeDescription = `Presets default values for different use cases. \"one-shot\" returns more comprehensive results and longer excerpts to answer questions from a single response, while \"agentic\" returns more concise, token-efficient results for use in an agentic loop. Defaults to \"agentic\".`;\n\n/**\n * Search tool that mirrors the MCP web_search_preview tool.\n * Takes objective and optional search_queries/mode, returns raw search response.\n */\nexport const searchTool = tool({\n description: `Purpose: Perform web searches and return results in an LLM-friendly format.\n\nUse the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`,\n inputSchema: z.object({\n objective: z.string().describe(objectiveDescription),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(searchQueriesDescription),\n mode: z\n .enum(['agentic', 'one-shot'])\n .optional()\n .default('agentic')\n .describe(modeDescription),\n }),\n\n execute: async function (\n { objective, search_queries, mode },\n { abortSignal }\n ) {\n return await parallelClient.beta.search(\n {\n objective,\n search_queries,\n mode,\n },\n {\n signal: abortSignal,\n }\n );\n },\n});\n\nconst defaultSearchDescription = `Purpose: Perform web searches and return results in an LLM-friendly format.\n\nUse the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`;\n\n/**\n * Factory function to create a search tool with custom defaults.\n *\n * Use this when you want to set defaults for mode, max_results, excerpts,\n * source_policy, or fetch_policy in your code, so the LLM only needs to\n * provide objective and search_queries.\n *\n * @example\n * ```ts\n * const mySearchTool = createSearchTool({\n * mode: 'one-shot',\n * max_results: 5,\n * excerpts: { max_chars_per_result: 5000 },\n * });\n * ```\n */\nexport function createSearchTool(options: CreateSearchToolOptions = {}) {\n const {\n apiKey,\n mode: defaultMode = 'agentic',\n max_results,\n excerpts,\n source_policy,\n fetch_policy,\n description = defaultSearchDescription,\n } = options;\n\n const client = apiKey\n ? new Parallel({\n apiKey,\n defaultHeaders: {\n 'X-Tool-Calling-Package': `npm:@parallel-web/ai-sdk-tools/v${__PACKAGE_VERSION__ ?? '0.0.0'}`,\n },\n })\n : parallelClient;\n\n return tool({\n description,\n inputSchema: z.object({\n objective: z.string().describe(objectiveDescription),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(searchQueriesDescription),\n }),\n\n execute: async function ({ objective, search_queries }, { abortSignal }) {\n return await client.beta.search(\n {\n objective,\n search_queries,\n mode: defaultMode,\n max_results,\n excerpts,\n source_policy,\n fetch_policy,\n },\n {\n signal: abortSignal,\n }\n );\n },\n });\n}\n","/**\n * Extract tool for Parallel Web\n */\n\ndeclare const __PACKAGE_VERSION__: string;\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { Parallel } from 'parallel-web';\nimport type {\n ExcerptSettings,\n FetchPolicy,\n BetaExtractParams,\n} from 'parallel-web/resources/beta/beta.mjs';\nimport { parallelClient } from '../client.js';\n\n/**\n * Options for creating a custom extract tool with code-supplied defaults.\n */\nexport interface CreateExtractToolOptions {\n /**\n * API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY\n * environment variable.\n */\n apiKey?: string;\n\n /**\n * Include excerpts from each URL relevant to the search objective and queries.\n * Can be a boolean or ExcerptSettings object. Defaults to true.\n */\n excerpts?: boolean | ExcerptSettings;\n\n /**\n * Include full content from each URL. Can be a boolean or FullContentSettings object.\n * Defaults to false.\n */\n full_content?: BetaExtractParams['full_content'];\n\n /**\n * Fetch policy for controlling cached vs fresh content.\n */\n fetch_policy?: FetchPolicy | null;\n\n /**\n * Custom tool description. If not provided, uses the default description.\n */\n description?: string;\n}\n\nconst urlsDescription = `List of URLs to extract content from. Must be valid HTTP/HTTPS URLs. Maximum 10 URLs per request.`;\n\nconst objectiveDescription = `Natural-language description of what information you're looking for from the URLs.`;\n\n/**\n * Extract tool that mirrors the MCP web_fetch tool.\n * Takes urls and optional objective, returns raw extract response.\n */\nexport const extractTool = tool({\n description: `Purpose: Fetch and extract relevant content from specific web URLs.\n\nIdeal Use Cases:\n- Extracting content from specific URLs you've already identified\n- Exploring URLs returned by a web search in greater depth`,\n inputSchema: z.object({\n urls: z.array(z.string()).describe(urlsDescription),\n objective: z.string().optional().describe(objectiveDescription),\n }),\n\n execute: async function (\n { urls, objective }: { urls: string[]; objective?: string },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\n return await parallelClient.beta.extract(\n {\n urls,\n objective,\n },\n {\n signal: abortSignal,\n }\n );\n },\n});\n\nconst defaultExtractDescription = `Purpose: Fetch and extract relevant content from specific web URLs.\n\nIdeal Use Cases:\n- Extracting content from specific URLs you've already identified\n- Exploring URLs returned by a web search in greater depth`;\n\n/**\n * Factory function to create an extract tool with custom defaults.\n *\n * Use this when you want to set defaults for excerpts, full_content, or\n * fetch_policy in your code, so the LLM only needs to provide urls and objective.\n *\n * @example\n * ```ts\n * const myExtractTool = createExtractTool({\n * excerpts: { max_chars_per_result: 5000 },\n * full_content: true,\n * });\n * ```\n */\nexport function createExtractTool(options: CreateExtractToolOptions = {}) {\n const {\n apiKey,\n excerpts,\n full_content,\n fetch_policy,\n description = defaultExtractDescription,\n } = options;\n\n const client = apiKey\n ? new Parallel({\n apiKey,\n defaultHeaders: {\n 'X-Tool-Calling-Package': `npm:@parallel-web/ai-sdk-tools/v${__PACKAGE_VERSION__ ?? '0.0.0'}`,\n },\n })\n : parallelClient;\n\n return tool({\n description,\n inputSchema: z.object({\n urls: z.array(z.string()).describe(urlsDescription),\n objective: z.string().optional().describe(objectiveDescription),\n }),\n\n execute: async function (\n { urls, objective }: { urls: string[]; objective?: string },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\n return await client.beta.extract(\n {\n urls,\n objective,\n excerpts,\n full_content,\n fetch_policy,\n },\n {\n signal: abortSignal,\n }\n );\n },\n });\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,38 +1,127 @@
|
|
|
1
1
|
import * as ai from 'ai';
|
|
2
|
-
import
|
|
2
|
+
import { Parallel } from 'parallel-web';
|
|
3
|
+
import { ExcerptSettings, FetchPolicy, BetaExtractParams } from 'parallel-web/resources/beta/beta.mjs';
|
|
4
|
+
import { SourcePolicy } from 'parallel-web/resources/shared.mjs';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
7
|
+
* Options for creating a custom search tool with code-supplied defaults.
|
|
8
|
+
*/
|
|
9
|
+
interface CreateSearchToolOptions {
|
|
10
|
+
/**
|
|
11
|
+
* API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY
|
|
12
|
+
* environment variable.
|
|
13
|
+
*/
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Default mode for search. 'agentic' returns concise, token-efficient results
|
|
17
|
+
* for multi-step workflows. 'one-shot' returns comprehensive results with
|
|
18
|
+
* longer excerpts. Defaults to 'agentic'.
|
|
19
|
+
*/
|
|
20
|
+
mode?: 'agentic' | 'one-shot';
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of search results to return. Defaults to 10.
|
|
23
|
+
*/
|
|
24
|
+
max_results?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Excerpt settings for controlling excerpt length.
|
|
27
|
+
*/
|
|
28
|
+
excerpts?: ExcerptSettings;
|
|
29
|
+
/**
|
|
30
|
+
* Source policy for controlling which domains to include/exclude and freshness.
|
|
31
|
+
*/
|
|
32
|
+
source_policy?: SourcePolicy | null;
|
|
33
|
+
/**
|
|
34
|
+
* Fetch policy for controlling cached vs fresh content.
|
|
35
|
+
*/
|
|
36
|
+
fetch_policy?: FetchPolicy | null;
|
|
37
|
+
/**
|
|
38
|
+
* Custom tool description. If not provided, uses the default description.
|
|
39
|
+
*/
|
|
40
|
+
description?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Search tool that mirrors the MCP web_search_preview tool.
|
|
44
|
+
* Takes objective and optional search_queries/mode, returns raw search response.
|
|
6
45
|
*/
|
|
7
46
|
declare const searchTool: ai.Tool<{
|
|
8
47
|
objective: string;
|
|
9
|
-
|
|
48
|
+
mode: "agentic" | "one-shot";
|
|
10
49
|
search_queries?: string[] | undefined;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
50
|
+
}, Parallel.Beta.SearchResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Factory function to create a search tool with custom defaults.
|
|
53
|
+
*
|
|
54
|
+
* Use this when you want to set defaults for mode, max_results, excerpts,
|
|
55
|
+
* source_policy, or fetch_policy in your code, so the LLM only needs to
|
|
56
|
+
* provide objective and search_queries.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const mySearchTool = createSearchTool({
|
|
61
|
+
* mode: 'one-shot',
|
|
62
|
+
* max_results: 5,
|
|
63
|
+
* excerpts: { max_chars_per_result: 5000 },
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function createSearchTool(options?: CreateSearchToolOptions): ai.Tool<{
|
|
68
|
+
objective: string;
|
|
69
|
+
search_queries?: string[] | undefined;
|
|
70
|
+
}, Parallel.Beta.SearchResult>;
|
|
21
71
|
|
|
22
72
|
/**
|
|
23
|
-
*
|
|
73
|
+
* Options for creating a custom extract tool with code-supplied defaults.
|
|
74
|
+
*/
|
|
75
|
+
interface CreateExtractToolOptions {
|
|
76
|
+
/**
|
|
77
|
+
* API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY
|
|
78
|
+
* environment variable.
|
|
79
|
+
*/
|
|
80
|
+
apiKey?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Include excerpts from each URL relevant to the search objective and queries.
|
|
83
|
+
* Can be a boolean or ExcerptSettings object. Defaults to true.
|
|
84
|
+
*/
|
|
85
|
+
excerpts?: boolean | ExcerptSettings;
|
|
86
|
+
/**
|
|
87
|
+
* Include full content from each URL. Can be a boolean or FullContentSettings object.
|
|
88
|
+
* Defaults to false.
|
|
89
|
+
*/
|
|
90
|
+
full_content?: BetaExtractParams['full_content'];
|
|
91
|
+
/**
|
|
92
|
+
* Fetch policy for controlling cached vs fresh content.
|
|
93
|
+
*/
|
|
94
|
+
fetch_policy?: FetchPolicy | null;
|
|
95
|
+
/**
|
|
96
|
+
* Custom tool description. If not provided, uses the default description.
|
|
97
|
+
*/
|
|
98
|
+
description?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Extract tool that mirrors the MCP web_fetch tool.
|
|
102
|
+
* Takes urls and optional objective, returns raw extract response.
|
|
24
103
|
*/
|
|
25
104
|
declare const extractTool: ai.Tool<{
|
|
26
|
-
objective: string;
|
|
27
105
|
urls: string[];
|
|
28
|
-
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
106
|
+
objective?: string | undefined;
|
|
107
|
+
}, Parallel.Beta.ExtractResponse>;
|
|
108
|
+
/**
|
|
109
|
+
* Factory function to create an extract tool with custom defaults.
|
|
110
|
+
*
|
|
111
|
+
* Use this when you want to set defaults for excerpts, full_content, or
|
|
112
|
+
* fetch_policy in your code, so the LLM only needs to provide urls and objective.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* const myExtractTool = createExtractTool({
|
|
117
|
+
* excerpts: { max_chars_per_result: 5000 },
|
|
118
|
+
* full_content: true,
|
|
119
|
+
* });
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare function createExtractTool(options?: CreateExtractToolOptions): ai.Tool<{
|
|
123
|
+
urls: string[];
|
|
124
|
+
objective?: string | undefined;
|
|
125
|
+
}, Parallel.Beta.ExtractResponse>;
|
|
37
126
|
|
|
38
|
-
export { extractTool, searchTool };
|
|
127
|
+
export { type CreateExtractToolOptions, type CreateSearchToolOptions, createExtractTool, createSearchTool, extractTool, searchTool };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,127 @@
|
|
|
1
1
|
import * as ai from 'ai';
|
|
2
|
-
import
|
|
2
|
+
import { Parallel } from 'parallel-web';
|
|
3
|
+
import { ExcerptSettings, FetchPolicy, BetaExtractParams } from 'parallel-web/resources/beta/beta.mjs';
|
|
4
|
+
import { SourcePolicy } from 'parallel-web/resources/shared.mjs';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
7
|
+
* Options for creating a custom search tool with code-supplied defaults.
|
|
8
|
+
*/
|
|
9
|
+
interface CreateSearchToolOptions {
|
|
10
|
+
/**
|
|
11
|
+
* API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY
|
|
12
|
+
* environment variable.
|
|
13
|
+
*/
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Default mode for search. 'agentic' returns concise, token-efficient results
|
|
17
|
+
* for multi-step workflows. 'one-shot' returns comprehensive results with
|
|
18
|
+
* longer excerpts. Defaults to 'agentic'.
|
|
19
|
+
*/
|
|
20
|
+
mode?: 'agentic' | 'one-shot';
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of search results to return. Defaults to 10.
|
|
23
|
+
*/
|
|
24
|
+
max_results?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Excerpt settings for controlling excerpt length.
|
|
27
|
+
*/
|
|
28
|
+
excerpts?: ExcerptSettings;
|
|
29
|
+
/**
|
|
30
|
+
* Source policy for controlling which domains to include/exclude and freshness.
|
|
31
|
+
*/
|
|
32
|
+
source_policy?: SourcePolicy | null;
|
|
33
|
+
/**
|
|
34
|
+
* Fetch policy for controlling cached vs fresh content.
|
|
35
|
+
*/
|
|
36
|
+
fetch_policy?: FetchPolicy | null;
|
|
37
|
+
/**
|
|
38
|
+
* Custom tool description. If not provided, uses the default description.
|
|
39
|
+
*/
|
|
40
|
+
description?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Search tool that mirrors the MCP web_search_preview tool.
|
|
44
|
+
* Takes objective and optional search_queries/mode, returns raw search response.
|
|
6
45
|
*/
|
|
7
46
|
declare const searchTool: ai.Tool<{
|
|
8
47
|
objective: string;
|
|
9
|
-
|
|
48
|
+
mode: "agentic" | "one-shot";
|
|
10
49
|
search_queries?: string[] | undefined;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
50
|
+
}, Parallel.Beta.SearchResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Factory function to create a search tool with custom defaults.
|
|
53
|
+
*
|
|
54
|
+
* Use this when you want to set defaults for mode, max_results, excerpts,
|
|
55
|
+
* source_policy, or fetch_policy in your code, so the LLM only needs to
|
|
56
|
+
* provide objective and search_queries.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const mySearchTool = createSearchTool({
|
|
61
|
+
* mode: 'one-shot',
|
|
62
|
+
* max_results: 5,
|
|
63
|
+
* excerpts: { max_chars_per_result: 5000 },
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
declare function createSearchTool(options?: CreateSearchToolOptions): ai.Tool<{
|
|
68
|
+
objective: string;
|
|
69
|
+
search_queries?: string[] | undefined;
|
|
70
|
+
}, Parallel.Beta.SearchResult>;
|
|
21
71
|
|
|
22
72
|
/**
|
|
23
|
-
*
|
|
73
|
+
* Options for creating a custom extract tool with code-supplied defaults.
|
|
74
|
+
*/
|
|
75
|
+
interface CreateExtractToolOptions {
|
|
76
|
+
/**
|
|
77
|
+
* API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY
|
|
78
|
+
* environment variable.
|
|
79
|
+
*/
|
|
80
|
+
apiKey?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Include excerpts from each URL relevant to the search objective and queries.
|
|
83
|
+
* Can be a boolean or ExcerptSettings object. Defaults to true.
|
|
84
|
+
*/
|
|
85
|
+
excerpts?: boolean | ExcerptSettings;
|
|
86
|
+
/**
|
|
87
|
+
* Include full content from each URL. Can be a boolean or FullContentSettings object.
|
|
88
|
+
* Defaults to false.
|
|
89
|
+
*/
|
|
90
|
+
full_content?: BetaExtractParams['full_content'];
|
|
91
|
+
/**
|
|
92
|
+
* Fetch policy for controlling cached vs fresh content.
|
|
93
|
+
*/
|
|
94
|
+
fetch_policy?: FetchPolicy | null;
|
|
95
|
+
/**
|
|
96
|
+
* Custom tool description. If not provided, uses the default description.
|
|
97
|
+
*/
|
|
98
|
+
description?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Extract tool that mirrors the MCP web_fetch tool.
|
|
102
|
+
* Takes urls and optional objective, returns raw extract response.
|
|
24
103
|
*/
|
|
25
104
|
declare const extractTool: ai.Tool<{
|
|
26
|
-
objective: string;
|
|
27
105
|
urls: string[];
|
|
28
|
-
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
106
|
+
objective?: string | undefined;
|
|
107
|
+
}, Parallel.Beta.ExtractResponse>;
|
|
108
|
+
/**
|
|
109
|
+
* Factory function to create an extract tool with custom defaults.
|
|
110
|
+
*
|
|
111
|
+
* Use this when you want to set defaults for excerpts, full_content, or
|
|
112
|
+
* fetch_policy in your code, so the LLM only needs to provide urls and objective.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* const myExtractTool = createExtractTool({
|
|
117
|
+
* excerpts: { max_chars_per_result: 5000 },
|
|
118
|
+
* full_content: true,
|
|
119
|
+
* });
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
declare function createExtractTool(options?: CreateExtractToolOptions): ai.Tool<{
|
|
123
|
+
urls: string[];
|
|
124
|
+
objective?: string | undefined;
|
|
125
|
+
}, Parallel.Beta.ExtractResponse>;
|
|
37
126
|
|
|
38
|
-
export { extractTool, searchTool };
|
|
127
|
+
export { type CreateExtractToolOptions, type CreateSearchToolOptions, createExtractTool, createSearchTool, extractTool, searchTool };
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,10 @@ var parallelClient = new Proxy({}, {
|
|
|
8
8
|
get(_target, prop) {
|
|
9
9
|
if (!_parallelClient) {
|
|
10
10
|
_parallelClient = new Parallel({
|
|
11
|
-
apiKey: process.env["PARALLEL_API_KEY"]
|
|
11
|
+
apiKey: process.env["PARALLEL_API_KEY"],
|
|
12
|
+
defaultHeaders: {
|
|
13
|
+
"X-Tool-Calling-Package": `npm:@parallel-web/ai-sdk-tools/v${"0.2.1"}`
|
|
14
|
+
}
|
|
12
15
|
});
|
|
13
16
|
}
|
|
14
17
|
return _parallelClient[prop];
|
|
@@ -16,90 +19,77 @@ var parallelClient = new Proxy({}, {
|
|
|
16
19
|
});
|
|
17
20
|
|
|
18
21
|
// src/tools/search.ts
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
case "general":
|
|
24
|
-
return { max_results: 10, max_chars_per_result: 9e3 };
|
|
25
|
-
case "single_page":
|
|
26
|
-
return { max_results: 2, max_chars_per_result: 3e4 };
|
|
27
|
-
case "list":
|
|
28
|
-
default:
|
|
29
|
-
return { max_results: 20, max_chars_per_result: 1500 };
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
var search = async (searchArgs, { abortSignal }) => {
|
|
33
|
-
return await parallelClient.beta.search(
|
|
34
|
-
{
|
|
35
|
-
...searchArgs
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
signal: abortSignal,
|
|
39
|
-
headers: { "parallel-beta": "search-extract-2025-10-10" }
|
|
40
|
-
}
|
|
41
|
-
);
|
|
42
|
-
};
|
|
22
|
+
var objectiveDescription = `Natural-language description of what the web search is trying to find.
|
|
23
|
+
Try to make the search objective atomic, looking for a specific piece of information. May include guidance about preferred sources or freshness.`;
|
|
24
|
+
var searchQueriesDescription = `(optional) List of keyword search queries of 1-6 words, which may include search operators. The search queries should be related to the objective. Limited to 5 entries of 200 characters each.`;
|
|
25
|
+
var modeDescription = `Presets default values for different use cases. "one-shot" returns more comprehensive results and longer excerpts to answer questions from a single response, while "agentic" returns more concise, token-efficient results for use in an agentic loop. Defaults to "agentic".`;
|
|
43
26
|
var searchTool = tool({
|
|
44
|
-
description: `
|
|
45
|
-
web_search_parallel tool returns ranked, extended web excerpts optimized for LLMs.
|
|
46
|
-
Intelligently scale the number of web_search_parallel tool calls to get more information
|
|
47
|
-
when needed, from a single call for simple factual questions to five or more calls for
|
|
48
|
-
complex research questions.
|
|
27
|
+
description: `Purpose: Perform web searches and return results in an LLM-friendly format.
|
|
49
28
|
|
|
50
|
-
|
|
51
|
-
queries and medium context, then add words to narrow results or use high context
|
|
52
|
-
if needed.
|
|
53
|
-
* Include broader context about what the search is trying to accomplish in the
|
|
54
|
-
\`objective\` field. This helps the search engine understand the user's intent and
|
|
55
|
-
provide relevant results and excerpts.
|
|
56
|
-
* Never repeat similar search queries - make every query unique. If initial results are
|
|
57
|
-
insufficient, reformulate queries to obtain new and better results.
|
|
58
|
-
|
|
59
|
-
How to use:
|
|
60
|
-
- For simple queries, a one-shot call to depth is usually sufficient.
|
|
61
|
-
- For complex multi-hop queries, first try to use breadth to narrow down sources. Then
|
|
62
|
-
use other search types with include_domains to get more detailed results.`,
|
|
29
|
+
Use the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`,
|
|
63
30
|
inputSchema: z.object({
|
|
64
|
-
objective: z.string().describe(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
freshness guidance here. Limit to 200 characters. This should reflect the end goal so
|
|
68
|
-
that the tool can better understand the intent and return the best results. Do not
|
|
69
|
-
dump long texts.`
|
|
70
|
-
),
|
|
71
|
-
search_type: z.enum(["list", "general", "single_page", "targeted"]).describe(
|
|
72
|
-
`Can be "list", "general", "single_page" or "targeted".
|
|
73
|
-
"list" should be used for searching for data broadly, like aggregating data or
|
|
74
|
-
considering multiple sources or doing broad initial research. "targeted" should be
|
|
75
|
-
used for searching for data from a specific source set. "general" is a catch all case
|
|
76
|
-
if there is no specific use case from list or targeted. "single_page" extracts data
|
|
77
|
-
from a single page - extremely targeted. If there is a specific webpage you want the
|
|
78
|
-
data from, use "single_page" and mention the URL in the objective.
|
|
79
|
-
Use search_type appropriately.`
|
|
80
|
-
).optional().default("list"),
|
|
81
|
-
search_queries: z.array(z.string()).optional().describe(
|
|
82
|
-
`(optional) List of keyword search queries of 1-6
|
|
83
|
-
words, which may include search operators. The search queries should be related to the
|
|
84
|
-
objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are
|
|
85
|
-
ideal.`
|
|
86
|
-
),
|
|
87
|
-
include_domains: z.array(z.string()).optional().describe(`(optional) List of valid URL domains to explicitly
|
|
88
|
-
focus on for the search. This will restrict all search results to only include results
|
|
89
|
-
from the provided list. This is useful when you want to only use a specific set of
|
|
90
|
-
sources. example: ["google.com", "wikipedia.org"]. Maximum 10 entries.`)
|
|
31
|
+
objective: z.string().describe(objectiveDescription),
|
|
32
|
+
search_queries: z.array(z.string()).optional().describe(searchQueriesDescription),
|
|
33
|
+
mode: z.enum(["agentic", "one-shot"]).optional().default("agentic").describe(modeDescription)
|
|
91
34
|
}),
|
|
92
|
-
execute: async function({
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
|
|
35
|
+
execute: async function({ objective, search_queries, mode }, { abortSignal }) {
|
|
36
|
+
return await parallelClient.beta.search(
|
|
37
|
+
{
|
|
38
|
+
objective,
|
|
39
|
+
search_queries,
|
|
40
|
+
mode
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
signal: abortSignal
|
|
44
|
+
}
|
|
96
45
|
);
|
|
97
|
-
return {
|
|
98
|
-
searchParams: args,
|
|
99
|
-
answer: results
|
|
100
|
-
};
|
|
101
46
|
}
|
|
102
47
|
});
|
|
48
|
+
var defaultSearchDescription = `Purpose: Perform web searches and return results in an LLM-friendly format.
|
|
49
|
+
|
|
50
|
+
Use the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`;
|
|
51
|
+
function createSearchTool(options = {}) {
|
|
52
|
+
const {
|
|
53
|
+
apiKey,
|
|
54
|
+
mode: defaultMode = "agentic",
|
|
55
|
+
max_results,
|
|
56
|
+
excerpts,
|
|
57
|
+
source_policy,
|
|
58
|
+
fetch_policy,
|
|
59
|
+
description = defaultSearchDescription
|
|
60
|
+
} = options;
|
|
61
|
+
const client = apiKey ? new Parallel({
|
|
62
|
+
apiKey,
|
|
63
|
+
defaultHeaders: {
|
|
64
|
+
"X-Tool-Calling-Package": `npm:@parallel-web/ai-sdk-tools/v${"0.2.1"}`
|
|
65
|
+
}
|
|
66
|
+
}) : parallelClient;
|
|
67
|
+
return tool({
|
|
68
|
+
description,
|
|
69
|
+
inputSchema: z.object({
|
|
70
|
+
objective: z.string().describe(objectiveDescription),
|
|
71
|
+
search_queries: z.array(z.string()).optional().describe(searchQueriesDescription)
|
|
72
|
+
}),
|
|
73
|
+
execute: async function({ objective, search_queries }, { abortSignal }) {
|
|
74
|
+
return await client.beta.search(
|
|
75
|
+
{
|
|
76
|
+
objective,
|
|
77
|
+
search_queries,
|
|
78
|
+
mode: defaultMode,
|
|
79
|
+
max_results,
|
|
80
|
+
excerpts,
|
|
81
|
+
source_policy,
|
|
82
|
+
fetch_policy
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
signal: abortSignal
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
var urlsDescription = `List of URLs to extract content from. Must be valid HTTP/HTTPS URLs. Maximum 10 URLs per request.`;
|
|
92
|
+
var objectiveDescription2 = `Natural-language description of what information you're looking for from the URLs.`;
|
|
103
93
|
var extractTool = tool({
|
|
104
94
|
description: `Purpose: Fetch and extract relevant content from specific web URLs.
|
|
105
95
|
|
|
@@ -107,36 +97,63 @@ Ideal Use Cases:
|
|
|
107
97
|
- Extracting content from specific URLs you've already identified
|
|
108
98
|
- Exploring URLs returned by a web search in greater depth`,
|
|
109
99
|
inputSchema: z.object({
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
Limit to 200 characters.`
|
|
113
|
-
),
|
|
114
|
-
urls: z.array(z.string()).describe(
|
|
115
|
-
`List of URLs to extract content from. Must be valid
|
|
116
|
-
HTTP/HTTPS URLs. Maximum 10 URLs per request.`
|
|
117
|
-
),
|
|
118
|
-
search_queries: z.array(z.string()).optional().describe(
|
|
119
|
-
`(optional) List of keyword search queries of 1-6
|
|
120
|
-
words, which may include search operators. The search queries should be related to the
|
|
121
|
-
objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are
|
|
122
|
-
ideal.`
|
|
123
|
-
)
|
|
100
|
+
urls: z.array(z.string()).describe(urlsDescription),
|
|
101
|
+
objective: z.string().optional().describe(objectiveDescription2)
|
|
124
102
|
}),
|
|
125
|
-
execute: async function({
|
|
126
|
-
|
|
127
|
-
{
|
|
103
|
+
execute: async function({ urls, objective }, { abortSignal }) {
|
|
104
|
+
return await parallelClient.beta.extract(
|
|
105
|
+
{
|
|
106
|
+
urls,
|
|
107
|
+
objective
|
|
108
|
+
},
|
|
128
109
|
{
|
|
129
|
-
signal: abortSignal
|
|
130
|
-
headers: { "parallel-beta": "search-extract-2025-10-10" }
|
|
110
|
+
signal: abortSignal
|
|
131
111
|
}
|
|
132
112
|
);
|
|
133
|
-
return {
|
|
134
|
-
searchParams: args,
|
|
135
|
-
answer: results
|
|
136
|
-
};
|
|
137
113
|
}
|
|
138
114
|
});
|
|
115
|
+
var defaultExtractDescription = `Purpose: Fetch and extract relevant content from specific web URLs.
|
|
116
|
+
|
|
117
|
+
Ideal Use Cases:
|
|
118
|
+
- Extracting content from specific URLs you've already identified
|
|
119
|
+
- Exploring URLs returned by a web search in greater depth`;
|
|
120
|
+
function createExtractTool(options = {}) {
|
|
121
|
+
const {
|
|
122
|
+
apiKey,
|
|
123
|
+
excerpts,
|
|
124
|
+
full_content,
|
|
125
|
+
fetch_policy,
|
|
126
|
+
description = defaultExtractDescription
|
|
127
|
+
} = options;
|
|
128
|
+
const client = apiKey ? new Parallel({
|
|
129
|
+
apiKey,
|
|
130
|
+
defaultHeaders: {
|
|
131
|
+
"X-Tool-Calling-Package": `npm:@parallel-web/ai-sdk-tools/v${"0.2.1"}`
|
|
132
|
+
}
|
|
133
|
+
}) : parallelClient;
|
|
134
|
+
return tool({
|
|
135
|
+
description,
|
|
136
|
+
inputSchema: z.object({
|
|
137
|
+
urls: z.array(z.string()).describe(urlsDescription),
|
|
138
|
+
objective: z.string().optional().describe(objectiveDescription2)
|
|
139
|
+
}),
|
|
140
|
+
execute: async function({ urls, objective }, { abortSignal }) {
|
|
141
|
+
return await client.beta.extract(
|
|
142
|
+
{
|
|
143
|
+
urls,
|
|
144
|
+
objective,
|
|
145
|
+
excerpts,
|
|
146
|
+
full_content,
|
|
147
|
+
fetch_policy
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
signal: abortSignal
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
139
156
|
|
|
140
|
-
export { extractTool, searchTool };
|
|
157
|
+
export { createExtractTool, createSearchTool, extractTool, searchTool };
|
|
141
158
|
//# sourceMappingURL=index.js.map
|
|
142
159
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/tools/search.ts","../src/tools/extract.ts"],"names":["tool","z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared Parallel Web client instance\n */\n\nimport { Parallel } from 'parallel-web';\n\nlet _parallelClient: Parallel | null = null;\n\nexport const parallelClient = new Proxy({} as Parallel, {\n get(_target, prop) {\n if (!_parallelClient) {\n _parallelClient = new Parallel({\n apiKey: process.env['PARALLEL_API_KEY'],\n });\n }\n return (_parallelClient as any)[prop];\n },\n});\n","/**\n * Search tool for Parallel Web\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { BetaSearchParams } from 'parallel-web/resources/beta/beta.mjs';\nimport { parallelClient } from '../client.js';\n\nfunction getSearchParams(\n search_type: 'list' | 'targeted' | 'general' | 'single_page'\n): Pick<BetaSearchParams, 'max_results' | 'max_chars_per_result'> {\n switch (search_type) {\n case 'targeted':\n return { max_results: 5, max_chars_per_result: 16000 };\n case 'general':\n return { max_results: 10, max_chars_per_result: 9000 };\n case 'single_page':\n return { max_results: 2, max_chars_per_result: 30000 };\n case 'list':\n default:\n return { max_results: 20, max_chars_per_result: 1500 };\n }\n}\n\nconst search = async (\n searchArgs: BetaSearchParams,\n { abortSignal }: { abortSignal: AbortSignal | undefined }\n) => {\n return await parallelClient.beta.search(\n {\n ...searchArgs,\n },\n {\n signal: abortSignal,\n headers: { 'parallel-beta': 'search-extract-2025-10-10' },\n }\n );\n};\n\nexport const searchTool = tool({\n description: `Use the web_search_parallel tool to access information from the web. The\nweb_search_parallel tool returns ranked, extended web excerpts optimized for LLMs.\nIntelligently scale the number of web_search_parallel tool calls to get more information\nwhen needed, from a single call for simple factual questions to five or more calls for\ncomplex research questions.\n\n* Keep queries concise - 1-6 words for best results. Start broad with very short\n queries and medium context, then add words to narrow results or use high context\n if needed.\n* Include broader context about what the search is trying to accomplish in the\n \\`objective\\` field. This helps the search engine understand the user's intent and\n provide relevant results and excerpts.\n* Never repeat similar search queries - make every query unique. If initial results are\n insufficient, reformulate queries to obtain new and better results.\n\nHow to use:\n- For simple queries, a one-shot call to depth is usually sufficient.\n- For complex multi-hop queries, first try to use breadth to narrow down sources. Then\nuse other search types with include_domains to get more detailed results.`,\n inputSchema: z.object({\n objective: z.string().describe(\n `Natural-language description of what the web research goal\n is. Specify the broad intent of the search query here. Also include any source or\n freshness guidance here. Limit to 200 characters. This should reflect the end goal so\n that the tool can better understand the intent and return the best results. Do not\n dump long texts.`\n ),\n search_type: z\n .enum(['list', 'general', 'single_page', 'targeted'])\n .describe(\n `Can be \"list\", \"general\", \"single_page\" or \"targeted\".\n \"list\" should be used for searching for data broadly, like aggregating data or\n considering multiple sources or doing broad initial research. \"targeted\" should be\n used for searching for data from a specific source set. \"general\" is a catch all case\n if there is no specific use case from list or targeted. \"single_page\" extracts data\n from a single page - extremely targeted. If there is a specific webpage you want the\n data from, use \"single_page\" and mention the URL in the objective.\n Use search_type appropriately.`\n )\n .optional()\n .default('list'),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(\n `(optional) List of keyword search queries of 1-6\n words, which may include search operators. The search queries should be related to the\n objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are\n ideal.`\n ),\n include_domains: z.array(z.string()).optional()\n .describe(`(optional) List of valid URL domains to explicitly\n focus on for the search. This will restrict all search results to only include results\n from the provided list. This is useful when you want to only use a specific set of\n sources. example: [\"google.com\", \"wikipedia.org\"]. Maximum 10 entries.`),\n }),\n\n execute: async function ({ ...args }, { abortSignal }) {\n const results = await search(\n { ...args, ...getSearchParams(args.search_type) },\n { abortSignal }\n );\n\n return {\n searchParams: args,\n answer: results,\n };\n },\n});\n","/**\n * Extract tool for Parallel Web\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { parallelClient } from '../client.js';\n\nexport const extractTool = tool({\n description: `Purpose: Fetch and extract relevant content from specific web URLs.\n\nIdeal Use Cases:\n- Extracting content from specific URLs you've already identified\n- Exploring URLs returned by a web search in greater depth`,\n inputSchema: z.object({\n objective: z.string().describe(\n `Natural-language description of what information you're looking for from the URLs. \n Limit to 200 characters.`\n ),\n\n urls: z.array(z.string()).describe(\n `List of URLs to extract content from. Must be valid\nHTTP/HTTPS URLs. Maximum 10 URLs per request.`\n ),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(\n `(optional) List of keyword search queries of 1-6\n words, which may include search operators. The search queries should be related to the\n objective. Limited to 5 entries of 200 characters each. Usually 1-3 queries are\n ideal.`\n ),\n }),\n\n execute: async function ({ ...args }, { abortSignal }) {\n const results = await parallelClient.beta.extract(\n { ...args },\n {\n signal: abortSignal,\n headers: { 'parallel-beta': 'search-extract-2025-10-10' },\n }\n );\n\n return {\n searchParams: args,\n answer: results,\n };\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/tools/search.ts","../src/tools/extract.ts"],"names":["Parallel","objectiveDescription","tool","z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shared Parallel Web client instance\n */\n\ndeclare const __PACKAGE_VERSION__: string;\n\nimport { Parallel } from 'parallel-web';\n\nlet _parallelClient: Parallel | null = null;\n\nexport const parallelClient = new Proxy({} as Parallel, {\n get(_target, prop: keyof Parallel) {\n if (!_parallelClient) {\n _parallelClient = new Parallel({\n apiKey: process.env['PARALLEL_API_KEY'],\n defaultHeaders: {\n 'X-Tool-Calling-Package': `npm:@parallel-web/ai-sdk-tools/v${__PACKAGE_VERSION__ ?? '0.0.0'}`,\n },\n });\n }\n return _parallelClient[prop];\n },\n});\n","/**\n * Search tool for Parallel Web\n */\n\ndeclare const __PACKAGE_VERSION__: string;\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { Parallel } from 'parallel-web';\nimport type {\n ExcerptSettings,\n FetchPolicy,\n} from 'parallel-web/resources/beta/beta.mjs';\nimport type { SourcePolicy } from 'parallel-web/resources/shared.mjs';\nimport { parallelClient } from '../client.js';\n\n/**\n * Options for creating a custom search tool with code-supplied defaults.\n */\nexport interface CreateSearchToolOptions {\n /**\n * API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY\n * environment variable.\n */\n apiKey?: string;\n\n /**\n * Default mode for search. 'agentic' returns concise, token-efficient results\n * for multi-step workflows. 'one-shot' returns comprehensive results with\n * longer excerpts. Defaults to 'agentic'.\n */\n mode?: 'agentic' | 'one-shot';\n\n /**\n * Maximum number of search results to return. Defaults to 10.\n */\n max_results?: number;\n\n /**\n * Excerpt settings for controlling excerpt length.\n */\n excerpts?: ExcerptSettings;\n\n /**\n * Source policy for controlling which domains to include/exclude and freshness.\n */\n source_policy?: SourcePolicy | null;\n\n /**\n * Fetch policy for controlling cached vs fresh content.\n */\n fetch_policy?: FetchPolicy | null;\n\n /**\n * Custom tool description. If not provided, uses the default description.\n */\n description?: string;\n}\n\nconst objectiveDescription = `Natural-language description of what the web search is trying to find.\nTry to make the search objective atomic, looking for a specific piece of information. May include guidance about preferred sources or freshness.`;\n\nconst searchQueriesDescription = `(optional) List of keyword search queries of 1-6 words, which may include search operators. The search queries should be related to the objective. Limited to 5 entries of 200 characters each.`;\n\nconst modeDescription = `Presets default values for different use cases. \"one-shot\" returns more comprehensive results and longer excerpts to answer questions from a single response, while \"agentic\" returns more concise, token-efficient results for use in an agentic loop. Defaults to \"agentic\".`;\n\n/**\n * Search tool that mirrors the MCP web_search_preview tool.\n * Takes objective and optional search_queries/mode, returns raw search response.\n */\nexport const searchTool = tool({\n description: `Purpose: Perform web searches and return results in an LLM-friendly format.\n\nUse the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`,\n inputSchema: z.object({\n objective: z.string().describe(objectiveDescription),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(searchQueriesDescription),\n mode: z\n .enum(['agentic', 'one-shot'])\n .optional()\n .default('agentic')\n .describe(modeDescription),\n }),\n\n execute: async function (\n { objective, search_queries, mode },\n { abortSignal }\n ) {\n return await parallelClient.beta.search(\n {\n objective,\n search_queries,\n mode,\n },\n {\n signal: abortSignal,\n }\n );\n },\n});\n\nconst defaultSearchDescription = `Purpose: Perform web searches and return results in an LLM-friendly format.\n\nUse the web search tool to search the web and access information from the web. The tool returns ranked, extended web excerpts optimized for LLMs.`;\n\n/**\n * Factory function to create a search tool with custom defaults.\n *\n * Use this when you want to set defaults for mode, max_results, excerpts,\n * source_policy, or fetch_policy in your code, so the LLM only needs to\n * provide objective and search_queries.\n *\n * @example\n * ```ts\n * const mySearchTool = createSearchTool({\n * mode: 'one-shot',\n * max_results: 5,\n * excerpts: { max_chars_per_result: 5000 },\n * });\n * ```\n */\nexport function createSearchTool(options: CreateSearchToolOptions = {}) {\n const {\n apiKey,\n mode: defaultMode = 'agentic',\n max_results,\n excerpts,\n source_policy,\n fetch_policy,\n description = defaultSearchDescription,\n } = options;\n\n const client = apiKey\n ? new Parallel({\n apiKey,\n defaultHeaders: {\n 'X-Tool-Calling-Package': `npm:@parallel-web/ai-sdk-tools/v${__PACKAGE_VERSION__ ?? '0.0.0'}`,\n },\n })\n : parallelClient;\n\n return tool({\n description,\n inputSchema: z.object({\n objective: z.string().describe(objectiveDescription),\n search_queries: z\n .array(z.string())\n .optional()\n .describe(searchQueriesDescription),\n }),\n\n execute: async function ({ objective, search_queries }, { abortSignal }) {\n return await client.beta.search(\n {\n objective,\n search_queries,\n mode: defaultMode,\n max_results,\n excerpts,\n source_policy,\n fetch_policy,\n },\n {\n signal: abortSignal,\n }\n );\n },\n });\n}\n","/**\n * Extract tool for Parallel Web\n */\n\ndeclare const __PACKAGE_VERSION__: string;\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { Parallel } from 'parallel-web';\nimport type {\n ExcerptSettings,\n FetchPolicy,\n BetaExtractParams,\n} from 'parallel-web/resources/beta/beta.mjs';\nimport { parallelClient } from '../client.js';\n\n/**\n * Options for creating a custom extract tool with code-supplied defaults.\n */\nexport interface CreateExtractToolOptions {\n /**\n * API key for Parallel Web. If not provided, falls back to PARALLEL_API_KEY\n * environment variable.\n */\n apiKey?: string;\n\n /**\n * Include excerpts from each URL relevant to the search objective and queries.\n * Can be a boolean or ExcerptSettings object. Defaults to true.\n */\n excerpts?: boolean | ExcerptSettings;\n\n /**\n * Include full content from each URL. Can be a boolean or FullContentSettings object.\n * Defaults to false.\n */\n full_content?: BetaExtractParams['full_content'];\n\n /**\n * Fetch policy for controlling cached vs fresh content.\n */\n fetch_policy?: FetchPolicy | null;\n\n /**\n * Custom tool description. If not provided, uses the default description.\n */\n description?: string;\n}\n\nconst urlsDescription = `List of URLs to extract content from. Must be valid HTTP/HTTPS URLs. Maximum 10 URLs per request.`;\n\nconst objectiveDescription = `Natural-language description of what information you're looking for from the URLs.`;\n\n/**\n * Extract tool that mirrors the MCP web_fetch tool.\n * Takes urls and optional objective, returns raw extract response.\n */\nexport const extractTool = tool({\n description: `Purpose: Fetch and extract relevant content from specific web URLs.\n\nIdeal Use Cases:\n- Extracting content from specific URLs you've already identified\n- Exploring URLs returned by a web search in greater depth`,\n inputSchema: z.object({\n urls: z.array(z.string()).describe(urlsDescription),\n objective: z.string().optional().describe(objectiveDescription),\n }),\n\n execute: async function (\n { urls, objective }: { urls: string[]; objective?: string },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\n return await parallelClient.beta.extract(\n {\n urls,\n objective,\n },\n {\n signal: abortSignal,\n }\n );\n },\n});\n\nconst defaultExtractDescription = `Purpose: Fetch and extract relevant content from specific web URLs.\n\nIdeal Use Cases:\n- Extracting content from specific URLs you've already identified\n- Exploring URLs returned by a web search in greater depth`;\n\n/**\n * Factory function to create an extract tool with custom defaults.\n *\n * Use this when you want to set defaults for excerpts, full_content, or\n * fetch_policy in your code, so the LLM only needs to provide urls and objective.\n *\n * @example\n * ```ts\n * const myExtractTool = createExtractTool({\n * excerpts: { max_chars_per_result: 5000 },\n * full_content: true,\n * });\n * ```\n */\nexport function createExtractTool(options: CreateExtractToolOptions = {}) {\n const {\n apiKey,\n excerpts,\n full_content,\n fetch_policy,\n description = defaultExtractDescription,\n } = options;\n\n const client = apiKey\n ? new Parallel({\n apiKey,\n defaultHeaders: {\n 'X-Tool-Calling-Package': `npm:@parallel-web/ai-sdk-tools/v${__PACKAGE_VERSION__ ?? '0.0.0'}`,\n },\n })\n : parallelClient;\n\n return tool({\n description,\n inputSchema: z.object({\n urls: z.array(z.string()).describe(urlsDescription),\n objective: z.string().optional().describe(objectiveDescription),\n }),\n\n execute: async function (\n { urls, objective }: { urls: string[]; objective?: string },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\n return await client.beta.extract(\n {\n urls,\n objective,\n excerpts,\n full_content,\n fetch_policy,\n },\n {\n signal: abortSignal,\n }\n );\n },\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parallel-web/ai-sdk-tools",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "AI SDK tools for Parallel Web",
|
|
5
5
|
"author": "Parallel Web",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,15 +34,15 @@
|
|
|
34
34
|
],
|
|
35
35
|
"repository": {
|
|
36
36
|
"type": "git",
|
|
37
|
-
"url": "https://github.com/parallel-web/parallel-npm-packages",
|
|
37
|
+
"url": "git+https://github.com/parallel-web/parallel-npm-packages.git",
|
|
38
38
|
"directory": "packages/ai-sdk-tools"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"parallel-web": "^0.
|
|
45
|
-
"zod": "^3.
|
|
44
|
+
"parallel-web": "^0.3.1",
|
|
45
|
+
"zod": "^4.3.6"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"ai": "^5.0.0"
|