@parallel-web/ai-sdk-tools 0.1.2 → 0.1.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @parallel-web/ai-sdk-tools
2
2
 
3
- AI-SDK tools for Parallel Web with support for Vercel's AI-SDK v4 and v5.
3
+ AI SDK tools for Parallel Web, built for Vercel's AI SDK v5.
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,6 +12,8 @@ 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. If you're using AI SDK v4, see the [AI SDK v4 Implementation](#ai-sdk-v4-implementation) section below.
16
+
15
17
  ## Usage
16
18
 
17
19
  Add `PARALLEL_API_KEY` obtained from [Parallel Platform](https://platform.parallel.ai/settings?tab=api-keys) to your environment variables.
@@ -25,7 +27,7 @@ Add `PARALLEL_API_KEY` obtained from [Parallel Platform](https://platform.parall
25
27
  `extractTool` uses [Parallel's extract API](https://docs.parallel.ai/api-reference/search-and-extract-api-beta/extract) to extract a web-page's content, for a given objective.
26
28
 
27
29
 
28
- ### With AI SDK v5 (Default exports)
30
+ ### Basic Example
29
31
 
30
32
  ```typescript
31
33
  import { openai } from '@ai-sdk/openai';
@@ -38,31 +40,8 @@ const result = streamText({
38
40
  { role: 'user', content: 'What are the latest developments in AI?' }
39
41
  ],
40
42
  tools: {
41
- 'web-search': searchTool as Tool,
42
- 'web-extract': extractTool as Tool,
43
- },
44
- toolChoice: 'auto',
45
- });
46
-
47
- // Stream the response
48
- return result.toDataStreamResponse();
49
- ```
50
-
51
- ### With AI SDK v4
52
-
53
- ```typescript
54
- import { openai } from '@ai-sdk/openai';
55
- import { streamText, type Tool } from 'ai';
56
- import { searchTool, extractTool } from '@parallel-web/ai-sdk-tools/v4';
57
-
58
- const result = streamText({
59
- model: openai('gpt-4o'),
60
- messages: [
61
- { role: 'user', content: 'What are the latest developments in AI?' }
62
- ],
63
- tools: {
64
- 'web-search': searchTool as Tool,
65
- 'web-extract': extractTool as Tool,
43
+ 'web-search': searchTool,
44
+ 'web-extract': extractTool,
66
45
  },
67
46
  toolChoice: 'auto',
68
47
  });
@@ -71,12 +50,9 @@ const result = streamText({
71
50
  return result.toDataStreamResponse();
72
51
  ```
73
52
 
74
-
75
53
  ### Custom Tools
76
54
 
77
55
  You can create custom tools that wrap the Parallel Web API:
78
-
79
- **For AI SDK v5:**
80
56
  ```typescript
81
57
  import { tool, generateText } from 'ai';
82
58
  import { openai } from '@ai-sdk/openai';
@@ -89,7 +65,7 @@ const parallel = new Parallel({
89
65
 
90
66
  const webSearch = tool({
91
67
  description: 'Use this tool to search the web.',
92
- inputSchema: z.object({ // v5 uses inputSchema
68
+ inputSchema: z.object({
93
69
  searchQueries: z.array(z.string()).describe("Search queries"),
94
70
  usersQuestion: z.string().describe("The user's question"),
95
71
  }),
@@ -105,7 +81,12 @@ const webSearch = tool({
105
81
  });
106
82
  ```
107
83
 
108
- **For AI SDK v4:**
84
+ ## AI SDK v4 Implementation
85
+
86
+ If you're using AI SDK v4, you can implement the tools manually using the Parallel Web API. The key difference is that v4 uses `parameters` instead of `inputSchema`.
87
+
88
+ ### Search Tool (v4)
89
+
109
90
  ```typescript
110
91
  import { tool } from 'ai';
111
92
  import { z } from 'zod';
@@ -115,53 +96,114 @@ const parallel = new Parallel({
115
96
  apiKey: process.env.PARALLEL_API_KEY,
116
97
  });
117
98
 
118
- const webSearch = tool({
119
- description: 'Use this tool to search the web.',
120
- parameters: z.object({ // v4 uses parameters
121
- searchQueries: z.array(z.string()).describe("Search queries"),
122
- usersQuestion: z.string().describe("The user's question"),
99
+ function getSearchParams(
100
+ search_type: 'list' | 'targeted' | 'general' | 'single_page'
101
+ ): Pick<BetaSearchParams, 'max_results' | 'max_chars_per_result'> {
102
+ switch (search_type) {
103
+ case 'targeted':
104
+ return {
105
+ max_results: 5,
106
+ max_chars_per_result: 16000
107
+ };
108
+ case 'general':
109
+ return {
110
+ max_results: 10,
111
+ max_chars_per_result: 9000
112
+ };
113
+ case 'single_page':
114
+ return {
115
+ max_results: 2,
116
+ max_chars_per_result: 30000
117
+ };
118
+ case 'list':
119
+ default:
120
+ return {
121
+ max_results: 20,
122
+ max_chars_per_result: 1500
123
+ };
124
+ }
125
+ }
126
+
127
+ const searchTool = tool({
128
+ description: `Use the web_search_parallel tool to access information from the web. The
129
+ web_search_parallel tool returns ranked, extended web excerpts optimized for LLMs.
130
+ Intelligently scale the number of web_search_parallel tool calls to get more information
131
+ when needed, from a single call for simple factual questions to five or more calls for
132
+ complex research questions.`,
133
+ parameters: z.object({ // v4 uses parameters instead of inputSchema
134
+ objective: z.string().describe(
135
+ 'Natural-language description of what the web research goal is.'
136
+ ),
137
+ search_type: z
138
+ .enum(['list', 'general', 'single_page', 'targeted'])
139
+ .optional()
140
+ .default('list'),
141
+ search_queries: z
142
+ .array(z.string())
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.'),
123
149
  }),
124
- execute: async ({ searchQueries, usersQuestion }) => {
125
- const search = await parallel.beta.search({
126
- objective: usersQuestion,
127
- search_queries: searchQueries,
128
- max_results: 3,
129
- max_chars_per_result: 1000,
130
- });
131
- return search.results;
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
+ };
132
162
  },
133
163
  });
134
164
  ```
135
165
 
166
+ ### Extract Tool (v4)
136
167
 
137
- **Note:** This package includes both AI SDK v4 and v5 support via package aliases.
138
-
139
- ## Version Compatibility
140
-
141
- **This package supports both AI SDK v4 and v5.**
142
-
143
- Using npm package aliases, we bundle both `ai@4.x` and `ai@5.x` within the same package, providing compatibility for both versions.
144
-
145
- ### Choose Your Version
146
-
147
- - **AI SDK v5 (Default/Recommended)**
148
- ```typescript
149
- import { searchTool, extractTool } from '@parallel-web/ai-sdk-tools';
150
- // or explicitly
151
- import { searchTool, extractTool } from '@parallel-web/ai-sdk-tools/v5';
152
- ```
153
-
154
- - **AI SDK v4**
155
- ```typescript
156
- import { searchTool, extractTool } from '@parallel-web/ai-sdk-tools/v4';
157
- ```
158
-
159
- ### How It Works
168
+ ```typescript
169
+ import { tool } from 'ai';
170
+ import { z } from 'zod';
171
+ import { Parallel } from 'parallel-web';
160
172
 
161
- The package uses npm package aliases to install both versions:
162
- - `ai-v4`: Maps to `ai@^4.0.0` (uses `parameters` API)
163
- - `ai-v5`: Maps to `ai@^5.0.0` (uses `inputSchema` API)
173
+ const parallel = new Parallel({
174
+ apiKey: process.env.PARALLEL_API_KEY,
175
+ });
164
176
 
165
- Each version has its own implementation that imports from the appropriate aliased package, ensuring compatibility with both SDK versions.
177
+ const extractTool = tool({
178
+ description: `Purpose: Fetch and extract relevant content from specific web URLs.
179
+
180
+ Ideal Use Cases:
181
+ - Extracting content from specific URLs you've already identified
182
+ - Exploring URLs returned by a web search in greater depth`,
183
+ parameters: z.object({ // v4 uses parameters instead of inputSchema
184
+ objective: z.string().describe(
185
+ 'Natural-language description of what information you\'re looking for from the URLs.'
186
+ ),
187
+ urls: z.array(z.string()).describe(
188
+ 'List of URLs to extract content from. Maximum 10 URLs per request.'
189
+ ),
190
+ search_queries: z
191
+ .array(z.string())
192
+ .optional()
193
+ .describe('Optional keyword search queries related to the objective.'),
194
+ }),
195
+ execute: async ({ objective, urls, search_queries }) => {
196
+ const results = await parallel.beta.extract({
197
+ objective,
198
+ urls,
199
+ search_queries,
200
+ });
201
+ return {
202
+ searchParams: { objective, urls, search_queries },
203
+ answer: results,
204
+ };
205
+ },
206
+ });
207
+ ```
166
208
 
167
209
 
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var aiV5 = require('ai-v5');
3
+ var ai = require('ai');
4
4
  var zod = require('zod');
5
5
  var parallelWeb = require('parallel-web');
6
6
 
7
- // src/v5/tools/search.ts
7
+ // src/tools/search.ts
8
8
  var _parallelClient = null;
9
9
  var parallelClient = new Proxy({}, {
10
10
  get(_target, prop) {
@@ -17,7 +17,7 @@ var parallelClient = new Proxy({}, {
17
17
  }
18
18
  });
19
19
 
20
- // src/v5/tools/search.ts
20
+ // src/tools/search.ts
21
21
  function getSearchParams(search_type) {
22
22
  switch (search_type) {
23
23
  case "targeted":
@@ -37,12 +37,12 @@ var search = async (searchArgs, { abortSignal }) => {
37
37
  ...searchArgs
38
38
  },
39
39
  {
40
- signal: abortSignal
41
- // headers: { 'parallel-beta': 'search-extract-2025-10-10' },
40
+ signal: abortSignal,
41
+ headers: { "parallel-beta": "search-extract-2025-10-10" }
42
42
  }
43
43
  );
44
44
  };
45
- var searchTool = aiV5.tool({
45
+ var searchTool = ai.tool({
46
46
  description: `Use the web_search_parallel tool to access information from the web. The
47
47
  web_search_parallel tool returns ranked, extended web excerpts optimized for LLMs.
48
48
  Intelligently scale the number of web_search_parallel tool calls to get more information
@@ -102,7 +102,7 @@ use other search types with include_domains to get more detailed results.`,
102
102
  };
103
103
  }
104
104
  });
105
- var extractTool = aiV5.tool({
105
+ var extractTool = ai.tool({
106
106
  description: `Purpose: Fetch and extract relevant content from specific web URLs.
107
107
 
108
108
  Ideal Use Cases:
@@ -127,10 +127,7 @@ HTTP/HTTPS URLs. Maximum 10 URLs per request.`
127
127
  execute: async function({ ...args }, { abortSignal }) {
128
128
  const results = await parallelClient.beta.extract(
129
129
  { ...args },
130
- {
131
- signal: abortSignal,
132
- headers: { "parallel-beta": "search-extract-2025-10-10" }
133
- }
130
+ { signal: abortSignal, headers: { "parallel-beta": "parallel" } }
134
131
  );
135
132
  return {
136
133
  searchParams: args,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/v5/tools/search.ts","../src/v5/tools/extract.ts"],"names":["Parallel","tool","z"],"mappings":";;;;;;;AAMA,IAAI,eAAA,GAAmC,IAAA;AAEhC,IAAM,cAAA,GAAiB,IAAI,KAAA,CAAM,EAAC,EAAe;AAAA,EACtD,GAAA,CAAI,SAAS,IAAA,EAAM;AACjB,IAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,MAAA,eAAA,GAAkB,IAAIA,oBAAA,CAAS;AAAA,QAC7B,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,kBAAkB;AAAA,OACvC,CAAA;AAAA,IACH;AACA,IAAA,OAAQ,gBAAwB,IAAI,CAAA;AAAA,EACtC;AACF,CAAC,CAAA;;;ACRD,SAAS,gBACP,WAAA,EACgE;AAChE,EAAA,QAAQ,WAAA;AAAa,IACnB,KAAK,UAAA;AACH,MAAA,OAAO,EAAE,WAAA,EAAa,CAAA,EAAG,oBAAA,EAAsB,IAAA,EAAM;AAAA,IACvD,KAAK,SAAA;AACH,MAAA,OAAO,EAAE,WAAA,EAAa,EAAA,EAAI,oBAAA,EAAsB,GAAA,EAAK;AAAA,IACvD,KAAK,aAAA;AACH,MAAA,OAAO,EAAE,WAAA,EAAa,CAAA,EAAG,oBAAA,EAAsB,GAAA,EAAM;AAAA,IACvD,KAAK,MAAA;AAAA,IACL;AACE,MAAA,OAAO,EAAE,WAAA,EAAa,EAAA,EAAI,oBAAA,EAAsB,IAAA,EAAK;AAAA;AAE3D;AAEA,IAAM,MAAA,GAAS,OACb,UAAA,EACA,EAAE,aAAY,KACX;AACH,EAAA,OAAO,MAAM,eAAe,IAAA,CAAK,MAAA;AAAA,IAC/B;AAAA,MACE,GAAG;AAAA,KACL;AAAA,IACA;AAAA,MACE,MAAA,EAAQ;AAAA;AAAA;AAEV,GACF;AACF,CAAA;AAEO,IAAM,aAAqBC,SAAA,CAAK;AAAA,EACrC,WAAA,EAAa,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,yEAAA,CAAA;AAAA,EAmBb,WAAA,EAAaC,MAAE,MAAA,CAAO;AAAA,IACpB,SAAA,EAAWA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAA,MACpB,CAAA;AAAA;AAAA;AAAA;AAAA,iBAAA;AAAA,KAKF;AAAA,IACA,WAAA,EAAaA,MACV,IAAA,CAAK,CAAC,QAAQ,SAAA,EAAW,aAAA,EAAe,UAAU,CAAC,CAAA,CACnD,QAAA;AAAA,MACC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAAA;AAAA,KAQF,CACC,QAAA,EAAS,CACT,OAAA,CAAQ,MAAM,CAAA;AAAA,IACjB,cAAA,EAAgBA,MACb,KAAA,CAAMA,KAAA,CAAE,QAAQ,CAAA,CAChB,UAAS,CACT,QAAA;AAAA,MACC,CAAA;AAAA;AAAA;AAAA,OAAA;AAAA,KAIF;AAAA,IACF,eAAA,EAAiBA,MAAE,KAAA,CAAMA,KAAA,CAAE,QAAQ,CAAA,CAAE,QAAA,EAAS,CAC3C,QAAA,CAAS,CAAA;AAAA;AAAA;AAAA,uEAAA,CAGwD;AAAA,GACrE,CAAA;AAAA,EAED,OAAA,EAAS,eAAgB,EAAE,GAAG,MAAK,EAAG,EAAE,aAAY,EAAG;AACrD,IAAA,MAAM,UAAU,MAAM,MAAA;AAAA,MACpB,EAAE,GAAG,IAAA,EAAM,GAAG,eAAA,CAAgB,IAAA,CAAK,WAAW,CAAA,EAAE;AAAA,MAChD,EAAE,WAAA;AAAY,KAChB;AAEA,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,IAAA;AAAA,MACd,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AACF,CAAC;ACrGM,IAAM,cAAsBD,SAAAA,CAAK;AAAA,EACtC,WAAA,EAAa,CAAA;;AAAA;AAAA;AAAA,0DAAA,CAAA;AAAA,EAKb,WAAA,EAAaC,MAAE,MAAA,CAAO;AAAA,IACpB,SAAA,EAAWA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAA,MACpB,CAAA;AAAA,yBAAA;AAAA,KAEF;AAAA,IAEA,MAAMA,KAAAA,CAAE,KAAA,CAAMA,KAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA;AAAA,MACxB,CAAA;AAAA,6CAAA;AAAA,KAEF;AAAA,IACA,cAAA,EAAgBA,MACb,KAAA,CAAMA,KAAAA,CAAE,QAAQ,CAAA,CAChB,UAAS,CACT,QAAA;AAAA,MACC,CAAA;AAAA;AAAA;AAAA,OAAA;AAAA;AAIF,GACH,CAAA;AAAA,EAED,OAAA,EAAS,eAAgB,EAAE,GAAG,MAAK,EAAG,EAAE,aAAY,EAAG;AACrD,IAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,IAAA,CAAK,OAAA;AAAA,MACxC,EAAE,GAAG,IAAA,EAAK;AAAA,MACV;AAAA,QACE,MAAA,EAAQ,WAAA;AAAA,QACR,OAAA,EAAS,EAAE,eAAA,EAAiB,2BAAA;AAA4B;AAC1D,KACF;AAEA,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,IAAA;AAAA,MACd,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AACF,CAAC","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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\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: ToolV5 = 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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\nimport { z } from 'zod';\nimport { parallelClient } from '../../client.js';\n\nexport const extractTool: ToolV5 = 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"],"mappings":";;;;;;;AAMA,IAAI,eAAA,GAAmC,IAAA;AAEhC,IAAM,cAAA,GAAiB,IAAI,KAAA,CAAM,EAAC,EAAe;AAAA,EACtD,GAAA,CAAI,SAAS,IAAA,EAAM;AACjB,IAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,MAAA,eAAA,GAAkB,IAAIA,oBAAA,CAAS;AAAA,QAC7B,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,kBAAkB;AAAA,OACvC,CAAA;AAAA,IACH;AACA,IAAA,OAAQ,gBAAwB,IAAI,CAAA;AAAA,EACtC;AACF,CAAC,CAAA;;;ACRD,SAAS,gBACP,WAAA,EACgE;AAChE,EAAA,QAAQ,WAAA;AAAa,IACnB,KAAK,UAAA;AACH,MAAA,OAAO,EAAE,WAAA,EAAa,CAAA,EAAG,oBAAA,EAAsB,IAAA,EAAM;AAAA,IACvD,KAAK,SAAA;AACH,MAAA,OAAO,EAAE,WAAA,EAAa,EAAA,EAAI,oBAAA,EAAsB,GAAA,EAAK;AAAA,IACvD,KAAK,aAAA;AACH,MAAA,OAAO,EAAE,WAAA,EAAa,CAAA,EAAG,oBAAA,EAAsB,GAAA,EAAM;AAAA,IACvD,KAAK,MAAA;AAAA,IACL;AACE,MAAA,OAAO,EAAE,WAAA,EAAa,EAAA,EAAI,oBAAA,EAAsB,IAAA,EAAK;AAAA;AAE3D;AAEA,IAAM,MAAA,GAAS,OACb,UAAA,EACA,EAAE,aAAY,KACX;AACH,EAAA,OAAO,MAAM,eAAe,IAAA,CAAK,MAAA;AAAA,IAC/B;AAAA,MACE,GAAG;AAAA,KACL;AAAA,IACA;AAAA,MACE,MAAA,EAAQ,WAAA;AAAA,MACR,OAAA,EAAS,EAAE,eAAA,EAAiB,2BAAA;AAA4B;AAC1D,GACF;AACF,CAAA;AAEO,IAAM,aAAaC,OAAA,CAAK;AAAA,EAC7B,WAAA,EAAa,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,yEAAA,CAAA;AAAA,EAmBb,WAAA,EAAaC,MAAE,MAAA,CAAO;AAAA,IACpB,SAAA,EAAWA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAA,MACpB,CAAA;AAAA;AAAA;AAAA;AAAA,iBAAA;AAAA,KAKF;AAAA,IACA,WAAA,EAAaA,MACV,IAAA,CAAK,CAAC,QAAQ,SAAA,EAAW,aAAA,EAAe,UAAU,CAAC,CAAA,CACnD,QAAA;AAAA,MACC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAAA;AAAA,KAQF,CACC,QAAA,EAAS,CACT,OAAA,CAAQ,MAAM,CAAA;AAAA,IACjB,cAAA,EAAgBA,MACb,KAAA,CAAMA,KAAA,CAAE,QAAQ,CAAA,CAChB,UAAS,CACT,QAAA;AAAA,MACC,CAAA;AAAA;AAAA;AAAA,OAAA;AAAA,KAIF;AAAA,IACF,eAAA,EAAiBA,MAAE,KAAA,CAAMA,KAAA,CAAE,QAAQ,CAAA,CAAE,QAAA,EAAS,CAC3C,QAAA,CAAS,CAAA;AAAA;AAAA;AAAA,uEAAA,CAGwD;AAAA,GACrE,CAAA;AAAA,EAED,OAAA,EAAS,eAAgB,EAAE,GAAG,MAAK,EAAG,EAAE,aAAY,EAAG;AACrD,IAAA,MAAM,UAAU,MAAM,MAAA;AAAA,MACpB,EAAE,GAAG,IAAA,EAAM,GAAG,eAAA,CAAgB,IAAA,CAAK,WAAW,CAAA,EAAE;AAAA,MAChD,EAAE,WAAA;AAAY,KAChB;AAEA,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,IAAA;AAAA,MACd,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AACF,CAAC;ACrGM,IAAM,cAAcD,OAAAA,CAAK;AAAA,EAC9B,WAAA,EAAa,CAAA;;AAAA;AAAA;AAAA,0DAAA,CAAA;AAAA,EAKb,WAAA,EAAaC,MAAE,MAAA,CAAO;AAAA,IACpB,SAAA,EAAWA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAA,MACpB,CAAA;AAAA,yBAAA;AAAA,KAEF;AAAA,IAEA,MAAMA,KAAAA,CAAE,KAAA,CAAMA,KAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA;AAAA,MACxB,CAAA;AAAA,6CAAA;AAAA,KAEF;AAAA,IACA,cAAA,EAAgBA,MACb,KAAA,CAAMA,KAAAA,CAAE,QAAQ,CAAA,CAChB,UAAS,CACT,QAAA;AAAA,MACC,CAAA;AAAA;AAAA;AAAA,OAAA;AAAA;AAIF,GACH,CAAA;AAAA,EAED,OAAA,EAAS,eAAgB,EAAE,GAAG,MAAK,EAAG,EAAE,aAAY,EAAG;AACrD,IAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,IAAA,CAAK,OAAA;AAAA,MACxC,EAAE,GAAG,IAAA,EAAK;AAAA,MACV,EAAE,MAAA,EAAQ,WAAA,EAAa,SAAS,EAAE,eAAA,EAAiB,YAAW;AAAE,KAClE;AAEA,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,IAAA;AAAA,MACd,MAAA,EAAQ;AAAA,KACV;AAAA,EACF;AACF,CAAC","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 { signal: abortSignal, headers: { 'parallel-beta': 'parallel' } }\n );\n\n return {\n searchParams: args,\n answer: results,\n };\n },\n});\n"]}
package/dist/index.d.cts CHANGED
@@ -1,15 +1,38 @@
1
- import { Tool } from 'ai-v5';
1
+ import * as ai from 'ai';
2
+ import * as parallel_web_resources_beta_beta_mjs from 'parallel-web/resources/beta/beta.mjs';
2
3
 
3
4
  /**
4
- * Search tool for Parallel Web (AI SDK v5)
5
+ * Search tool for Parallel Web
5
6
  */
6
-
7
- declare const searchTool: Tool;
7
+ declare const searchTool: ai.Tool<{
8
+ objective: string;
9
+ search_type: "list" | "targeted" | "general" | "single_page";
10
+ search_queries?: string[] | undefined;
11
+ include_domains?: string[] | undefined;
12
+ }, {
13
+ searchParams: {
14
+ objective: string;
15
+ search_type: "list" | "targeted" | "general" | "single_page";
16
+ search_queries?: string[] | undefined;
17
+ include_domains?: string[] | undefined;
18
+ };
19
+ answer: parallel_web_resources_beta_beta_mjs.SearchResult;
20
+ }>;
8
21
 
9
22
  /**
10
- * Extract tool for Parallel Web (AI SDK v5)
23
+ * Extract tool for Parallel Web
11
24
  */
12
-
13
- declare const extractTool: Tool;
25
+ declare const extractTool: ai.Tool<{
26
+ objective: string;
27
+ urls: string[];
28
+ search_queries?: string[] | undefined;
29
+ }, {
30
+ searchParams: {
31
+ objective: string;
32
+ urls: string[];
33
+ search_queries?: string[] | undefined;
34
+ };
35
+ answer: parallel_web_resources_beta_beta_mjs.ExtractResponse;
36
+ }>;
14
37
 
15
38
  export { extractTool, searchTool };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,38 @@
1
- import { Tool } from 'ai-v5';
1
+ import * as ai from 'ai';
2
+ import * as parallel_web_resources_beta_beta_mjs from 'parallel-web/resources/beta/beta.mjs';
2
3
 
3
4
  /**
4
- * Search tool for Parallel Web (AI SDK v5)
5
+ * Search tool for Parallel Web
5
6
  */
6
-
7
- declare const searchTool: Tool;
7
+ declare const searchTool: ai.Tool<{
8
+ objective: string;
9
+ search_type: "list" | "targeted" | "general" | "single_page";
10
+ search_queries?: string[] | undefined;
11
+ include_domains?: string[] | undefined;
12
+ }, {
13
+ searchParams: {
14
+ objective: string;
15
+ search_type: "list" | "targeted" | "general" | "single_page";
16
+ search_queries?: string[] | undefined;
17
+ include_domains?: string[] | undefined;
18
+ };
19
+ answer: parallel_web_resources_beta_beta_mjs.SearchResult;
20
+ }>;
8
21
 
9
22
  /**
10
- * Extract tool for Parallel Web (AI SDK v5)
23
+ * Extract tool for Parallel Web
11
24
  */
12
-
13
- declare const extractTool: Tool;
25
+ declare const extractTool: ai.Tool<{
26
+ objective: string;
27
+ urls: string[];
28
+ search_queries?: string[] | undefined;
29
+ }, {
30
+ searchParams: {
31
+ objective: string;
32
+ urls: string[];
33
+ search_queries?: string[] | undefined;
34
+ };
35
+ answer: parallel_web_resources_beta_beta_mjs.ExtractResponse;
36
+ }>;
14
37
 
15
38
  export { extractTool, searchTool };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { tool } from 'ai-v5';
1
+ import { tool } from 'ai';
2
2
  import { z } from 'zod';
3
3
  import { Parallel } from 'parallel-web';
4
4
 
5
- // src/v5/tools/search.ts
5
+ // src/tools/search.ts
6
6
  var _parallelClient = null;
7
7
  var parallelClient = new Proxy({}, {
8
8
  get(_target, prop) {
@@ -15,7 +15,7 @@ var parallelClient = new Proxy({}, {
15
15
  }
16
16
  });
17
17
 
18
- // src/v5/tools/search.ts
18
+ // src/tools/search.ts
19
19
  function getSearchParams(search_type) {
20
20
  switch (search_type) {
21
21
  case "targeted":
@@ -35,8 +35,8 @@ var search = async (searchArgs, { abortSignal }) => {
35
35
  ...searchArgs
36
36
  },
37
37
  {
38
- signal: abortSignal
39
- // headers: { 'parallel-beta': 'search-extract-2025-10-10' },
38
+ signal: abortSignal,
39
+ headers: { "parallel-beta": "search-extract-2025-10-10" }
40
40
  }
41
41
  );
42
42
  };
@@ -125,10 +125,7 @@ HTTP/HTTPS URLs. Maximum 10 URLs per request.`
125
125
  execute: async function({ ...args }, { abortSignal }) {
126
126
  const results = await parallelClient.beta.extract(
127
127
  { ...args },
128
- {
129
- signal: abortSignal,
130
- headers: { "parallel-beta": "search-extract-2025-10-10" }
131
- }
128
+ { signal: abortSignal, headers: { "parallel-beta": "parallel" } }
132
129
  );
133
130
  return {
134
131
  searchParams: args,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/v5/tools/search.ts","../src/v5/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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\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: ToolV5 = 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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\nimport { z } from 'zod';\nimport { parallelClient } from '../../client.js';\n\nexport const extractTool: ToolV5 = 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":["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 { signal: abortSignal, headers: { 'parallel-beta': 'parallel' } }\n );\n\n return {\n searchParams: args,\n answer: results,\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.2",
3
+ "version": "0.1.3",
4
4
  "description": "AI SDK tools for Parallel Web",
5
5
  "author": "Parallel Web",
6
6
  "license": "MIT",
@@ -13,16 +13,6 @@
13
13
  "types": "./dist/index.d.ts",
14
14
  "import": "./dist/index.js",
15
15
  "require": "./dist/index.cjs"
16
- },
17
- "./v4": {
18
- "types": "./dist/v4.d.ts",
19
- "import": "./dist/v4.js",
20
- "require": "./dist/v4.cjs"
21
- },
22
- "./v5": {
23
- "types": "./dist/v5.d.ts",
24
- "import": "./dist/v5.js",
25
- "require": "./dist/v5.cjs"
26
16
  }
27
17
  },
28
18
  "files": [
@@ -51,12 +41,14 @@
51
41
  "access": "public"
52
42
  },
53
43
  "dependencies": {
54
- "ai-v4": "npm:ai@^4.0.0",
55
- "ai-v5": "npm:ai@^5.0.0",
56
44
  "parallel-web": "^0.2.1",
57
45
  "zod": "^3.23.0"
58
46
  },
47
+ "peerDependencies": {
48
+ "ai": "^5.0.0"
49
+ },
59
50
  "devDependencies": {
60
- "@types/node": "^20.0.0"
51
+ "@types/node": "^20.0.0",
52
+ "ai": "^5.0.0"
61
53
  }
62
54
  }
package/dist/v4.cjs DELETED
@@ -1,145 +0,0 @@
1
- 'use strict';
2
-
3
- var aiV4 = require('ai-v4');
4
- var zod = require('zod');
5
- var parallelWeb = require('parallel-web');
6
-
7
- // src/v4/tools/search.ts
8
- var _parallelClient = null;
9
- var parallelClient = new Proxy({}, {
10
- get(_target, prop) {
11
- if (!_parallelClient) {
12
- _parallelClient = new parallelWeb.Parallel({
13
- apiKey: process.env["PARALLEL_API_KEY"]
14
- });
15
- }
16
- return _parallelClient[prop];
17
- }
18
- });
19
-
20
- // src/v4/tools/search.ts
21
- function getSearchParams(search_type) {
22
- switch (search_type) {
23
- case "targeted":
24
- return { max_results: 5, max_chars_per_result: 16e3 };
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
- };
45
- var searchTool = aiV4.tool({
46
- description: `Use the web_search_parallel tool to access information from the web. The
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.
51
-
52
- * Keep queries concise - 1-6 words for best results. Start broad with very short
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.`,
65
- parameters: zod.z.object({
66
- objective: zod.z.string().describe(
67
- `Natural-language description of what the web research goal
68
- is. Specify the broad intent of the search query here. Also include any source or
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.`)
93
- }),
94
- execute: async function({ ...args }, { abortSignal }) {
95
- const results = await search(
96
- { ...args, ...getSearchParams(args.search_type) },
97
- { abortSignal }
98
- );
99
- return {
100
- searchParams: args,
101
- answer: results
102
- };
103
- }
104
- });
105
- var extractTool = aiV4.tool({
106
- description: `Purpose: Fetch and extract relevant content from specific web URLs.
107
-
108
- Ideal Use Cases:
109
- - Extracting content from specific URLs you've already identified
110
- - Exploring URLs returned by a web search in greater depth`,
111
- parameters: zod.z.object({
112
- objective: zod.z.string().describe(
113
- `Natural-language description of what information you're looking for from the URLs.
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
- )
126
- }),
127
- execute: async function({ ...args }, { abortSignal }) {
128
- const results = await parallelClient.beta.extract(
129
- { ...args },
130
- {
131
- signal: abortSignal,
132
- headers: { "parallel-beta": "search-extract-2025-10-10" }
133
- }
134
- );
135
- return {
136
- searchParams: args,
137
- answer: results
138
- };
139
- }
140
- });
141
-
142
- exports.extractTool = extractTool;
143
- exports.searchTool = searchTool;
144
- //# sourceMappingURL=v4.cjs.map
145
- //# sourceMappingURL=v4.cjs.map
package/dist/v4.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/client.ts","../src/v4/tools/search.ts","../src/v4/tools/extract.ts"],"names":["Parallel","tool","z"],"mappings":"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","file":"v4.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 (AI SDK v4)\n */\n\nimport { tool, type Tool as ToolV4 } from 'ai-v4';\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: ToolV4 = 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 parameters: 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 (\n { ...args },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\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 (AI SDK v4)\n */\n\nimport { tool, type Tool as ToolV4 } from 'ai-v4';\nimport { z } from 'zod';\nimport { parallelClient } from '../../client.js';\n\nexport const extractTool: ToolV4 = 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 parameters: 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 (\n { ...args },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\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"]}
package/dist/v4.d.cts DELETED
@@ -1,15 +0,0 @@
1
- import { Tool } from 'ai-v4';
2
-
3
- /**
4
- * Search tool for Parallel Web (AI SDK v4)
5
- */
6
-
7
- declare const searchTool: Tool;
8
-
9
- /**
10
- * Extract tool for Parallel Web (AI SDK v4)
11
- */
12
-
13
- declare const extractTool: Tool;
14
-
15
- export { extractTool, searchTool };
package/dist/v4.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import { Tool } from 'ai-v4';
2
-
3
- /**
4
- * Search tool for Parallel Web (AI SDK v4)
5
- */
6
-
7
- declare const searchTool: Tool;
8
-
9
- /**
10
- * Extract tool for Parallel Web (AI SDK v4)
11
- */
12
-
13
- declare const extractTool: Tool;
14
-
15
- export { extractTool, searchTool };
package/dist/v4.js DELETED
@@ -1,142 +0,0 @@
1
- import { tool } from 'ai-v4';
2
- import { z } from 'zod';
3
- import { Parallel } from 'parallel-web';
4
-
5
- // src/v4/tools/search.ts
6
- var _parallelClient = null;
7
- var parallelClient = new Proxy({}, {
8
- get(_target, prop) {
9
- if (!_parallelClient) {
10
- _parallelClient = new Parallel({
11
- apiKey: process.env["PARALLEL_API_KEY"]
12
- });
13
- }
14
- return _parallelClient[prop];
15
- }
16
- });
17
-
18
- // src/v4/tools/search.ts
19
- function getSearchParams(search_type) {
20
- switch (search_type) {
21
- case "targeted":
22
- return { max_results: 5, max_chars_per_result: 16e3 };
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
- };
43
- var searchTool = tool({
44
- description: `Use the web_search_parallel tool to access information from the web. The
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.
49
-
50
- * Keep queries concise - 1-6 words for best results. Start broad with very short
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.`,
63
- parameters: z.object({
64
- objective: z.string().describe(
65
- `Natural-language description of what the web research goal
66
- is. Specify the broad intent of the search query here. Also include any source or
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.`)
91
- }),
92
- execute: async function({ ...args }, { abortSignal }) {
93
- const results = await search(
94
- { ...args, ...getSearchParams(args.search_type) },
95
- { abortSignal }
96
- );
97
- return {
98
- searchParams: args,
99
- answer: results
100
- };
101
- }
102
- });
103
- var extractTool = tool({
104
- description: `Purpose: Fetch and extract relevant content from specific web URLs.
105
-
106
- Ideal Use Cases:
107
- - Extracting content from specific URLs you've already identified
108
- - Exploring URLs returned by a web search in greater depth`,
109
- parameters: z.object({
110
- objective: z.string().describe(
111
- `Natural-language description of what information you're looking for from the URLs.
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
- )
124
- }),
125
- execute: async function({ ...args }, { abortSignal }) {
126
- const results = await parallelClient.beta.extract(
127
- { ...args },
128
- {
129
- signal: abortSignal,
130
- headers: { "parallel-beta": "search-extract-2025-10-10" }
131
- }
132
- );
133
- return {
134
- searchParams: args,
135
- answer: results
136
- };
137
- }
138
- });
139
-
140
- export { extractTool, searchTool };
141
- //# sourceMappingURL=v4.js.map
142
- //# sourceMappingURL=v4.js.map
package/dist/v4.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/client.ts","../src/v4/tools/search.ts","../src/v4/tools/extract.ts"],"names":["tool","z"],"mappings":"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","file":"v4.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 (AI SDK v4)\n */\n\nimport { tool, type Tool as ToolV4 } from 'ai-v4';\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: ToolV4 = 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 parameters: 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 (\n { ...args },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\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 (AI SDK v4)\n */\n\nimport { tool, type Tool as ToolV4 } from 'ai-v4';\nimport { z } from 'zod';\nimport { parallelClient } from '../../client.js';\n\nexport const extractTool: ToolV4 = 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 parameters: 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 (\n { ...args },\n { abortSignal }: { abortSignal?: AbortSignal }\n ) {\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"]}
package/dist/v5.cjs DELETED
@@ -1,145 +0,0 @@
1
- 'use strict';
2
-
3
- var aiV5 = require('ai-v5');
4
- var zod = require('zod');
5
- var parallelWeb = require('parallel-web');
6
-
7
- // src/v5/tools/search.ts
8
- var _parallelClient = null;
9
- var parallelClient = new Proxy({}, {
10
- get(_target, prop) {
11
- if (!_parallelClient) {
12
- _parallelClient = new parallelWeb.Parallel({
13
- apiKey: process.env["PARALLEL_API_KEY"]
14
- });
15
- }
16
- return _parallelClient[prop];
17
- }
18
- });
19
-
20
- // src/v5/tools/search.ts
21
- function getSearchParams(search_type) {
22
- switch (search_type) {
23
- case "targeted":
24
- return { max_results: 5, max_chars_per_result: 16e3 };
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
- };
45
- var searchTool = aiV5.tool({
46
- description: `Use the web_search_parallel tool to access information from the web. The
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.
51
-
52
- * Keep queries concise - 1-6 words for best results. Start broad with very short
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.`,
65
- inputSchema: zod.z.object({
66
- objective: zod.z.string().describe(
67
- `Natural-language description of what the web research goal
68
- is. Specify the broad intent of the search query here. Also include any source or
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.`)
93
- }),
94
- execute: async function({ ...args }, { abortSignal }) {
95
- const results = await search(
96
- { ...args, ...getSearchParams(args.search_type) },
97
- { abortSignal }
98
- );
99
- return {
100
- searchParams: args,
101
- answer: results
102
- };
103
- }
104
- });
105
- var extractTool = aiV5.tool({
106
- description: `Purpose: Fetch and extract relevant content from specific web URLs.
107
-
108
- Ideal Use Cases:
109
- - Extracting content from specific URLs you've already identified
110
- - Exploring URLs returned by a web search in greater depth`,
111
- inputSchema: zod.z.object({
112
- objective: zod.z.string().describe(
113
- `Natural-language description of what information you're looking for from the URLs.
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
- )
126
- }),
127
- execute: async function({ ...args }, { abortSignal }) {
128
- const results = await parallelClient.beta.extract(
129
- { ...args },
130
- {
131
- signal: abortSignal,
132
- headers: { "parallel-beta": "search-extract-2025-10-10" }
133
- }
134
- );
135
- return {
136
- searchParams: args,
137
- answer: results
138
- };
139
- }
140
- });
141
-
142
- exports.extractTool = extractTool;
143
- exports.searchTool = searchTool;
144
- //# sourceMappingURL=v5.cjs.map
145
- //# sourceMappingURL=v5.cjs.map
package/dist/v5.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/client.ts","../src/v5/tools/search.ts","../src/v5/tools/extract.ts"],"names":["Parallel","tool","z"],"mappings":"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","file":"v5.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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\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: ToolV5 = 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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\nimport { z } from 'zod';\nimport { parallelClient } from '../../client.js';\n\nexport const extractTool: ToolV5 = 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"]}
package/dist/v5.d.cts DELETED
@@ -1,2 +0,0 @@
1
- export { extractTool, searchTool } from './index.cjs';
2
- import 'ai-v5';
package/dist/v5.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export { extractTool, searchTool } from './index.js';
2
- import 'ai-v5';
package/dist/v5.js DELETED
@@ -1,142 +0,0 @@
1
- import { tool } from 'ai-v5';
2
- import { z } from 'zod';
3
- import { Parallel } from 'parallel-web';
4
-
5
- // src/v5/tools/search.ts
6
- var _parallelClient = null;
7
- var parallelClient = new Proxy({}, {
8
- get(_target, prop) {
9
- if (!_parallelClient) {
10
- _parallelClient = new Parallel({
11
- apiKey: process.env["PARALLEL_API_KEY"]
12
- });
13
- }
14
- return _parallelClient[prop];
15
- }
16
- });
17
-
18
- // src/v5/tools/search.ts
19
- function getSearchParams(search_type) {
20
- switch (search_type) {
21
- case "targeted":
22
- return { max_results: 5, max_chars_per_result: 16e3 };
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
- };
43
- var searchTool = tool({
44
- description: `Use the web_search_parallel tool to access information from the web. The
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.
49
-
50
- * Keep queries concise - 1-6 words for best results. Start broad with very short
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.`,
63
- inputSchema: z.object({
64
- objective: z.string().describe(
65
- `Natural-language description of what the web research goal
66
- is. Specify the broad intent of the search query here. Also include any source or
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.`)
91
- }),
92
- execute: async function({ ...args }, { abortSignal }) {
93
- const results = await search(
94
- { ...args, ...getSearchParams(args.search_type) },
95
- { abortSignal }
96
- );
97
- return {
98
- searchParams: args,
99
- answer: results
100
- };
101
- }
102
- });
103
- var extractTool = tool({
104
- description: `Purpose: Fetch and extract relevant content from specific web URLs.
105
-
106
- Ideal Use Cases:
107
- - Extracting content from specific URLs you've already identified
108
- - Exploring URLs returned by a web search in greater depth`,
109
- inputSchema: z.object({
110
- objective: z.string().describe(
111
- `Natural-language description of what information you're looking for from the URLs.
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
- )
124
- }),
125
- execute: async function({ ...args }, { abortSignal }) {
126
- const results = await parallelClient.beta.extract(
127
- { ...args },
128
- {
129
- signal: abortSignal,
130
- headers: { "parallel-beta": "search-extract-2025-10-10" }
131
- }
132
- );
133
- return {
134
- searchParams: args,
135
- answer: results
136
- };
137
- }
138
- });
139
-
140
- export { extractTool, searchTool };
141
- //# sourceMappingURL=v5.js.map
142
- //# sourceMappingURL=v5.js.map
package/dist/v5.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/client.ts","../src/v5/tools/search.ts","../src/v5/tools/extract.ts"],"names":["tool","z"],"mappings":"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","file":"v5.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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\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: ToolV5 = 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 (AI SDK v5)\n */\n\nimport { tool, type Tool as ToolV5 } from 'ai-v5';\nimport { z } from 'zod';\nimport { parallelClient } from '../../client.js';\n\nexport const extractTool: ToolV5 = 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"]}