Skip to content

Commit e09a8b8

Browse files
authored
fix(parallel): migrate search and extract to V1 and fix deep research schema (#7612)
* fix(parallel): migrate search and extract to V1 and fix deep research schema - Search and Extract targeted the retired /v1beta endpoints; both now use /v1 with the advanced_settings request shape, V1 modes (turbo, fast, basic, advanced), and mode-aware hosted-key pricing. Retired one-shot/agentic modes are remapped and an objective-only workflow falls back to the objective as its query so saved blocks keep working - Extract drops the removed excerpts toggle (V1 always returns excerpts), nests full_content under advanced_settings, surfaces the per-URL errors array, and fails cleanly when every URL errored - Deep research sent output_schema as a bare string, which Parallel treats as a text schema, and read status from the wrong path so it always reported completed. It now offers an Output Format choice (markdown report by default, structured JSON on Pro+), sends the object-form schema, reads run.status, and passes a timeout to the blocking result endpoint - Processor dropdown lists the documented tiers; subblock migration for the removed toggle; regenerated tool metadata and docs; unit tests for request shapes, pricing, and block mapping * fix(parallel): move the Pi web_search Parallel request to V1 and drop any in tests - The Pi web_search host and sandbox request builders still targeted /v1beta/search with the beta header and an objective-only body, which the V1 tool now rejects because search_queries is required. Both send the query as the single search query plus objective, with max_results under advanced_settings, so the parity test holds again - Test helpers return Record<string, unknown> instead of any
1 parent a0b120c commit e09a8b8

14 files changed

Lines changed: 580 additions & 189 deletions

File tree

apps/docs/content/docs/integrations/parallel_ai.mdx

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ Search the web using Parallel AI. Provides comprehensive search results with int
4343

4444
| Parameter | Type | Required | Description |
4545
| --------- | ---- | -------- | ----------- |
46-
| `objective` | string | Yes | The search objective or question to answer |
47-
| `search_queries` | string | No | Comma-separated list of search queries to execute |
48-
| `mode` | string | No | Search mode: one-shot, agentic, or fast \(default: one-shot\) |
49-
| `max_results` | number | No | Maximum number of results to return \(default: 10\) |
50-
| `max_chars_per_result` | number | No | Maximum characters per result excerpt \(minimum: 1000\) |
46+
| `search_queries` | string | Yes | Comma-separated list of concise keyword search queries \(3-6 words each\). At least one is required |
47+
| `objective` | string | No | Natural-language description of the search intent used to rank and excerpt results |
48+
| `mode` | string | No | Search mode: turbo, fast, basic, or advanced \(default: advanced\) |
49+
| `max_results` | number | No | Maximum number of results to return \(default: 10, max: 20\) |
50+
| `max_chars_per_result` | number | No | Maximum characters of excerpts per result |
5151
| `include_domains` | string | No | Comma-separated list of domains to restrict search results to |
5252
| `exclude_domains` | string | No | Comma-separated list of domains to exclude from search results |
5353
| `apiKey` | string | Yes | Parallel AI API Key |
@@ -71,10 +71,9 @@ Extract targeted information from specific URLs using Parallel AI. Processes pro
7171

7272
| Parameter | Type | Required | Description |
7373
| --------- | ---- | -------- | ----------- |
74-
| `urls` | string | Yes | Comma-separated list of URLs to extract information from |
75-
| `objective` | string | No | What information to extract from the provided URLs |
76-
| `excerpts` | boolean | No | Include relevant excerpts from the content \(default: true\) |
77-
| `full_content` | boolean | No | Include full page content as markdown \(default: false\) |
74+
| `urls` | string | Yes | Comma-separated list of URLs to extract information from \(up to 20\) |
75+
| `objective` | string | No | What information to extract from the provided URLs \(up to 5,000 characters\) |
76+
| `full_content` | boolean | No | Include full page content as markdown in addition to excerpts \(default: false\) |
7877
| `apiKey` | string | Yes | Parallel AI API Key |
7978

8079
#### Output
@@ -87,7 +86,12 @@ Extract targeted information from specific URLs using Parallel AI. Processes pro
8786
|`title` | string | The title of the page |
8887
|`publish_date` | string | Publication date \(YYYY-MM-DD\) |
8988
|`excerpts` | array | Relevant text excerpts in markdown |
90-
|`full_content` | string | Full page content as markdown |
89+
|`full_content` | string | Full page content as markdown \(only when requested\) |
90+
| `errors` | array | URLs that could not be extracted, with the reason |
91+
|`url` | string | The URL that failed |
92+
|`error_type` | string | Category of the failure |
93+
|`http_status_code` | number | HTTP status returned by the page, if any |
94+
|`content` | string | Error detail |
9195

9296
### Parallel AI Deep Research
9397

@@ -98,7 +102,8 @@ Conduct comprehensive deep research across the web using Parallel AI. Synthesize
98102
| Parameter | Type | Required | Description |
99103
| --------- | ---- | -------- | ----------- |
100104
| `input` | string | Yes | Research query or question \(up to 15,000 characters\) |
101-
| `processor` | string | No | Processing tier: pro, ultra, pro-fast, ultra-fast \(default: pro\) |
105+
| `output_format` | string | No | Output format: text for a markdown report with inline citations, auto for a structured JSON object that needs the pro tier or higher \(default: text\) |
106+
| `processor` | string | No | Processing tier: core, core2x, pro, ultra, ultra2x, ultra4x, ultra8x, or a -fast variant \(default: pro\) |
102107
| `include_domains` | string | No | Comma-separated list of domains to restrict research to \(source policy\) |
103108
| `exclude_domains` | string | No | Comma-separated list of domains to exclude from research \(source policy\) |
104109
| `apiKey` | string | Yes | Parallel AI API Key |
@@ -110,14 +115,14 @@ Conduct comprehensive deep research across the web using Parallel AI. Synthesize
110115
| `status` | string | Task status \(completed, failed, running\) |
111116
| `run_id` | string | Unique ID for this research task |
112117
| `message` | string | Status message |
113-
| `content` | object | Research results \(structured based on output_schema\) |
118+
| `content` | json | Research findings: a markdown report string for the text output format, or a structured object with query-specific keys for the auto format |
114119
| `basis` | array | Citations and sources with reasoning and confidence levels |
115120
|`field` | string | Output field dot-notation path |
116121
|`reasoning` | string | Explanation for the result |
117122
|`citations` | array | Array of sources |
118123
|`url` | string | Source URL |
119124
|`title` | string | Source title |
120125
|`excerpts` | array | Relevant excerpts from the source |
121-
|`confidence` | string | Confidence level \(high, medium\) |
126+
|`confidence` | string | Confidence level \(low, medium, high\) |
122127

123128

apps/sim/blocks/blocks/parallel.ts

Lines changed: 60 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
1919
sentences: {
2020
byOperation: {
2121
search: [
22-
{ text: 'Search the web for', field: 'objective', core: true },
22+
{ text: 'Search the web for', field: 'search_queries', core: true },
2323
{ text: ', limited to', field: 'search_include_domains' },
2424
],
2525
extract: [
@@ -46,19 +46,25 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
4646
value: () => 'search',
4747
},
4848
{
49-
id: 'objective',
50-
title: 'Search Objective',
49+
id: 'search_queries',
50+
title: 'Search Queries',
5151
type: 'long-input',
52-
placeholder: "When was the United Nations established? Prefer UN's websites.",
52+
placeholder:
53+
'Enter concise keyword queries separated by commas (e.g., "Founding year UN", "United Nations established")',
5354
required: true,
5455
condition: { field: 'operation', value: 'search' },
56+
wandConfig: {
57+
enabled: true,
58+
prompt:
59+
'Generate 1-5 concise keyword web search queries (3-6 words each) for the described research goal. Return ONLY the queries as a comma-separated list.',
60+
placeholder: 'Describe what you want to find...',
61+
},
5562
},
5663
{
57-
id: 'search_queries',
58-
title: 'Search Queries',
64+
id: 'objective',
65+
title: 'Search Objective',
5966
type: 'long-input',
60-
placeholder:
61-
'Enter search queries separated by commas (e.g., "Founding year UN", "Year of founding United Nations")',
67+
placeholder: "When was the United Nations established? Prefer UN's websites.",
6268
required: false,
6369
condition: { field: 'operation', value: 'search' },
6470
},
@@ -79,27 +85,13 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
7985
required: false,
8086
condition: { field: 'operation', value: 'extract' },
8187
},
82-
{
83-
id: 'excerpts',
84-
title: 'Include Excerpts',
85-
type: 'dropdown',
86-
options: [
87-
{ label: 'Yes', id: 'true' },
88-
{ label: 'No', id: 'false' },
89-
],
90-
value: () => 'true',
91-
condition: { field: 'operation', value: 'extract' },
92-
},
9388
{
9489
id: 'full_content',
9590
title: 'Include Full Content',
96-
type: 'dropdown',
97-
options: [
98-
{ label: 'Yes', id: 'true' },
99-
{ label: 'No', id: 'false' },
100-
],
101-
value: () => 'false',
91+
type: 'switch',
92+
defaultValue: false,
10293
condition: { field: 'operation', value: 'extract' },
94+
mode: 'advanced',
10395
},
10496
{
10597
id: 'research_input',
@@ -109,16 +101,28 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
109101
required: true,
110102
condition: { field: 'operation', value: 'deep_research' },
111103
},
104+
{
105+
id: 'output_format',
106+
title: 'Output Format',
107+
type: 'dropdown',
108+
options: [
109+
{ label: 'Markdown report', id: 'text' },
110+
{ label: 'Structured JSON (Pro tier or higher)', id: 'auto' },
111+
],
112+
value: () => 'text',
113+
condition: { field: 'operation', value: 'deep_research' },
114+
},
112115
{
113116
id: 'search_mode',
114117
title: 'Search Mode',
115118
type: 'dropdown',
116119
options: [
117-
{ label: 'One-Shot', id: 'one-shot' },
118-
{ label: 'Agentic', id: 'agentic' },
120+
{ label: 'Advanced', id: 'advanced' },
121+
{ label: 'Basic', id: 'basic' },
119122
{ label: 'Fast', id: 'fast' },
123+
{ label: 'Turbo', id: 'turbo' },
120124
],
121-
value: () => 'one-shot',
125+
value: () => 'advanced',
122126
condition: { field: 'operation', value: 'search' },
123127
mode: 'advanced',
124128
},
@@ -163,8 +167,13 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
163167
title: 'Research Processor',
164168
type: 'dropdown',
165169
options: [
170+
{ label: 'Core', id: 'core' },
171+
{ label: 'Core 2x', id: 'core2x' },
166172
{ label: 'Pro', id: 'pro' },
167173
{ label: 'Ultra', id: 'ultra' },
174+
{ label: 'Ultra 2x', id: 'ultra2x' },
175+
{ label: 'Ultra 4x', id: 'ultra4x' },
176+
{ label: 'Ultra 8x', id: 'ultra8x' },
168177
{ label: 'Pro Fast', id: 'pro-fast' },
169178
{ label: 'Ultra Fast', id: 'ultra-fast' },
170179
],
@@ -176,7 +185,7 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
176185
id: 'max_results',
177186
title: 'Max Results',
178187
type: 'short-input',
179-
placeholder: '10',
188+
placeholder: '10 (max 20)',
180189
condition: { field: 'operation', value: 'search' },
181190
mode: 'advanced',
182191
},
@@ -218,18 +227,10 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
218227
const operation = params.operation
219228

220229
if (operation === 'search') {
221-
if (params.search_queries && typeof params.search_queries === 'string') {
222-
const queries = params.search_queries
223-
.split(',')
224-
.map((query: string) => query.trim())
225-
.filter((query: string) => query.length > 0)
226-
if (queries.length > 0) {
227-
result.search_queries = queries
228-
}
229-
}
230-
if (params.search_mode && params.search_mode !== 'one-shot') {
231-
result.mode = params.search_mode
230+
if (!params.search_queries && params.objective) {
231+
result.search_queries = params.objective
232232
}
233+
if (params.search_mode) result.mode = params.search_mode
233234
if (params.max_results) result.max_results = Number(params.max_results)
234235
if (params.max_chars_per_result) {
235236
result.max_chars_per_result = Number(params.max_chars_per_result)
@@ -240,13 +241,13 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
240241

241242
if (operation === 'extract') {
242243
if (params.extract_objective) result.objective = params.extract_objective
243-
result.excerpts = !(params.excerpts === 'false' || params.excerpts === false)
244244
result.full_content = params.full_content === 'true' || params.full_content === true
245245
}
246246

247247
if (operation === 'deep_research') {
248248
if (params.research_input) result.input = params.research_input
249249
if (params.processor) result.processor = params.processor
250+
if (params.output_format) result.output_format = params.output_format
250251
}
251252

252253
return result
@@ -255,18 +256,22 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
255256
},
256257
inputs: {
257258
operation: { type: 'string', description: 'Operation type' },
259+
search_queries: { type: 'string', description: 'Comma-separated keyword search queries' },
258260
objective: { type: 'string', description: 'Search objective or question' },
259-
search_queries: { type: 'string', description: 'Comma-separated search queries' },
260261
urls: { type: 'string', description: 'Comma-separated URLs' },
261262
extract_objective: { type: 'string', description: 'What to extract from URLs' },
262-
excerpts: { type: 'boolean', description: 'Include excerpts' },
263263
full_content: { type: 'boolean', description: 'Include full content' },
264264
research_input: { type: 'string', description: 'Deep research query' },
265+
output_format: {
266+
type: 'string',
267+
description:
268+
'Deep research output format (text for a markdown report, auto for structured JSON; auto needs the pro tier or higher)',
269+
},
265270
include_domains: { type: 'string', description: 'Domains to include (deep research)' },
266271
exclude_domains: { type: 'string', description: 'Domains to exclude (deep research)' },
267272
search_include_domains: { type: 'string', description: 'Domains to include (search)' },
268273
search_exclude_domains: { type: 'string', description: 'Domains to exclude (search)' },
269-
search_mode: { type: 'string', description: 'Search mode (one-shot, agentic, fast)' },
274+
search_mode: { type: 'string', description: 'Search mode (turbo, fast, basic, advanced)' },
270275
processor: { type: 'string', description: 'Research processing tier' },
271276
max_results: { type: 'number', description: 'Maximum number of results' },
272277
max_chars_per_result: { type: 'number', description: 'Maximum characters per result' },
@@ -279,12 +284,18 @@ export const ParallelBlock: BlockConfig<ToolResponse> = {
279284
},
280285
search_id: { type: 'string', description: 'Search request ID (for search)' },
281286
extract_id: { type: 'string', description: 'Extract request ID (for extract)' },
287+
errors: {
288+
type: 'json',
289+
description:
290+
'URLs that could not be extracted (array of url, error_type, http_status_code, content) (for extract)',
291+
},
282292
status: { type: 'string', description: 'Task status (for deep research)' },
283293
run_id: { type: 'string', description: 'Task run ID (for deep research)' },
284294
message: { type: 'string', description: 'Status message (for deep research)' },
285295
content: {
286296
type: 'json',
287-
description: 'Research content (for deep research, structured based on output_schema)',
297+
description:
298+
'Research findings: a markdown report string when Output Format is Markdown report, or a structured object with query-specific keys when it is Structured JSON (for deep research)',
288299
},
289300
basis: {
290301
type: 'json',
@@ -372,27 +383,27 @@ export const ParallelBlockMeta = {
372383
description:
373384
'Run Parallel AI deep research on a company and produce a cited brief covering funding, leadership, and product.',
374385
content:
375-
'# Research Company Brief\n\nGenerate a sourced account brief for a target company.\n\n## Steps\n1. Use the Deep Research operation with a Research Query naming the company and the angles to cover: recent funding, leadership changes, product launches, and notable news.\n2. Choose a processor tier (Pro for balance, Ultra for depth) and optionally constrain Include or Exclude Domains.\n3. Read the structured content plus the basis field for citations and confidence per claim.\n\n## Output\nA brief organized by topic, where every claim links to its source URL from the basis, and note any low-confidence items that need verification.',
386+
'# Research Company Brief\n\nGenerate a sourced account brief for a target company.\n\n## Steps\n1. Use the Deep Research operation with a Research Query naming the company and the angles to cover: recent funding, leadership changes, product launches, and notable news.\n2. Choose an Output Format (Markdown report for prose, Structured JSON for fielded data), a processor tier (Pro for balance, Ultra for depth), and optionally constrain Include or Exclude Domains.\n3. Read the content plus the basis field for citations and confidence per claim.\n\n## Output\nA brief organized by topic, where every claim links to its source URL from the basis, and note any low-confidence items that need verification.',
376387
},
377388
{
378389
name: 'web-search-with-objective',
379390
description:
380391
'Use Parallel AI search to answer a question across the web and return ranked, cited results.',
381392
content:
382-
'# Web Search With Objective\n\nAnswer a factual question grounded in fresh web sources.\n\n## Steps\n1. Use the Search operation and state a clear Objective describing what you want to know and which sources to prefer.\n2. Optionally add specific Search Queries, set a Search Mode (one-shot, agentic, or fast), and limit results with Include or Exclude Domains.\n3. Tune Max Results and Max Chars Per Result for breadth versus depth.\n\n## Output\nA direct answer to the objective followed by the supporting results, each with title, URL, and the relevant excerpt.',
393+
'# Web Search With Objective\n\nAnswer a factual question grounded in fresh web sources.\n\n## Steps\n1. Use the Search operation with one or more concise keyword Search Queries, and optionally an Objective describing what you want to know and which sources to prefer.\n2. Optionally set a Search Mode (turbo, fast, basic, or advanced) and limit results with Include or Exclude Domains.\n3. Tune Max Results and Max Chars Per Result for breadth versus depth.\n\n## Output\nA direct answer to the objective followed by the supporting results, each with title, URL, and the relevant excerpt.',
383394
},
384395
{
385396
name: 'extract-facts-from-urls',
386397
description: 'Use Parallel AI extract to pull structured facts from a list of source URLs.',
387398
content:
388-
'# Extract Facts From URLs\n\nTurn a set of pages into structured data.\n\n## Steps\n1. Use the Extract operation and provide the comma-separated URLs to read.\n2. Set an Extract Objective describing exactly which fields to pull from each page.\n3. Enable Include Excerpts for supporting snippets and Include Full Content only when the whole page text is needed.\n\n## Output\nA normalized record per URL with the requested fields and an excerpt backing each value, plus a note on any URL that could not be parsed.',
399+
'# Extract Facts From URLs\n\nTurn a set of pages into structured data.\n\n## Steps\n1. Use the Extract operation and provide the comma-separated URLs to read.\n2. Set an Extract Objective describing exactly which fields to pull from each page.\n3. Excerpts are always returned; enable Include Full Content only when the whole page text is needed.\n\n## Output\nA normalized record per URL with the requested fields and an excerpt backing each value, plus a note on any URL that could not be parsed.',
389400
},
390401
{
391402
name: 'monitor-competitor-news',
392403
description:
393404
'Search Parallel AI for recent announcements from named competitors and summarize the changes.',
394405
content:
395-
'# Monitor Competitor News\n\nTrack what rivals shipped or announced recently.\n\n## Steps\n1. Use the Search operation with an Objective naming the competitors and the timeframe of interest.\n2. Optionally restrict Include Domains to the competitors official sites and reputable news outlets.\n3. For high-signal hits, follow up with the Extract operation to pull the specific details from each announcement URL.\n\n## Output\nA dated digest grouped by competitor, each item a one-line summary with its source URL and why it matters.',
406+
'# Monitor Competitor News\n\nTrack what rivals shipped or announced recently.\n\n## Steps\n1. Use the Search operation with keyword Search Queries naming each competitor, plus an Objective describing the timeframe of interest.\n2. Optionally restrict Include Domains to the competitors official sites and reputable news outlets.\n3. For high-signal hits, follow up with the Extract operation to pull the specific details from each announcement URL.\n\n## Output\nA dated digest grouped by competitor, each item a one-line summary with its source URL and why it matters.',
396407
},
397408
],
398409
} as const satisfies BlockMeta

0 commit comments

Comments
 (0)