n8n-nodes-perf 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +88 -0
- package/dist/credentials/PerfApi.credentials.d.ts +9 -0
- package/dist/credentials/PerfApi.credentials.js +45 -0
- package/dist/credentials/PerfApi.credentials.js.map +1 -0
- package/dist/nodes/PerfChat/PerfChat.node.d.ts +5 -0
- package/dist/nodes/PerfChat/PerfChat.node.js +297 -0
- package/dist/nodes/PerfChat/PerfChat.node.js.map +1 -0
- package/dist/nodes/PerfChat/perf.svg +3 -0
- package/dist/nodes/PerfValidate/PerfValidate.node.d.ts +5 -0
- package/dist/nodes/PerfValidate/PerfValidate.node.js +142 -0
- package/dist/nodes/PerfValidate/PerfValidate.node.js.map +1 -0
- package/dist/nodes/PerfValidate/perf.svg +3 -0
- package/dist/nodes/PerfVerify/PerfVerify.node.d.ts +5 -0
- package/dist/nodes/PerfVerify/PerfVerify.node.js +219 -0
- package/dist/nodes/PerfVerify/PerfVerify.node.js.map +1 -0
- package/dist/nodes/PerfVerify/perf.svg +3 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Perf Technology
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# n8n-nodes-perf
|
|
2
|
+
|
|
3
|
+
[n8n](https://n8n.io/) community nodes for [Perf AI](https://withperf.pro) — intelligent LLM routing, fact-checking, and schema validation for your automation workflows.
|
|
4
|
+
|
|
5
|
+
## Nodes
|
|
6
|
+
|
|
7
|
+
### Perf Chat
|
|
8
|
+
|
|
9
|
+
Send messages to any LLM with intelligent model routing. One node, any model.
|
|
10
|
+
|
|
11
|
+
- **Intelligent Routing** — Perf automatically selects the best model (GPT-4o, Claude, Gemini, etc.) based on task complexity and cost
|
|
12
|
+
- **Model Override** — Pin to a specific model when needed
|
|
13
|
+
- **JSON Mode** — Get structured JSON output with optional schema enforcement
|
|
14
|
+
- **OpenAI-Compatible** — Drop-in replacement for vendor-specific LLM nodes
|
|
15
|
+
|
|
16
|
+
### Perf Verify
|
|
17
|
+
|
|
18
|
+
Verify any text for factual accuracy and hallucinations before it reaches your users.
|
|
19
|
+
|
|
20
|
+
- **Dual Output Routing** — Automatically routes to "Verified" or "Issues Found" based on confidence thresholds
|
|
21
|
+
- **Three Verification Modes** — Fast (~200ms), Standard (~500ms), or Thorough (~2s)
|
|
22
|
+
- **Auto-Correction** — Returns a corrected version of the text with factual fixes applied
|
|
23
|
+
- **Claim-Level Detail** — See exactly which claims were verified, corrected, or retracted
|
|
24
|
+
|
|
25
|
+
### Perf Validate
|
|
26
|
+
|
|
27
|
+
Validate JSON against a schema and auto-repair errors using AI-powered correction.
|
|
28
|
+
|
|
29
|
+
- **Dual Output Routing** — Routes to "Valid" or "Invalid" based on validation result
|
|
30
|
+
- **Auto-Repair** — Fixes type mismatches, missing fields, and format errors
|
|
31
|
+
- **Strict Mode** — Reject on any error instead of attempting repair
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
### In n8n (Community Nodes)
|
|
36
|
+
|
|
37
|
+
1. Go to **Settings → Community Nodes**
|
|
38
|
+
2. Enter `n8n-nodes-perf`
|
|
39
|
+
3. Click **Install**
|
|
40
|
+
|
|
41
|
+
### Manual Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cd ~/.n8n/custom
|
|
45
|
+
npm install n8n-nodes-perf
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Setup
|
|
49
|
+
|
|
50
|
+
1. Sign up at [app.withperf.pro](https://app.withperf.pro) and create an API key
|
|
51
|
+
2. In n8n, go to **Credentials → New Credential → Perf API**
|
|
52
|
+
3. Paste your API key
|
|
53
|
+
|
|
54
|
+
## Example Workflows
|
|
55
|
+
|
|
56
|
+
### AI Email Response with Fact-Checking
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Email Trigger → Perf Chat → Perf Verify → [Verified] → Send Reply
|
|
60
|
+
→ [Issues] → Human Review
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Structured Data Extraction
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
Webhook → Perf Chat (JSON mode + schema) → Perf Validate → [Valid] → Database Insert
|
|
67
|
+
→ [Invalid] → Error Queue
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Research Report Pipeline
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Schedule → HTTP (fetch sources) → Perf Chat → Perf Verify (thorough) → [Verified] → Slack
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## AI Agent Tool Support
|
|
77
|
+
|
|
78
|
+
All three nodes can be used as tools by n8n's AI Agent node (`usableAsTool: true`). Enable community node tool usage in your n8n instance settings.
|
|
79
|
+
|
|
80
|
+
## Resources
|
|
81
|
+
|
|
82
|
+
- [Perf API Documentation](https://docs.withperf.pro)
|
|
83
|
+
- [Perf Dashboard](https://app.withperf.pro)
|
|
84
|
+
- [Report Issues](https://github.com/Perf-Technology/n8n-nodes-perf/issues)
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class PerfApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
properties: INodeProperties[];
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PerfApi = void 0;
|
|
4
|
+
class PerfApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'perfApi';
|
|
7
|
+
this.displayName = 'Perf API';
|
|
8
|
+
this.documentationUrl = 'https://docs.withperf.pro/api-reference/authentication';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'API Key',
|
|
12
|
+
name: 'apiKey',
|
|
13
|
+
type: 'string',
|
|
14
|
+
typeOptions: { password: true },
|
|
15
|
+
default: '',
|
|
16
|
+
required: true,
|
|
17
|
+
description: 'Your Perf API key from https://app.withperf.pro',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
displayName: 'Base URL',
|
|
21
|
+
name: 'baseUrl',
|
|
22
|
+
type: 'string',
|
|
23
|
+
default: 'https://api.withperf.pro',
|
|
24
|
+
description: 'Perf API base URL. Only change for self-hosted instances.',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
this.authenticate = {
|
|
28
|
+
type: 'generic',
|
|
29
|
+
properties: {
|
|
30
|
+
headers: {
|
|
31
|
+
Authorization: '=Bearer {{$credentials.apiKey}}',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
this.test = {
|
|
36
|
+
request: {
|
|
37
|
+
baseURL: '={{$credentials.baseUrl}}',
|
|
38
|
+
url: '/v1/health',
|
|
39
|
+
method: 'GET',
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.PerfApi = PerfApi;
|
|
45
|
+
//# sourceMappingURL=PerfApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PerfApi.credentials.js","sourceRoot":"","sources":["../../credentials/PerfApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,OAAO;IAApB;QACE,SAAI,GAAG,SAAS,CAAC;QACjB,gBAAW,GAAG,UAAU,CAAC;QACzB,qBAAgB,GAAG,wDAAwD,CAAC;QAC5E,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,iDAAiD;aAC/D;YACD;gBACE,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,0BAA0B;gBACnC,WAAW,EAAE,2DAA2D;aACzE;SACF,CAAC;QAEF,iBAAY,GAAyB;YACnC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,aAAa,EAAE,iCAAiC;iBACjD;aACF;SACF,CAAC;QAEF,SAAI,GAA2B;YAC7B,OAAO,EAAE;gBACP,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,YAAY;gBACjB,MAAM,EAAE,KAAK;aACd;SACF,CAAC;IACJ,CAAC;CAAA;AAvCD,0BAuCC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class PerfChat implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PerfChat = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
class PerfChat {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Perf Chat',
|
|
9
|
+
name: 'perfChat',
|
|
10
|
+
icon: 'file:perf.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
subtitle: '={{$parameter["model"] === "auto" ? "Intelligent Routing" : $parameter["model"]}}',
|
|
14
|
+
description: 'Send messages to any LLM with intelligent model routing. One node, any model — Perf automatically selects the best model for each request.',
|
|
15
|
+
defaults: { name: 'Perf Chat' },
|
|
16
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
17
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
18
|
+
usableAsTool: true,
|
|
19
|
+
credentials: [
|
|
20
|
+
{
|
|
21
|
+
name: 'perfApi',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
properties: [
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Input Mode',
|
|
28
|
+
name: 'inputMode',
|
|
29
|
+
type: 'options',
|
|
30
|
+
options: [
|
|
31
|
+
{ name: 'Simple', value: 'simple', description: 'Single user message' },
|
|
32
|
+
{
|
|
33
|
+
name: 'Message List',
|
|
34
|
+
value: 'messages',
|
|
35
|
+
description: 'Full conversation with roles',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'JSON',
|
|
39
|
+
value: 'json',
|
|
40
|
+
description: 'Raw JSON messages array (OpenAI format)',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
default: 'simple',
|
|
44
|
+
description: 'How to provide the input messages',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
displayName: 'Message',
|
|
48
|
+
name: 'message',
|
|
49
|
+
type: 'string',
|
|
50
|
+
typeOptions: { rows: 4 },
|
|
51
|
+
default: '',
|
|
52
|
+
required: true,
|
|
53
|
+
displayOptions: { show: { inputMode: ['simple'] } },
|
|
54
|
+
description: 'The message to send',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
displayName: 'Messages',
|
|
58
|
+
name: 'messages',
|
|
59
|
+
type: 'fixedCollection',
|
|
60
|
+
typeOptions: { multipleValues: true, sortable: true },
|
|
61
|
+
default: { values: [] },
|
|
62
|
+
displayOptions: { show: { inputMode: ['messages'] } },
|
|
63
|
+
options: [
|
|
64
|
+
{
|
|
65
|
+
name: 'values',
|
|
66
|
+
displayName: 'Message',
|
|
67
|
+
values: [
|
|
68
|
+
{
|
|
69
|
+
displayName: 'Role',
|
|
70
|
+
name: 'role',
|
|
71
|
+
type: 'options',
|
|
72
|
+
options: [
|
|
73
|
+
{ name: 'System', value: 'system' },
|
|
74
|
+
{ name: 'User', value: 'user' },
|
|
75
|
+
{ name: 'Assistant', value: 'assistant' },
|
|
76
|
+
],
|
|
77
|
+
default: 'user',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
displayName: 'Content',
|
|
81
|
+
name: 'content',
|
|
82
|
+
type: 'string',
|
|
83
|
+
typeOptions: { rows: 3 },
|
|
84
|
+
default: '',
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
description: 'The messages to send (supports system, user, and assistant roles)',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
displayName: 'Messages JSON',
|
|
93
|
+
name: 'messagesJson',
|
|
94
|
+
type: 'json',
|
|
95
|
+
default: '[\n { "role": "user", "content": "Hello" }\n]',
|
|
96
|
+
displayOptions: { show: { inputMode: ['json'] } },
|
|
97
|
+
description: 'Messages array in OpenAI format: [{ "role": "user", "content": "..." }]',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
displayName: 'Model',
|
|
101
|
+
name: 'model',
|
|
102
|
+
type: 'options',
|
|
103
|
+
options: [
|
|
104
|
+
{
|
|
105
|
+
name: 'Auto (Intelligent Routing)',
|
|
106
|
+
value: 'auto',
|
|
107
|
+
description: 'Perf selects the best model based on task complexity and cost',
|
|
108
|
+
},
|
|
109
|
+
{ name: 'GPT-4o', value: 'gpt-4o' },
|
|
110
|
+
{ name: 'GPT-4o Mini', value: 'gpt-4o-mini' },
|
|
111
|
+
{ name: 'Claude 3.5 Haiku', value: 'claude-haiku-4-5' },
|
|
112
|
+
{ name: 'Gemini 2.5 Flash', value: 'gemini-2.5-flash' },
|
|
113
|
+
{ name: 'Gemini 2.5 Flash Lite', value: 'gemini-2.5-flash-lite' },
|
|
114
|
+
{ name: 'Gemini 2.5 Pro', value: 'gemini-2.5-pro' },
|
|
115
|
+
],
|
|
116
|
+
default: 'auto',
|
|
117
|
+
description: 'Which model to use. "Auto" lets Perf intelligently route to the best model.',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
displayName: 'System Prompt',
|
|
121
|
+
name: 'systemPrompt',
|
|
122
|
+
type: 'string',
|
|
123
|
+
typeOptions: { rows: 3 },
|
|
124
|
+
default: '',
|
|
125
|
+
description: 'Optional system prompt prepended to the conversation',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
displayName: 'Options',
|
|
129
|
+
name: 'options',
|
|
130
|
+
type: 'collection',
|
|
131
|
+
placeholder: 'Add Option',
|
|
132
|
+
default: {},
|
|
133
|
+
options: [
|
|
134
|
+
{
|
|
135
|
+
displayName: 'Max Cost Per Call (USD)',
|
|
136
|
+
name: 'maxCostPerCall',
|
|
137
|
+
type: 'number',
|
|
138
|
+
typeOptions: { minValue: 0, numberPrecision: 4 },
|
|
139
|
+
default: 0,
|
|
140
|
+
description: 'Maximum cost in USD for this call. 0 means no limit.',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
displayName: 'Response Format',
|
|
144
|
+
name: 'responseFormat',
|
|
145
|
+
type: 'options',
|
|
146
|
+
options: [
|
|
147
|
+
{ name: 'Text', value: 'text' },
|
|
148
|
+
{ name: 'JSON', value: 'json' },
|
|
149
|
+
],
|
|
150
|
+
default: 'text',
|
|
151
|
+
description: 'Response format. JSON mode returns structured JSON output.',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
displayName: 'JSON Schema',
|
|
155
|
+
name: 'jsonSchema',
|
|
156
|
+
type: 'json',
|
|
157
|
+
default: '',
|
|
158
|
+
displayOptions: { show: { responseFormat: ['json'] } },
|
|
159
|
+
description: 'Optional JSON Schema to enforce on the response',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
displayName: 'Include Routing Metadata',
|
|
163
|
+
name: 'includeMetadata',
|
|
164
|
+
type: 'boolean',
|
|
165
|
+
default: true,
|
|
166
|
+
description: 'Whether to include model routing metadata (model selected, cost, latency) in the output',
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async execute() {
|
|
174
|
+
var _a;
|
|
175
|
+
const items = this.getInputData();
|
|
176
|
+
const returnData = [];
|
|
177
|
+
for (let i = 0; i < items.length; i++) {
|
|
178
|
+
try {
|
|
179
|
+
const credentials = await this.getCredentials('perfApi');
|
|
180
|
+
const inputMode = this.getNodeParameter('inputMode', i);
|
|
181
|
+
const model = this.getNodeParameter('model', i);
|
|
182
|
+
const systemPrompt = this.getNodeParameter('systemPrompt', i, '');
|
|
183
|
+
const options = this.getNodeParameter('options', i, {});
|
|
184
|
+
// Build messages array based on input mode
|
|
185
|
+
let messages = [];
|
|
186
|
+
if (inputMode === 'simple') {
|
|
187
|
+
const message = this.getNodeParameter('message', i);
|
|
188
|
+
messages = [{ role: 'user', content: message }];
|
|
189
|
+
}
|
|
190
|
+
else if (inputMode === 'messages') {
|
|
191
|
+
const messageList = this.getNodeParameter('messages.values', i, []);
|
|
192
|
+
messages = messageList.map((m) => ({ role: m.role, content: m.content }));
|
|
193
|
+
}
|
|
194
|
+
else if (inputMode === 'json') {
|
|
195
|
+
const rawJson = this.getNodeParameter('messagesJson', i);
|
|
196
|
+
try {
|
|
197
|
+
messages = typeof rawJson === 'string' ? JSON.parse(rawJson) : rawJson;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in Messages JSON field', {
|
|
201
|
+
itemIndex: i,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (systemPrompt) {
|
|
206
|
+
messages.unshift({ role: 'system', content: systemPrompt });
|
|
207
|
+
}
|
|
208
|
+
if (messages.length === 0) {
|
|
209
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one message is required', {
|
|
210
|
+
itemIndex: i,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
// Build request body
|
|
214
|
+
const body = { messages };
|
|
215
|
+
if (model !== 'auto') {
|
|
216
|
+
body.model = model;
|
|
217
|
+
}
|
|
218
|
+
if (options.maxCostPerCall && options.maxCostPerCall > 0) {
|
|
219
|
+
body.max_cost_per_call = options.maxCostPerCall;
|
|
220
|
+
}
|
|
221
|
+
if (options.responseFormat === 'json') {
|
|
222
|
+
body.response_format = { type: 'json_object' };
|
|
223
|
+
if (options.jsonSchema) {
|
|
224
|
+
try {
|
|
225
|
+
body.target_schema =
|
|
226
|
+
typeof options.jsonSchema === 'string'
|
|
227
|
+
? JSON.parse(options.jsonSchema)
|
|
228
|
+
: options.jsonSchema;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON Schema', { itemIndex: i });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'perfApi', {
|
|
236
|
+
method: 'POST',
|
|
237
|
+
url: `${credentials.baseUrl}/v1/chat`,
|
|
238
|
+
body,
|
|
239
|
+
json: true,
|
|
240
|
+
timeout: 60000,
|
|
241
|
+
}));
|
|
242
|
+
const choice = (_a = response.choices) === null || _a === void 0 ? void 0 : _a[0];
|
|
243
|
+
if (!choice) {
|
|
244
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No response from Perf API', {
|
|
245
|
+
itemIndex: i,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
const output = {
|
|
249
|
+
content: choice.message.content,
|
|
250
|
+
role: 'assistant',
|
|
251
|
+
model: response.model,
|
|
252
|
+
finish_reason: choice.finish_reason,
|
|
253
|
+
};
|
|
254
|
+
// Parse JSON content if JSON mode
|
|
255
|
+
if (options.responseFormat === 'json') {
|
|
256
|
+
try {
|
|
257
|
+
output.json_content = JSON.parse(choice.message.content);
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
output.json_content = null;
|
|
261
|
+
output.json_parse_error = true;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Include routing metadata
|
|
265
|
+
const includeMetadata = options.includeMetadata !== false;
|
|
266
|
+
if (includeMetadata && response.perf) {
|
|
267
|
+
output.perf = {
|
|
268
|
+
request_id: response.perf.request_id,
|
|
269
|
+
task_type: response.perf.task_type,
|
|
270
|
+
complexity: response.perf.complexity,
|
|
271
|
+
model_selected: response.perf.model_selected,
|
|
272
|
+
cost_usd: response.perf.cost_usd,
|
|
273
|
+
latency_ms: response.perf.latency_ms,
|
|
274
|
+
fallback_used: response.perf.fallback_used,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
if (response.usage) {
|
|
278
|
+
output.usage = response.usage;
|
|
279
|
+
}
|
|
280
|
+
returnData.push({ json: output, pairedItem: { item: i } });
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
if (this.continueOnFail()) {
|
|
284
|
+
returnData.push({
|
|
285
|
+
json: { error: error.message },
|
|
286
|
+
pairedItem: { item: i },
|
|
287
|
+
});
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
throw error;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return [returnData];
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
exports.PerfChat = PerfChat;
|
|
297
|
+
//# sourceMappingURL=PerfChat.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PerfChat.node.js","sourceRoot":"","sources":["../../../nodes/PerfChat/PerfChat.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="60" height="60" viewBox="0 0 322 322" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M160.746 206.364C166.958 206.364 171.993 211.401 171.993 217.612V321.487H149.498V217.612C149.498 211.4 154.534 206.364 160.746 206.364ZM282.587 55.1768L213.476 124.288C193.122 144.642 193.122 177.643 213.476 197.997L282.587 267.108L267.148 282.547L198.037 213.436C177.683 193.082 144.682 193.081 124.328 213.436L55.2168 282.547L39.7783 267.108L108.89 197.997C129.244 177.643 129.244 144.642 108.89 124.288L39.7783 55.1768L55.2168 39.7383L124.328 108.85C144.682 129.204 177.683 129.204 198.037 108.85L267.148 39.7383L282.587 55.1768ZM103.875 149.498C110.087 149.498 115.123 154.533 115.123 160.745C115.123 166.957 110.087 171.993 103.875 171.993H0V149.498H103.875ZM321.488 171.989H217.613C211.401 171.989 206.365 166.954 206.365 160.742C206.365 154.53 211.401 149.494 217.613 149.494H321.488V171.989ZM171.99 103.875C171.99 110.087 166.955 115.123 160.743 115.123C154.531 115.123 149.495 110.087 149.495 103.875V0H171.99V103.875Z" fill="#1A1A1A"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class PerfValidate implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PerfValidate = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
class PerfValidate {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Perf Validate',
|
|
9
|
+
name: 'perfValidate',
|
|
10
|
+
icon: 'file:perf.svg',
|
|
11
|
+
group: ['transform'],
|
|
12
|
+
version: 1,
|
|
13
|
+
subtitle: 'Schema Validation',
|
|
14
|
+
description: 'Validate JSON against a schema and auto-repair errors. Routes to "Valid" or "Invalid" output.',
|
|
15
|
+
defaults: { name: 'Perf Validate' },
|
|
16
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
17
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main, n8n_workflow_1.NodeConnectionTypes.Main],
|
|
18
|
+
outputNames: ['Valid', 'Invalid'],
|
|
19
|
+
usableAsTool: true,
|
|
20
|
+
credentials: [
|
|
21
|
+
{
|
|
22
|
+
name: 'perfApi',
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
properties: [
|
|
27
|
+
{
|
|
28
|
+
displayName: 'Content',
|
|
29
|
+
name: 'content',
|
|
30
|
+
type: 'string',
|
|
31
|
+
typeOptions: { rows: 6 },
|
|
32
|
+
default: '={{ JSON.stringify($json) }}',
|
|
33
|
+
required: true,
|
|
34
|
+
description: 'The JSON string to validate',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
displayName: 'Target Schema',
|
|
38
|
+
name: 'targetSchema',
|
|
39
|
+
type: 'json',
|
|
40
|
+
default: '',
|
|
41
|
+
required: true,
|
|
42
|
+
description: 'The JSON Schema to validate against',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
displayName: 'Repair Mode',
|
|
46
|
+
name: 'repairMode',
|
|
47
|
+
type: 'options',
|
|
48
|
+
options: [
|
|
49
|
+
{
|
|
50
|
+
name: 'Best Effort',
|
|
51
|
+
value: 'best_effort',
|
|
52
|
+
description: 'Attempt to fix validation errors automatically',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Strict',
|
|
56
|
+
value: 'strict',
|
|
57
|
+
description: 'Reject if any validation errors are found',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
default: 'best_effort',
|
|
61
|
+
description: 'How to handle validation errors',
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async execute() {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
const items = this.getInputData();
|
|
69
|
+
const validItems = [];
|
|
70
|
+
const invalidItems = [];
|
|
71
|
+
for (let i = 0; i < items.length; i++) {
|
|
72
|
+
try {
|
|
73
|
+
const credentials = await this.getCredentials('perfApi');
|
|
74
|
+
const content = this.getNodeParameter('content', i);
|
|
75
|
+
const targetSchemaRaw = this.getNodeParameter('targetSchema', i);
|
|
76
|
+
const repairMode = this.getNodeParameter('repairMode', i);
|
|
77
|
+
let targetSchema;
|
|
78
|
+
try {
|
|
79
|
+
targetSchema =
|
|
80
|
+
typeof targetSchemaRaw === 'string' ? JSON.parse(targetSchemaRaw) : targetSchemaRaw;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid JSON in Target Schema field', {
|
|
84
|
+
itemIndex: i,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'perfApi', {
|
|
88
|
+
method: 'POST',
|
|
89
|
+
url: `${credentials.baseUrl}/v1/validate`,
|
|
90
|
+
body: { content, target_schema: targetSchema, repair_mode: repairMode },
|
|
91
|
+
json: true,
|
|
92
|
+
timeout: 30000,
|
|
93
|
+
}));
|
|
94
|
+
const output = {
|
|
95
|
+
action_taken: response.action_taken,
|
|
96
|
+
overall_confidence: response.overall_confidence,
|
|
97
|
+
changes_count: ((_a = response.changes) === null || _a === void 0 ? void 0 : _a.length) || 0,
|
|
98
|
+
};
|
|
99
|
+
// Parse corrected JSON
|
|
100
|
+
try {
|
|
101
|
+
output.corrected_json = JSON.parse(response.corrected_text);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
output.corrected_text = response.corrected_text;
|
|
105
|
+
}
|
|
106
|
+
if (((_b = response.changes) === null || _b === void 0 ? void 0 : _b.length) > 0) {
|
|
107
|
+
output.changes = response.changes.map((c) => ({
|
|
108
|
+
original: c.original,
|
|
109
|
+
replacement: c.replacement,
|
|
110
|
+
error_type: c.error_type,
|
|
111
|
+
confidence: c.confidence,
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
if (response.validation_errors) {
|
|
115
|
+
output.validation_errors = response.validation_errors;
|
|
116
|
+
}
|
|
117
|
+
if (response.quota) {
|
|
118
|
+
output.quota = response.quota;
|
|
119
|
+
}
|
|
120
|
+
if (response.action_taken === 'rejected') {
|
|
121
|
+
invalidItems.push({ json: output, pairedItem: { item: i } });
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
validItems.push({ json: output, pairedItem: { item: i } });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (this.continueOnFail()) {
|
|
129
|
+
invalidItems.push({
|
|
130
|
+
json: { error: error.message },
|
|
131
|
+
pairedItem: { item: i },
|
|
132
|
+
});
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return [validItems, invalidItems];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.PerfValidate = PerfValidate;
|
|
142
|
+
//# sourceMappingURL=PerfValidate.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PerfValidate.node.js","sourceRoot":"","sources":["../../../nodes/PerfValidate/PerfValidate.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="60" height="60" viewBox="0 0 322 322" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M160.746 206.364C166.958 206.364 171.993 211.401 171.993 217.612V321.487H149.498V217.612C149.498 211.4 154.534 206.364 160.746 206.364ZM282.587 55.1768L213.476 124.288C193.122 144.642 193.122 177.643 213.476 197.997L282.587 267.108L267.148 282.547L198.037 213.436C177.683 193.082 144.682 193.081 124.328 213.436L55.2168 282.547L39.7783 267.108L108.89 197.997C129.244 177.643 129.244 144.642 108.89 124.288L39.7783 55.1768L55.2168 39.7383L124.328 108.85C144.682 129.204 177.683 129.204 198.037 108.85L267.148 39.7383L282.587 55.1768ZM103.875 149.498C110.087 149.498 115.123 154.533 115.123 160.745C115.123 166.957 110.087 171.993 103.875 171.993H0V149.498H103.875ZM321.488 171.989H217.613C211.401 171.989 206.365 166.954 206.365 160.742C206.365 154.53 211.401 149.494 217.613 149.494H321.488V171.989ZM171.99 103.875C171.99 110.087 166.955 115.123 160.743 115.123C154.531 115.123 149.495 110.087 149.495 103.875V0H171.99V103.875Z" fill="#1A1A1A"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class PerfVerify implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PerfVerify = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
/**
|
|
6
|
+
* Applies corrections from verified claims back into the original text.
|
|
7
|
+
*/
|
|
8
|
+
function buildCorrectedText(originalText, claims) {
|
|
9
|
+
let result = originalText;
|
|
10
|
+
const corrections = claims
|
|
11
|
+
.filter((c) => c.status === 'CORRECTED' && c.corrected_text)
|
|
12
|
+
.sort((a, b) => {
|
|
13
|
+
const idxA = result.lastIndexOf(a.claim_text);
|
|
14
|
+
const idxB = result.lastIndexOf(b.claim_text);
|
|
15
|
+
return idxB - idxA;
|
|
16
|
+
});
|
|
17
|
+
for (const correction of corrections) {
|
|
18
|
+
const idx = result.lastIndexOf(correction.claim_text);
|
|
19
|
+
if (idx !== -1) {
|
|
20
|
+
result =
|
|
21
|
+
result.slice(0, idx) +
|
|
22
|
+
correction.corrected_text +
|
|
23
|
+
result.slice(idx + correction.claim_text.length);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
class PerfVerify {
|
|
29
|
+
constructor() {
|
|
30
|
+
this.description = {
|
|
31
|
+
displayName: 'Perf Verify',
|
|
32
|
+
name: 'perfVerify',
|
|
33
|
+
icon: 'file:perf.svg',
|
|
34
|
+
group: ['transform'],
|
|
35
|
+
version: 1,
|
|
36
|
+
subtitle: 'Fact-Check',
|
|
37
|
+
description: 'Verify text for factual accuracy and hallucinations. Routes to "Verified" or "Issues Found" output based on confidence thresholds.',
|
|
38
|
+
defaults: { name: 'Perf Verify' },
|
|
39
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
40
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main, n8n_workflow_1.NodeConnectionTypes.Main],
|
|
41
|
+
outputNames: ['Verified', 'Issues Found'],
|
|
42
|
+
usableAsTool: true,
|
|
43
|
+
credentials: [
|
|
44
|
+
{
|
|
45
|
+
name: 'perfApi',
|
|
46
|
+
required: true,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
properties: [
|
|
50
|
+
{
|
|
51
|
+
displayName: 'Text',
|
|
52
|
+
name: 'text',
|
|
53
|
+
type: 'string',
|
|
54
|
+
typeOptions: { rows: 4 },
|
|
55
|
+
default: '={{ $json.content }}',
|
|
56
|
+
required: true,
|
|
57
|
+
description: 'The text to verify for factual accuracy',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
displayName: 'Verification Mode',
|
|
61
|
+
name: 'mode',
|
|
62
|
+
type: 'options',
|
|
63
|
+
options: [
|
|
64
|
+
{
|
|
65
|
+
name: 'Fast',
|
|
66
|
+
value: 'fast',
|
|
67
|
+
description: 'Quick check (~200ms). Best for high-volume workflows.',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Standard',
|
|
71
|
+
value: 'standard',
|
|
72
|
+
description: 'Balanced accuracy and speed (~500ms). Recommended for most use cases.',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'Thorough',
|
|
76
|
+
value: 'thorough',
|
|
77
|
+
description: 'Deep verification with cross-examination (~2s). Best for critical content.',
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
default: 'standard',
|
|
81
|
+
description: 'Verification depth — deeper modes catch more issues but take longer',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
displayName: 'Options',
|
|
85
|
+
name: 'options',
|
|
86
|
+
type: 'collection',
|
|
87
|
+
placeholder: 'Add Option',
|
|
88
|
+
default: {},
|
|
89
|
+
options: [
|
|
90
|
+
{
|
|
91
|
+
displayName: 'Confidence Threshold',
|
|
92
|
+
name: 'confidenceThreshold',
|
|
93
|
+
type: 'number',
|
|
94
|
+
typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2 },
|
|
95
|
+
default: 0.8,
|
|
96
|
+
description: 'Minimum confidence score (0-1) to route to "Verified" output. Below this routes to "Issues Found".',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
displayName: 'Max Retracted Claims',
|
|
100
|
+
name: 'maxRetractedClaims',
|
|
101
|
+
type: 'number',
|
|
102
|
+
typeOptions: { minValue: 0 },
|
|
103
|
+
default: 0,
|
|
104
|
+
description: 'Maximum number of retracted (disproven) claims allowed before routing to "Issues Found"',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
displayName: 'Include Claim Details',
|
|
108
|
+
name: 'includeClaims',
|
|
109
|
+
type: 'boolean',
|
|
110
|
+
default: true,
|
|
111
|
+
description: 'Whether to include per-claim verification breakdown in the output',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
displayName: 'Include Corrected Text',
|
|
115
|
+
name: 'includeCorrectedText',
|
|
116
|
+
type: 'boolean',
|
|
117
|
+
default: true,
|
|
118
|
+
description: 'Whether to include an auto-corrected version of the text with factual fixes applied',
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async execute() {
|
|
126
|
+
var _a, _b;
|
|
127
|
+
const items = this.getInputData();
|
|
128
|
+
const verifiedItems = [];
|
|
129
|
+
const issueItems = [];
|
|
130
|
+
for (let i = 0; i < items.length; i++) {
|
|
131
|
+
try {
|
|
132
|
+
const credentials = await this.getCredentials('perfApi');
|
|
133
|
+
const text = this.getNodeParameter('text', i);
|
|
134
|
+
const mode = this.getNodeParameter('mode', i);
|
|
135
|
+
const options = this.getNodeParameter('options', i, {});
|
|
136
|
+
const threshold = (_a = options.confidenceThreshold) !== null && _a !== void 0 ? _a : 0.8;
|
|
137
|
+
const maxRetracted = (_b = options.maxRetractedClaims) !== null && _b !== void 0 ? _b : 0;
|
|
138
|
+
const includeClaims = options.includeClaims !== false;
|
|
139
|
+
const includeCorrectedText = options.includeCorrectedText !== false;
|
|
140
|
+
// Determine timeout based on mode
|
|
141
|
+
const timeouts = {
|
|
142
|
+
fast: 15000,
|
|
143
|
+
standard: 30000,
|
|
144
|
+
thorough: 120000,
|
|
145
|
+
};
|
|
146
|
+
const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'perfApi', {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
url: `${credentials.baseUrl}/v1/verify`,
|
|
149
|
+
body: { text, mode, stream: false },
|
|
150
|
+
json: true,
|
|
151
|
+
timeout: timeouts[mode] || 30000,
|
|
152
|
+
}));
|
|
153
|
+
const epistemic = response.perf.epistemic;
|
|
154
|
+
const summary = epistemic.summary;
|
|
155
|
+
const output = {
|
|
156
|
+
original_text: text,
|
|
157
|
+
status: epistemic.status,
|
|
158
|
+
composite_confidence: summary.composite_confidence,
|
|
159
|
+
total_claims: summary.total_claims,
|
|
160
|
+
verified_claims: summary.verified,
|
|
161
|
+
corrected_claims: summary.corrected,
|
|
162
|
+
uncertain_claims: summary.uncertain,
|
|
163
|
+
retracted_claims: summary.retracted,
|
|
164
|
+
mode: epistemic.mode,
|
|
165
|
+
latency_ms: epistemic.latency_ms,
|
|
166
|
+
};
|
|
167
|
+
if (includeCorrectedText) {
|
|
168
|
+
output.corrected_text = buildCorrectedText(text, epistemic.claims);
|
|
169
|
+
}
|
|
170
|
+
if (includeClaims) {
|
|
171
|
+
output.claims = epistemic.claims.map((c) => {
|
|
172
|
+
var _a;
|
|
173
|
+
return ({
|
|
174
|
+
claim_text: c.claim_text,
|
|
175
|
+
type: c.claim_type,
|
|
176
|
+
status: c.status,
|
|
177
|
+
confidence: c.confidence,
|
|
178
|
+
corrected_text: c.corrected_text || null,
|
|
179
|
+
correction_source: c.correction_source || null,
|
|
180
|
+
evidence: ((_a = c.channels) === null || _a === void 0 ? void 0 : _a.map((ch) => ({
|
|
181
|
+
channel: ch.name,
|
|
182
|
+
status: ch.status,
|
|
183
|
+
source: ch.source || null,
|
|
184
|
+
}))) || [],
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
if (response.quota) {
|
|
189
|
+
output.quota = response.quota;
|
|
190
|
+
}
|
|
191
|
+
// Route based on thresholds
|
|
192
|
+
const hasIssues = summary.composite_confidence < threshold || summary.retracted > maxRetracted;
|
|
193
|
+
if (hasIssues) {
|
|
194
|
+
output.issue_reason =
|
|
195
|
+
summary.retracted > maxRetracted
|
|
196
|
+
? `${summary.retracted} retracted claim(s) exceed threshold of ${maxRetracted}`
|
|
197
|
+
: `Confidence ${summary.composite_confidence.toFixed(2)} below threshold ${threshold}`;
|
|
198
|
+
issueItems.push({ json: output, pairedItem: { item: i } });
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
verifiedItems.push({ json: output, pairedItem: { item: i } });
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
if (this.continueOnFail()) {
|
|
206
|
+
issueItems.push({
|
|
207
|
+
json: { error: error.message, original_text: '' },
|
|
208
|
+
pairedItem: { item: i },
|
|
209
|
+
});
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return [verifiedItems, issueItems];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.PerfVerify = PerfVerify;
|
|
219
|
+
//# sourceMappingURL=PerfVerify.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PerfVerify.node.js","sourceRoot":"","sources":["../../../nodes/PerfVerify/PerfVerify.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="60" height="60" viewBox="0 0 322 322" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M160.746 206.364C166.958 206.364 171.993 211.401 171.993 217.612V321.487H149.498V217.612C149.498 211.4 154.534 206.364 160.746 206.364ZM282.587 55.1768L213.476 124.288C193.122 144.642 193.122 177.643 213.476 197.997L282.587 267.108L267.148 282.547L198.037 213.436C177.683 193.082 144.682 193.081 124.328 213.436L55.2168 282.547L39.7783 267.108L108.89 197.997C129.244 177.643 129.244 144.642 108.89 124.288L39.7783 55.1768L55.2168 39.7383L124.328 108.85C144.682 129.204 177.683 129.204 198.037 108.85L267.148 39.7383L282.587 55.1768ZM103.875 149.498C110.087 149.498 115.123 154.533 115.123 160.745C115.123 166.957 110.087 171.993 103.875 171.993H0V149.498H103.875ZM321.488 171.989H217.613C211.401 171.989 206.365 166.954 206.365 160.742C206.365 154.53 211.401 149.494 217.613 149.494H321.488V171.989ZM171.99 103.875C171.99 110.087 166.955 115.123 160.743 115.123C154.531 115.123 149.495 110.087 149.495 103.875V0H171.99V103.875Z" fill="#1A1A1A"/>
|
|
3
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-perf",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community nodes for Perf AI — intelligent LLM routing, fact-checking, and schema validation",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"n8n-community-node-package",
|
|
8
|
+
"n8n",
|
|
9
|
+
"ai",
|
|
10
|
+
"llm",
|
|
11
|
+
"hallucination",
|
|
12
|
+
"fact-check",
|
|
13
|
+
"verification",
|
|
14
|
+
"routing",
|
|
15
|
+
"schema-validation"
|
|
16
|
+
],
|
|
17
|
+
"author": {
|
|
18
|
+
"name": "Perf Technology",
|
|
19
|
+
"email": "support@withperf.pro",
|
|
20
|
+
"url": "https://withperf.pro"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/Perf-Technology/n8n-nodes-perf.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://docs.withperf.pro",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18.0"
|
|
29
|
+
},
|
|
30
|
+
"main": "index.js",
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc && npm run copy-icons",
|
|
33
|
+
"copy-icons": "cp nodes/PerfChat/*.svg dist/nodes/PerfChat/ && cp nodes/PerfVerify/*.svg dist/nodes/PerfVerify/ && cp nodes/PerfValidate/*.svg dist/nodes/PerfValidate/",
|
|
34
|
+
"dev": "tsc --watch",
|
|
35
|
+
"lint": "eslint nodes credentials --ext .ts",
|
|
36
|
+
"lint:fix": "eslint nodes credentials --ext .ts --fix",
|
|
37
|
+
"test": "jest",
|
|
38
|
+
"prepublishOnly": "npm run build"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
],
|
|
43
|
+
"n8n": {
|
|
44
|
+
"n8nNodesApiVersion": 1,
|
|
45
|
+
"credentials": [
|
|
46
|
+
"dist/credentials/PerfApi.credentials.js"
|
|
47
|
+
],
|
|
48
|
+
"nodes": [
|
|
49
|
+
"dist/nodes/PerfChat/PerfChat.node.js",
|
|
50
|
+
"dist/nodes/PerfVerify/PerfVerify.node.js",
|
|
51
|
+
"dist/nodes/PerfValidate/PerfValidate.node.js"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/jest": "^29.0.0",
|
|
56
|
+
"@types/node": "^20.0.0",
|
|
57
|
+
"jest": "^29.0.0",
|
|
58
|
+
"ts-jest": "^29.0.0",
|
|
59
|
+
"typescript": "^5.0.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"n8n-workflow": "*"
|
|
63
|
+
}
|
|
64
|
+
}
|