n8n-nodes-notte 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.
Files changed (28) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/credentials/NotteApi.credentials.d.ts +10 -0
  4. package/dist/credentials/NotteApi.credentials.js +46 -0
  5. package/dist/credentials/NotteApi.credentials.js.map +1 -0
  6. package/dist/icons/notte.svg +90 -0
  7. package/dist/nodes/Notte/GenericFunctions.d.ts +4 -0
  8. package/dist/nodes/Notte/GenericFunctions.js +83 -0
  9. package/dist/nodes/Notte/GenericFunctions.js.map +1 -0
  10. package/dist/nodes/Notte/Notte.node.d.ts +5 -0
  11. package/dist/nodes/Notte/Notte.node.js +280 -0
  12. package/dist/nodes/Notte/Notte.node.js.map +1 -0
  13. package/dist/nodes/Notte/Notte.node.json +18 -0
  14. package/dist/nodes/Notte/NotteTrigger.node.d.ts +5 -0
  15. package/dist/nodes/Notte/NotteTrigger.node.js +112 -0
  16. package/dist/nodes/Notte/NotteTrigger.node.js.map +1 -0
  17. package/dist/nodes/Notte/descriptions/AgentDescription.d.ts +2 -0
  18. package/dist/nodes/Notte/descriptions/AgentDescription.js +115 -0
  19. package/dist/nodes/Notte/descriptions/AgentDescription.js.map +1 -0
  20. package/dist/nodes/Notte/descriptions/FunctionDescription.d.ts +2 -0
  21. package/dist/nodes/Notte/descriptions/FunctionDescription.js +101 -0
  22. package/dist/nodes/Notte/descriptions/FunctionDescription.js.map +1 -0
  23. package/dist/nodes/Notte/descriptions/ScrapeDescription.d.ts +2 -0
  24. package/dist/nodes/Notte/descriptions/ScrapeDescription.js +113 -0
  25. package/dist/nodes/Notte/descriptions/ScrapeDescription.js.map +1 -0
  26. package/dist/package.json +58 -0
  27. package/dist/tsconfig.tsbuildinfo +1 -0
  28. package/package.json +58 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Notte Labs
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,95 @@
1
+ # n8n-nodes-notte
2
+
3
+ [n8n](https://n8n.io/) community node for [Notte](https://notte.cc) — AI browser automation, web scraping, and workflow execution.
4
+
5
+ ## Features
6
+
7
+ This node provides three modes of operation:
8
+
9
+ ### Agent Mode
10
+ Run an AI agent that autonomously performs browser tasks. Provide a URL and a natural language instruction — the node handles session lifecycle, agent execution, and polling automatically.
11
+
12
+ - Structured output via JSON schema
13
+ - Auto-login with Vault credentials
14
+ - Persona identity support
15
+ - Vision and captcha solving options
16
+
17
+ ### Scrape Mode
18
+ Extract structured data from any URL. Define a JSON schema for the output format and provide extraction instructions.
19
+
20
+ - CSS selector scoping
21
+ - Proxy and captcha support
22
+ - Returns both markdown and structured JSON
23
+
24
+ ### Function Mode
25
+ Execute deployed Notte functions (authored via the [Notte CLI](https://docs.notte.cc)). Pass variables from your n8n workflow and get results back.
26
+
27
+ - Key-value variable injection from n8n expressions
28
+ - Configurable polling interval and timeout
29
+ - Fire-and-forget or wait-for-completion
30
+
31
+ ### Trigger Node
32
+ Poll for new persona emails or SMS messages to kick off workflows automatically.
33
+
34
+ ## Installation
35
+
36
+ ### In n8n (recommended)
37
+ 1. Go to **Settings > Community Nodes**
38
+ 2. Search for `n8n-nodes-notte`
39
+ 3. Click **Install**
40
+
41
+ ### Manual
42
+ ```bash
43
+ npm install n8n-nodes-notte
44
+ ```
45
+
46
+ ## Credentials
47
+
48
+ You need a Notte API key. Get one at [notte.cc](https://notte.cc).
49
+
50
+ | Field | Description |
51
+ |-------|-------------|
52
+ | API Key | Your Notte API key |
53
+ | Base URL | API endpoint (default: `https://api.notte.cc`) |
54
+
55
+ ## Example Workflows
56
+
57
+ ### Scheduled competitor scraping
58
+ ```
59
+ Schedule Trigger → Notte (Scrape: competitor.com/pricing) → Google Sheets
60
+ ```
61
+
62
+ ### AI agent task with notifications
63
+ ```
64
+ Webhook Trigger → Notte (Agent: "sign up for trial on {{url}}") → Slack
65
+ ```
66
+
67
+ ### Run deployed automation
68
+ ```
69
+ Schedule Trigger → Notte (Function: fn_abc123, variables from sheet) → Email
70
+ ```
71
+
72
+ ### React to verification emails
73
+ ```
74
+ Notte Trigger (New Email on persona) → Notte (Agent: "click verification link") → Done
75
+ ```
76
+
77
+ ## Development
78
+
79
+ ```bash
80
+ # Install dependencies
81
+ npm install
82
+
83
+ # Build
84
+ npm run build
85
+
86
+ # Lint
87
+ npm run lint
88
+
89
+ # Dev mode (auto-reload in local n8n)
90
+ npm run dev
91
+ ```
92
+
93
+ ## License
94
+
95
+ [MIT](LICENSE)
@@ -0,0 +1,10 @@
1
+ import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class NotteApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ icon: "file:../icons/notte.svg";
7
+ properties: INodeProperties[];
8
+ authenticate: IAuthenticateGeneric;
9
+ test: ICredentialTestRequest;
10
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NotteApi = void 0;
4
+ class NotteApi {
5
+ constructor() {
6
+ this.name = 'notteApi';
7
+ this.displayName = 'Notte API';
8
+ this.documentationUrl = 'https://docs.notte.cc';
9
+ this.icon = 'file:../icons/notte.svg';
10
+ this.properties = [
11
+ {
12
+ displayName: 'API Key',
13
+ name: 'apiKey',
14
+ type: 'string',
15
+ typeOptions: { password: true },
16
+ default: '',
17
+ required: true,
18
+ description: 'Your Notte API key from notte.cc',
19
+ },
20
+ {
21
+ displayName: 'Base URL',
22
+ name: 'baseUrl',
23
+ type: 'string',
24
+ default: 'https://api.notte.cc',
25
+ description: 'Notte API base URL (change for staging/dev environments)',
26
+ },
27
+ ];
28
+ this.authenticate = {
29
+ type: 'generic',
30
+ properties: {
31
+ headers: {
32
+ Authorization: '=Bearer {{$credentials.apiKey}}',
33
+ },
34
+ },
35
+ };
36
+ this.test = {
37
+ request: {
38
+ baseURL: '={{$credentials.baseUrl}}',
39
+ url: '/health',
40
+ method: 'GET',
41
+ },
42
+ };
43
+ }
44
+ }
45
+ exports.NotteApi = NotteApi;
46
+ //# sourceMappingURL=NotteApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotteApi.credentials.js","sourceRoot":"","sources":["../../credentials/NotteApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,QAAQ;IAArB;QACC,SAAI,GAAG,UAAU,CAAC;QAElB,gBAAW,GAAG,WAAW,CAAC;QAE1B,qBAAgB,GAAG,uBAAuB,CAAC;QAE3C,SAAI,GAAG,yBAAkC,CAAC;QAE1C,eAAU,GAAsB;YAC/B;gBACC,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,kCAAkC;aAC/C;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,sBAAsB;gBAC/B,WAAW,EAAE,0DAA0D;aACvE;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,iCAAiC;iBAChD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AA5CD,4BA4CC"}
@@ -0,0 +1,90 @@
1
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
2
+ width="100%" viewBox="0 0 864 800" enable-background="new 0 0 864 800" xml:space="preserve">
3
+ <path fill="#000000" opacity="1.000000" stroke="none"
4
+ d="
5
+ M542.473267,581.566589
6
+ C551.091919,596.434387 559.457642,611.028992 568.062500,625.481018
7
+ C570.148193,628.984009 569.309021,630.754150 566.021729,632.595154
8
+ C553.234253,639.756470 540.471619,646.968506 527.854065,654.422791
9
+ C523.753723,656.845215 521.594910,656.302124 519.172668,652.066467
10
+ C494.451019,608.836304 469.547699,565.710144 444.680603,522.563171
11
+ C443.875580,521.166443 443.386841,519.445068 441.479645,518.893555
12
+ C439.493500,519.914307 440.246399,521.806946 440.247955,523.291809
13
+ C440.299866,572.948181 440.382568,622.604492 440.554504,672.260559
14
+ C440.568848,676.399414 439.771118,678.909302 434.831329,678.805115
15
+ C420.509949,678.502930 406.182373,678.488464 391.857117,678.373108
16
+ C385.886841,678.325073 385.158630,677.573059 385.157837,671.888428
17
+ C385.154785,649.734741 385.020569,627.580688 385.101990,605.427368
18
+ C385.196899,579.609802 385.483154,553.793091 385.631104,527.975586
19
+ C385.643982,525.732361 386.179565,523.299011 384.123810,521.040649
20
+ C381.604034,523.156738 380.466003,526.116943 378.944611,528.760010
21
+ C355.355804,569.739807 331.810455,610.744629 308.214417,651.720215
22
+ C304.724182,657.781128 304.622375,657.698425 298.708862,654.265869
23
+ C286.753906,647.326416 274.780396,640.418884 262.804138,633.516235
24
+ C257.177277,630.273254 256.987122,629.887573 260.153625,624.391113
25
+ C276.942139,595.248901 293.780243,566.135193 310.581055,537.000061
26
+ C318.068054,524.016479 325.522552,511.014008 332.949432,497.995972
27
+ C333.807983,496.491089 335.348755,495.076324 334.237854,492.914307
28
+ C331.824432,491.884949 330.136597,493.690399 328.394714,494.692871
29
+ C295.193298,513.800232 262.031952,532.977234 228.858109,552.132568
30
+ C220.059784,557.212891 211.179703,562.156372 202.476654,567.394531
31
+ C199.249939,569.336670 197.391373,568.684509 195.623749,565.598816
32
+ C188.090744,552.448364 180.482101,539.341064 172.854752,526.244995
33
+ C170.802673,522.721619 172.374893,520.834473 175.445892,519.071472
34
+ C196.391983,507.046600 217.277557,494.916382 238.196320,482.843781
35
+ C260.123169,470.189514 282.065918,457.562805 303.999298,444.919861
36
+ C305.533691,444.035400 307.372162,443.462036 308.000702,441.261475
37
+ C305.677490,439.532990 303.098846,440.206635 300.724976,440.204773
38
+ C252.566071,440.167084 204.407104,440.191956 156.248154,440.197693
39
+ C148.710190,440.198608 148.720169,440.183685 148.722137,432.751282
40
+ C148.725739,419.086823 148.708420,405.422363 148.715836,391.757904
41
+ C148.719315,385.360870 149.113739,384.932678 155.508636,384.932556
42
+ C201.501205,384.931732 247.493805,384.969482 293.486328,384.933746
43
+ C297.230560,384.930847 301.073730,385.497101 304.749817,384.148895
44
+ C304.881012,381.536652 302.963562,380.903992 301.458893,380.034882
45
+ C260.071747,356.128448 218.678696,332.232208 177.268646,308.365479
46
+ C170.515564,304.473389 170.442200,304.511230 174.286285,297.853485
47
+ C181.282303,285.736725 188.420593,273.700531 195.275192,261.504669
48
+ C197.255692,257.980927 199.143875,257.164093 202.775070,259.273041
49
+ C237.770111,279.597809 272.826752,299.816528 307.871155,320.056274
50
+ C314.936554,324.136902 322.012970,328.198822 329.111755,332.220978
51
+ C330.514893,333.016022 331.936310,334.029602 334.038239,333.382568
52
+ C334.493256,330.647400 332.679596,328.708008 331.510498,326.683960
53
+ C307.685211,285.435150 283.839661,244.197906 259.873535,203.030899
54
+ C257.520233,198.988617 257.816193,196.642578 262.145691,194.342010
55
+ C274.649841,187.697723 286.673859,180.225296 298.449005,172.355087
56
+ C303.794922,168.782028 304.460022,168.896652 307.839966,174.170563
57
+ C329.769653,208.388062 351.616058,242.658997 373.593933,276.845459
58
+ C393.948578,308.507019 414.450409,340.073853 434.852875,371.704712
59
+ C444.136597,386.097717 457.497498,395.824005 471.734467,404.736206
60
+ C525.236389,438.227661 578.639099,471.877563 632.075317,505.474030
61
+ C639.687317,510.259918 647.222717,515.170898 654.905212,519.840149
62
+ C658.308655,521.908691 658.421448,524.060059 656.397949,527.221008
63
+ C648.680298,539.276672 640.905029,551.296204 634.040466,563.881653
64
+ C630.809692,569.804871 630.143433,569.773071 624.440857,566.473511
65
+ C581.632996,541.704224 538.816772,516.949524 495.994263,492.205536
66
+ C494.592438,491.395599 493.252747,490.286194 490.063690,490.838715
67
+ C507.647583,521.265381 524.977844,551.253174 542.473267,581.566589
68
+ z"/>
69
+ <path fill="#000000" opacity="1.000000" stroke="none"
70
+ d="
71
+ M573.031311,367.251953
72
+ C525.028137,365.816040 491.512665,343.236115 472.070496,300.057220
73
+ C466.432709,287.536438 463.664764,274.075531 463.912292,260.226013
74
+ C464.564117,223.756668 465.338135,187.289429 466.116730,150.822479
75
+ C466.270142,143.638168 467.121674,142.854797 474.327972,142.973022
76
+ C488.148499,143.199753 501.966492,143.621719 515.787537,143.753998
77
+ C520.301453,143.797211 522.114136,145.724731 521.982666,150.112488
78
+ C521.095276,179.738205 520.153870,209.363022 519.461609,238.993546
79
+ C519.148193,252.408127 517.792664,265.816132 522.763550,278.996185
80
+ C529.509399,296.882324 549.189026,311.623169 568.425476,311.759003
81
+ C608.575562,312.042419 648.707581,310.917297 688.841797,310.009857
82
+ C692.172729,309.934570 695.506714,310.005707 698.838928,309.976776
83
+ C702.553711,309.944580 704.256775,311.638184 704.220825,315.470398
84
+ C704.125305,325.634949 704.150574,335.802063 704.268860,345.966522
85
+ C704.319153,350.285614 704.833252,354.597992 704.936157,358.918182
86
+ C705.071777,364.610809 703.685547,365.993896 697.966187,366.023895
87
+ C671.803284,366.161041 645.639587,366.186188 619.477478,366.407501
88
+ C604.159058,366.537079 588.843079,366.959534 573.031311,367.251953
89
+ z"/>
90
+ </svg>
@@ -0,0 +1,4 @@
1
+ import type { IExecuteFunctions, IHookFunctions, ILoadOptionsFunctions, IPollFunctions, IHttpRequestMethods } from 'n8n-workflow';
2
+ export declare function notteApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions | IPollFunctions | IHookFunctions, method: IHttpRequestMethods, endpoint: string, body?: object, qs?: Record<string, string | number | boolean>, extraHeaders?: Record<string, string>): Promise<unknown>;
3
+ export declare function notteApiRequestWithPolling(this: IExecuteFunctions, pollMethod: IHttpRequestMethods, pollEndpoint: string, statusField: string, terminalStatuses: string[], pollIntervalMs?: number, timeoutMs?: number): Promise<unknown>;
4
+ export declare function notteApiRequestWithRedirect(this: IExecuteFunctions, method: IHttpRequestMethods, endpoint: string, body?: object, extraHeaders?: Record<string, string>): Promise<unknown>;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.notteApiRequest = notteApiRequest;
4
+ exports.notteApiRequestWithPolling = notteApiRequestWithPolling;
5
+ exports.notteApiRequestWithRedirect = notteApiRequestWithRedirect;
6
+ const n8n_workflow_1 = require("n8n-workflow");
7
+ async function notteApiRequest(method, endpoint, body, qs, extraHeaders) {
8
+ var _a, _b;
9
+ const credentials = await this.getCredentials('notteApi');
10
+ const baseUrl = credentials.baseUrl || 'https://api.notte.cc';
11
+ const options = {
12
+ method,
13
+ url: `${baseUrl}${endpoint}`,
14
+ headers: {
15
+ Accept: 'application/json',
16
+ 'Content-Type': 'application/json',
17
+ Authorization: `Bearer ${credentials.apiKey}`,
18
+ ...extraHeaders,
19
+ },
20
+ json: true,
21
+ };
22
+ if (body && Object.keys(body).length > 0) {
23
+ options.body = body;
24
+ }
25
+ if (qs && Object.keys(qs).length > 0) {
26
+ options.qs = qs;
27
+ }
28
+ try {
29
+ return await this.helpers.httpRequest(options);
30
+ }
31
+ catch (error) {
32
+ const err = error;
33
+ const detail = ((_a = err.response) === null || _a === void 0 ? void 0 : _a.data)
34
+ ? JSON.stringify(err.response.data)
35
+ : ((_b = err.message) !== null && _b !== void 0 ? _b : 'Unknown error');
36
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Notte API error (${endpoint}): ${detail}`);
37
+ }
38
+ }
39
+ async function notteApiRequestWithPolling(pollMethod, pollEndpoint, statusField, terminalStatuses, pollIntervalMs = 2000, timeoutMs = 300000) {
40
+ const startTime = Date.now();
41
+ while (Date.now() - startTime < timeoutMs) {
42
+ const response = (await notteApiRequest.call(this, pollMethod, pollEndpoint));
43
+ const status = response[statusField];
44
+ if (terminalStatuses.includes(status)) {
45
+ return response;
46
+ }
47
+ await (0, n8n_workflow_1.sleep)(pollIntervalMs);
48
+ }
49
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Polling timed out after ${timeoutMs / 1000}s waiting for ${pollEndpoint}`);
50
+ }
51
+ async function notteApiRequestWithRedirect(method, endpoint, body, extraHeaders) {
52
+ const credentials = await this.getCredentials('notteApi');
53
+ const baseUrl = credentials.baseUrl || 'https://api.notte.cc';
54
+ const headers = {
55
+ Accept: 'application/json',
56
+ 'Content-Type': 'application/json',
57
+ Authorization: `Bearer ${credentials.apiKey}`,
58
+ ...extraHeaders,
59
+ };
60
+ const jsonBody = body && Object.keys(body).length > 0 ? JSON.stringify(body) : undefined;
61
+ let response = await fetch(`${baseUrl}${endpoint}`, {
62
+ method,
63
+ headers,
64
+ body: jsonBody,
65
+ redirect: 'manual',
66
+ });
67
+ if (response.status >= 300 && response.status < 400) {
68
+ const location = response.headers.get('location');
69
+ if (location) {
70
+ response = await fetch(location, {
71
+ method,
72
+ headers,
73
+ body: jsonBody,
74
+ });
75
+ }
76
+ }
77
+ if (!response.ok) {
78
+ const text = await response.text();
79
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Notte API error (${endpoint}): ${response.status} ${text}`);
80
+ }
81
+ return response.json();
82
+ }
83
+ //# sourceMappingURL=GenericFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenericFunctions.js","sourceRoot":"","sources":["../../../nodes/Notte/GenericFunctions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type IExecuteFunctions, type INodeExecutionData, type INodeType, type INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class Notte implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Notte = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const GenericFunctions_1 = require("./GenericFunctions");
6
+ const AgentDescription_1 = require("./descriptions/AgentDescription");
7
+ const ScrapeDescription_1 = require("./descriptions/ScrapeDescription");
8
+ const FunctionDescription_1 = require("./descriptions/FunctionDescription");
9
+ class Notte {
10
+ constructor() {
11
+ this.description = {
12
+ displayName: 'Notte',
13
+ name: 'notte',
14
+ icon: 'file:../../icons/notte.svg',
15
+ group: ['transform'],
16
+ version: 1,
17
+ subtitle: '={{ "Mode: " + $parameter["mode"] }}',
18
+ description: 'AI browser automation, web scraping, and workflow execution powered by Notte',
19
+ defaults: {
20
+ name: 'Notte',
21
+ },
22
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
23
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
24
+ usableAsTool: true,
25
+ credentials: [
26
+ {
27
+ name: 'notteApi',
28
+ required: true,
29
+ },
30
+ ],
31
+ properties: [
32
+ {
33
+ displayName: 'Mode',
34
+ name: 'mode',
35
+ type: 'options',
36
+ noDataExpression: true,
37
+ options: [
38
+ {
39
+ name: 'Agent',
40
+ value: 'agent',
41
+ description: 'Run an AI agent to perform browser tasks autonomously',
42
+ },
43
+ {
44
+ name: 'Scrape',
45
+ value: 'scrape',
46
+ description: 'Extract structured data from a URL',
47
+ },
48
+ {
49
+ name: 'Function',
50
+ value: 'function',
51
+ description: 'Run a deployed Notte function (author via CLI, execute here)',
52
+ },
53
+ ],
54
+ default: 'agent',
55
+ },
56
+ ...AgentDescription_1.agentFields,
57
+ ...ScrapeDescription_1.scrapeFields,
58
+ ...FunctionDescription_1.functionFields,
59
+ ],
60
+ };
61
+ }
62
+ async execute() {
63
+ const items = this.getInputData();
64
+ const returnData = [];
65
+ for (let i = 0; i < items.length; i++) {
66
+ try {
67
+ const mode = this.getNodeParameter('mode', i);
68
+ let result;
69
+ if (mode === 'agent') {
70
+ result = await executeAgent.call(this, i);
71
+ }
72
+ else if (mode === 'scrape') {
73
+ result = await executeScrape.call(this, i);
74
+ }
75
+ else if (mode === 'function') {
76
+ result = await executeFunction.call(this, i);
77
+ }
78
+ else {
79
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown mode: ${mode}`);
80
+ }
81
+ returnData.push({
82
+ json: result,
83
+ pairedItem: { item: i },
84
+ });
85
+ }
86
+ catch (error) {
87
+ if (this.continueOnFail()) {
88
+ returnData.push({
89
+ json: {
90
+ success: false,
91
+ error: error instanceof Error ? error.message : String(error),
92
+ },
93
+ pairedItem: { item: i },
94
+ });
95
+ continue;
96
+ }
97
+ throw error;
98
+ }
99
+ }
100
+ return [returnData];
101
+ }
102
+ }
103
+ exports.Notte = Notte;
104
+ async function executeAgent(itemIndex) {
105
+ var _a, _b, _c, _d, _e, _f;
106
+ const task = this.getNodeParameter('task', itemIndex);
107
+ let url = this.getNodeParameter('url', itemIndex, '');
108
+ const options = this.getNodeParameter('agentOptions', itemIndex, {});
109
+ if (url && !url.startsWith('http://') && !url.startsWith('https://')) {
110
+ url = `https://${url}`;
111
+ }
112
+ const sessionBody = {
113
+ headless: (_a = options.headless) !== null && _a !== void 0 ? _a : true,
114
+ solve_captchas: (_b = options.solveCaptchas) !== null && _b !== void 0 ? _b : false,
115
+ };
116
+ if (options.proxy) {
117
+ sessionBody.proxies = true;
118
+ }
119
+ const sessionResponse = (await GenericFunctions_1.notteApiRequest.call(this, 'POST', '/sessions/start', sessionBody));
120
+ const sessionId = sessionResponse.session_id;
121
+ if (!sessionId) {
122
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to get session_id from session start response');
123
+ }
124
+ let agentId;
125
+ try {
126
+ const agentBody = {
127
+ task,
128
+ session_id: sessionId,
129
+ };
130
+ if (url) {
131
+ agentBody.url = url;
132
+ }
133
+ if (options.maxSteps) {
134
+ agentBody.max_steps = options.maxSteps;
135
+ }
136
+ if (options.useVision !== undefined) {
137
+ agentBody.use_vision = options.useVision;
138
+ }
139
+ if (options.reasoningModel) {
140
+ agentBody.reasoning_model = options.reasoningModel;
141
+ }
142
+ if (options.vaultId) {
143
+ agentBody.vault_id = options.vaultId;
144
+ }
145
+ if (options.personaId) {
146
+ agentBody.persona_id = options.personaId;
147
+ }
148
+ if (options.responseFormat) {
149
+ try {
150
+ agentBody.response_format = JSON.parse(options.responseFormat);
151
+ }
152
+ catch {
153
+ agentBody.response_format = options.responseFormat;
154
+ }
155
+ }
156
+ const agentResponse = (await GenericFunctions_1.notteApiRequest.call(this, 'POST', '/agents/start', agentBody));
157
+ agentId = agentResponse.agent_id;
158
+ if (!agentId) {
159
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to get agent_id from agent start response');
160
+ }
161
+ const finalStatus = (await GenericFunctions_1.notteApiRequestWithPolling.call(this, 'GET', `/agents/${agentId}`, 'status', ['closed', 'error', 'failed'], 2000, 300000));
162
+ try {
163
+ await GenericFunctions_1.notteApiRequest.call(this, 'DELETE', `/sessions/${sessionId}/stop`);
164
+ }
165
+ catch {
166
+ }
167
+ return {
168
+ success: (_c = finalStatus.success) !== null && _c !== void 0 ? _c : false,
169
+ answer: (_d = finalStatus.answer) !== null && _d !== void 0 ? _d : null,
170
+ task: (_e = finalStatus.task) !== null && _e !== void 0 ? _e : task,
171
+ steps: (_f = finalStatus.steps) !== null && _f !== void 0 ? _f : [],
172
+ agent_id: agentId,
173
+ session_id: sessionId,
174
+ status: finalStatus.status,
175
+ };
176
+ }
177
+ catch (error) {
178
+ if (agentId) {
179
+ try {
180
+ await GenericFunctions_1.notteApiRequest.call(this, 'DELETE', `/agents/${agentId}/stop`, undefined, { session_id: sessionId });
181
+ }
182
+ catch {
183
+ }
184
+ }
185
+ try {
186
+ await GenericFunctions_1.notteApiRequest.call(this, 'DELETE', `/sessions/${sessionId}/stop`);
187
+ }
188
+ catch {
189
+ }
190
+ throw error;
191
+ }
192
+ }
193
+ async function executeScrape(itemIndex) {
194
+ var _a, _b, _c, _d, _e, _f, _g, _h;
195
+ let url = this.getNodeParameter('scrapeUrl', itemIndex);
196
+ const instructions = this.getNodeParameter('instructions', itemIndex);
197
+ const responseFormatRaw = this.getNodeParameter('scrapeResponseFormat', itemIndex);
198
+ const options = this.getNodeParameter('scrapeOptions', itemIndex, {});
199
+ if (url && !url.startsWith('http://') && !url.startsWith('https://')) {
200
+ url = `https://${url}`;
201
+ }
202
+ let responseFormat;
203
+ try {
204
+ responseFormat = JSON.parse(responseFormatRaw);
205
+ }
206
+ catch {
207
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Response Format must be valid JSON (a JSON schema)');
208
+ }
209
+ const body = {
210
+ url,
211
+ instructions,
212
+ response_format: responseFormat,
213
+ headless: (_a = options.headless) !== null && _a !== void 0 ? _a : true,
214
+ only_main_content: (_b = options.onlyMainContent) !== null && _b !== void 0 ? _b : true,
215
+ scrape_links: (_c = options.scrapeLinks) !== null && _c !== void 0 ? _c : true,
216
+ scrape_images: (_d = options.scrapeImages) !== null && _d !== void 0 ? _d : false,
217
+ solve_captchas: (_e = options.solveCaptchas) !== null && _e !== void 0 ? _e : false,
218
+ };
219
+ if (options.proxy) {
220
+ body.proxies = true;
221
+ }
222
+ if (options.selector) {
223
+ body.selector = options.selector;
224
+ }
225
+ const response = (await GenericFunctions_1.notteApiRequest.call(this, 'POST', '/scrape', body));
226
+ return {
227
+ success: true,
228
+ markdown: (_f = response.markdown) !== null && _f !== void 0 ? _f : null,
229
+ structured: (_g = response.structured) !== null && _g !== void 0 ? _g : null,
230
+ images: (_h = response.images) !== null && _h !== void 0 ? _h : [],
231
+ url,
232
+ };
233
+ }
234
+ async function executeFunction(itemIndex) {
235
+ var _a, _b, _c, _d, _e, _f;
236
+ const functionId = this.getNodeParameter('functionId', itemIndex);
237
+ const variablesParam = this.getNodeParameter('variables', itemIndex, {});
238
+ const options = this.getNodeParameter('functionOptions', itemIndex, {});
239
+ const variables = {};
240
+ if ((_a = variablesParam.variableValues) === null || _a === void 0 ? void 0 : _a.length) {
241
+ for (const v of variablesParam.variableValues) {
242
+ if (v.name) {
243
+ variables[v.name] = v.value;
244
+ }
245
+ }
246
+ }
247
+ const runBody = {
248
+ workflow_id: functionId,
249
+ };
250
+ if (Object.keys(variables).length > 0) {
251
+ runBody.variables = variables;
252
+ }
253
+ const credentials = await this.getCredentials('notteApi');
254
+ const runResponse = (await GenericFunctions_1.notteApiRequestWithRedirect.call(this, 'POST', `/functions/${functionId}/runs/start`, runBody, { 'x-notte-api-key': credentials.apiKey }));
255
+ const runId = runResponse.function_run_id;
256
+ if (!runId) {
257
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Failed to get function_run_id from run start response');
258
+ }
259
+ const waitForCompletion = (_b = options.waitForCompletion) !== null && _b !== void 0 ? _b : true;
260
+ if (!waitForCompletion) {
261
+ return {
262
+ success: true,
263
+ function_id: functionId,
264
+ function_run_id: runId,
265
+ status: 'started',
266
+ };
267
+ }
268
+ const timeoutMs = ((_c = options.timeout) !== null && _c !== void 0 ? _c : 300) * 1000;
269
+ const pollIntervalMs = ((_d = options.pollInterval) !== null && _d !== void 0 ? _d : 2) * 1000;
270
+ const finalStatus = (await GenericFunctions_1.notteApiRequestWithPolling.call(this, 'GET', `/functions/${functionId}/runs/${runId}`, 'status', ['closed', 'failed', 'stopped'], pollIntervalMs, timeoutMs));
271
+ return {
272
+ success: finalStatus.status === 'closed',
273
+ function_id: functionId,
274
+ function_run_id: runId,
275
+ status: finalStatus.status,
276
+ result: (_e = finalStatus.result) !== null && _e !== void 0 ? _e : null,
277
+ logs: (_f = finalStatus.logs) !== null && _f !== void 0 ? _f : [],
278
+ };
279
+ }
280
+ //# sourceMappingURL=Notte.node.js.map