Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
cache: npm
- run: npm install --global npm@11.6.0
- run: npm ci
- run: npm run format:check
- run: npm run lint
- run: npm run typecheck
- run: npm test
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
registry-url: https://registry.npmjs.org
- run: npm install --global npm@11.6.0
- run: npm ci
- run: npm run format:check
- run: npm run lint
- run: npm run typecheck
- run: npm test
Expand Down
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist
node_modules
.cache
package-lock.json
2 changes: 1 addition & 1 deletion .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ module.exports = {
quoteProps: 'as-needed',
endOfLine: 'lf',
printWidth: 100,
};
};
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Keep changes focused and preserve the persisted `name`, resource, and operation
Before opening a pull request, run:

```bash
npm run format:check
npm run lint
npm run typecheck
npm test
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ The trigger lifecycle does not register a remote webhook itself; the URL is part

```bash
npm ci
npm run format:check
npm run lint
npm run typecheck
npm test
Expand Down
3 changes: 2 additions & 1 deletion credentials/ParallelApi.credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export class ParallelApi implements ICredentialType {
},
default: '',
required: false,
description: 'Optional webhook secret for validating webhook signatures. Find this in Settings → Webhooks at https://platform.parallel.ai/settings',
description:
'Optional webhook secret for validating webhook signatures. Find this in Settings → Webhooks at https://platform.parallel.ai/settings',
hint: 'Webhook validation ensures secure communication. Get your secret from platform.parallel.ai/settings',
},
];
Expand Down
112 changes: 72 additions & 40 deletions nodes/Parallel/Parallel.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export class Parallel implements INodeType {
icon: { light: 'file:parallel.svg', dark: 'file:parallel.dark.svg' },
group: ['transform'],
version: 1,
subtitle: '={{$parameter["resource"] === "monitor" ? "Monitor / " + $parameter["monitorOperation"] : $parameter["operation"]}}',
subtitle:
'={{$parameter["resource"] === "monitor" ? "Monitor / " + $parameter["monitorOperation"] : $parameter["operation"]}}',
description: 'Highest accuracy web search tools for AI agents',
defaults: {
name: 'Parallel',
Expand Down Expand Up @@ -153,8 +154,10 @@ export class Parallel implements INodeType {
inputType: ['json'],
},
},
default: '{\n "company_name": "Apple Inc.",\n "company_domain": "apple.com",\n "company_ticker": "AAPL"\n}',
description: 'System will expect inputs of this JSON structure. Provide actual data values here.',
default:
'{\n "company_name": "Apple Inc.",\n "company_domain": "apple.com",\n "company_ticker": "AAPL"\n}',
description:
'System will expect inputs of this JSON structure. Provide actual data values here.',
},
{
displayName: 'Output Schema Type',
Expand Down Expand Up @@ -206,7 +209,8 @@ export class Parallel implements INodeType {
{
name: 'Auto',
value: 'auto',
description: 'Only supported in Pro and above. Optimized JSON output with nested citations.',
description:
'Only supported in Pro and above. Optimized JSON output with nested citations.',
},
],
default: 'text',
Expand All @@ -224,7 +228,8 @@ export class Parallel implements INodeType {
},
},
default: '',
placeholder: 'Optional: Describe the desired output (e.g., "Format as $X.X trillion (year)")',
placeholder:
'Optional: Describe the desired output (e.g., "Format as $X.X trillion (year)")',
description: 'Optional description of how you want the text output formatted',
},
{
Expand All @@ -241,7 +246,8 @@ export class Parallel implements INodeType {
},
},
default: '',
placeholder: 'Required: Describe what text output you want from the JSON input (e.g., "Generate a company summary")',
placeholder:
'Required: Describe what text output you want from the JSON input (e.g., "Generate a company summary")',
description: 'Required description of what text output you want when providing JSON input',
},
{
Expand All @@ -261,7 +267,8 @@ export class Parallel implements INodeType {
},
default:
'{\n "type": "object",\n "properties": {\n "company_name": {\n "type": "string",\n "description": "Official company name from recent filings or website."\n },\n "ceo_name": {\n "type": "string",\n "description": "Current CEO full name from company website or recent news."\n },\n "employee_count": {\n "type": "string",\n "description": "Current number of employees as approximate number or range (e.g., \'500-1000\', \'2500\')."\n },\n "annual_revenue_2024": {\n "type": "string",\n "description": "2024 annual revenue in millions USD format (e.g., \'$500M\', \'$2.5B\')."\n },\n "headquarters_city": {\n "type": "string",\n "description": "Primary headquarters city and country (e.g., \'San Francisco, USA\')."\n },\n "founded_year": {\n "type": "string",\n "description": "Year company was founded in YYYY format."\n }\n },\n "required": ["company_name", "ceo_name", "employee_count", "annual_revenue_2024", "headquarters_city", "founded_year"],\n "additionalProperties": false\n}',
description: 'JSON schema defining the structure of the expected output (description fields serve as field-level prompts)',
description:
'JSON schema defining the structure of the expected output (description fields serve as field-level prompts)',
},
{
displayName: 'JSON Schema',
Expand All @@ -280,7 +287,8 @@ export class Parallel implements INodeType {
},
default:
'{\n "type": "object",\n "properties": {\n "company_name": {\n "type": "string",\n "description": "Official company name from recent filings or website."\n },\n "ceo_name": {\n "type": "string",\n "description": "Current CEO full name from company website or recent news."\n },\n "employee_count": {\n "type": "string",\n "description": "Current number of employees as approximate number or range (e.g., \'500-1000\', \'2500\')."\n },\n "annual_revenue_2024": {\n "type": "string",\n "description": "2024 annual revenue in millions USD format (e.g., \'$500M\', \'$2.5B\')."\n },\n "headquarters_city": {\n "type": "string",\n "description": "Primary headquarters city and country (e.g., \'San Francisco, USA\')."\n },\n "founded_year": {\n "type": "string",\n "description": "Year company was founded in YYYY format."\n }\n },\n "required": ["company_name", "ceo_name", "employee_count", "annual_revenue_2024", "headquarters_city", "founded_year"],\n "additionalProperties": false\n}',
description: 'JSON schema defining the structure of the expected output (required when JSON type is selected)',
description:
'JSON schema defining the structure of the expected output (required when JSON type is selected)',
},
{
displayName: 'Processor',
Expand All @@ -300,7 +308,8 @@ export class Parallel implements INodeType {
displayName: 'Processor',
name: 'asyncProcessor',
type: 'options',
description: 'Processor used for the async task. Higher-end processors for longer-running tasks.',
description:
'Processor used for the async task. Higher-end processors for longer-running tasks.',
displayOptions: {
show: {
resource: ['task'],
Expand All @@ -322,7 +331,8 @@ export class Parallel implements INodeType {
},
default: '',
placeholder: 'https://your-domain.com/webhooks/parallel',
description: 'Optional webhook URL to receive real-time notifications when the task completes',
description:
'Optional webhook URL to receive real-time notifications when the task completes',
},
{
displayName: 'Additional Fields',
Expand Down Expand Up @@ -591,30 +601,38 @@ export class Parallel implements INodeType {
chatResponseFormat: ['json'],
},
},
default: JSON.stringify({
type: 'object',
properties: {
answer: {
type: 'string',
description: 'Direct factual answer to the user question based on web research. If unavailable, return \'Information not found\'.',
},
key_findings: {
type: 'array',
items: { type: 'string' },
description: 'List of 3-5 most important facts or insights related to the question. Return empty array if no findings.',
},
confidence_level: {
type: 'string',
description: 'Confidence level of the answer as \'High\', \'Medium\', or \'Low\' based on source quality and consistency.',
},
last_updated_date: {
type: 'string',
description: 'Most recent date of information found in YYYY-MM-DD format. If unavailable, return \'Unknown\'.',
default: JSON.stringify(
{
type: 'object',
properties: {
answer: {
type: 'string',
description:
"Direct factual answer to the user question based on web research. If unavailable, return 'Information not found'.",
},
key_findings: {
type: 'array',
items: { type: 'string' },
description:
'List of 3-5 most important facts or insights related to the question. Return empty array if no findings.',
},
confidence_level: {
type: 'string',
description:
"Confidence level of the answer as 'High', 'Medium', or 'Low' based on source quality and consistency.",
},
last_updated_date: {
type: 'string',
description:
"Most recent date of information found in YYYY-MM-DD format. If unavailable, return 'Unknown'.",
},
},
required: ['answer', 'key_findings', 'confidence_level', 'last_updated_date'],
additionalProperties: false,
},
required: ['answer', 'key_findings', 'confidence_level', 'last_updated_date'],
additionalProperties: false,
}, null, 2),
null,
2,
),
description: 'JSON schema defining the structure of the expected response',
},
{
Expand All @@ -639,7 +657,7 @@ export class Parallel implements INodeType {
},
default: '',
placeholder: 'You are a helpful assistant that provides accurate information...',
description: 'Optional system prompt to define the AI\'s behavior and role',
description: "Optional system prompt to define the AI's behavior and role",
},
],
},
Expand Down Expand Up @@ -677,7 +695,8 @@ export class Parallel implements INodeType {
},
default: '',
placeholder: 'Track funding announcements for AI startups',
description: 'What to monitor - natural language description of the events to track on the web',
description:
'What to monitor - natural language description of the events to track on the web',
},
{
displayName: 'Task Run ID',
Expand Down Expand Up @@ -782,7 +801,8 @@ export class Parallel implements INodeType {
monitorOutputSchemaType: ['json'],
},
},
default: '{\n "type": "object",\n "properties": {\n "company_name": {\n "type": "string",\n "description": "Company name"\n },\n "event_summary": {\n "type": "string",\n "description": "Brief summary of the event"\n },\n "sentiment": {\n "type": "string",\n "description": "Sentiment: positive, negative, or neutral"\n }\n }\n}',
default:
'{\n "type": "object",\n "properties": {\n "company_name": {\n "type": "string",\n "description": "Company name"\n },\n "event_summary": {\n "type": "string",\n "description": "Brief summary of the event"\n },\n "sentiment": {\n "type": "string",\n "description": "Sentiment: positive, negative, or neutral"\n }\n }\n}',
description: 'JSON schema defining the structure of monitor event outputs',
},
{
Expand All @@ -797,7 +817,8 @@ export class Parallel implements INodeType {
},
default: '',
placeholder: 'https://your-n8n-instance.com/webhook/parallel-monitor-event',
description: 'Webhook URL to receive notifications when events are detected. Use the URL from a Parallel Monitor Event Trigger node.',
description:
'Webhook URL to receive notifications when events are detected. Use the URL from a Parallel Monitor Event Trigger node.',
},
{
displayName: 'Webhook Event Types',
Expand Down Expand Up @@ -888,7 +909,14 @@ export class Parallel implements INodeType {
displayOptions: {
show: {
resource: ['monitor'],
monitorOperation: ['getMonitor', 'updateMonitor', 'deleteMonitor', 'listMonitorEvents', 'getMonitorEventGroup', 'triggerMonitor'],
monitorOperation: [
'getMonitor',
'updateMonitor',
'deleteMonitor',
'listMonitorEvents',
'getMonitorEventGroup',
'triggerMonitor',
],
},
},
default: '',
Expand Down Expand Up @@ -1171,9 +1199,13 @@ export class Parallel implements INodeType {
result = await operations.triggerMonitor.execute(this, i);
break;
default:
throw new NodeOperationError(this.getNode(), `Unknown monitor operation: ${monitorOperation}`, {
itemIndex: i,
});
throw new NodeOperationError(
this.getNode(),
`Unknown monitor operation: ${monitorOperation}`,
{
itemIndex: i,
},
);
}
} else {
const operation = this.getNodeParameter('operation', i) as string;
Expand Down
17 changes: 9 additions & 8 deletions nodes/Parallel/actions/asyncWebEnrichment.operation.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import type {
IExecuteFunctions,
IDataObject,
INodePropertyOptions,
} from 'n8n-workflow';
import type { IExecuteFunctions, IDataObject, INodePropertyOptions } from 'n8n-workflow';
import { NodeOperationError } from 'n8n-workflow';
import { assertTaskOutputSchemaCompatibility } from '../contracts/requests';
import { parallelApiRequest } from '../transport/ParallelApi';
Expand All @@ -11,7 +7,8 @@ import { buildSourcePolicy, buildMetadata } from '../utils';
export const description: INodePropertyOptions = {
name: 'Async Web Enrichment',
value: 'asyncWebEnrichment',
description: 'Create a Task with the Parallel Task API and retrieve its Run ID for async retrieval',
description:
'Create a Task with the Parallel Task API and retrieve its Run ID for async retrieval',
action: 'Async Web Enrichment',
};

Expand Down Expand Up @@ -72,7 +69,10 @@ export async function execute(
type: 'text',
};
} else if (outputSchemaType === 'json') {
const jsonSchemaString = executeFunctions.getNodeParameter('asyncOutputJsonSchema', itemIndex) as string;
const jsonSchemaString = executeFunctions.getNodeParameter(
'asyncOutputJsonSchema',
itemIndex,
) as string;
try {
const jsonSchema = JSON.parse(jsonSchemaString);
taskSpec.output_schema = {
Expand Down Expand Up @@ -134,7 +134,8 @@ export async function execute(
if (webhookUrl) {
result.webhook_configured = true;
result.webhook_url = webhookUrl;
result.message = 'Task started successfully with webhook notifications. You will receive a webhook call when the task completes.';
result.message =
'Task started successfully with webhook notifications. You will receive a webhook call when the task completes.';
} else {
result.webhook_configured = false;
}
Expand Down
Loading