notte-sdk 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/index.d.mts +1035 -46
- package/dist/index.d.ts +1035 -46
- package/dist/index.js +228 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +219 -4
- package/dist/index.mjs.map +1 -1
- package/dist/proxy/core.js +9 -0
- package/dist/proxy/core.js.map +1 -1
- package/dist/proxy/core.mjs +9 -0
- package/dist/proxy/core.mjs.map +1 -1
- package/dist/proxy/next.js +9 -0
- package/dist/proxy/next.js.map +1 -1
- package/dist/proxy/next.mjs +9 -0
- package/dist/proxy/next.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
Agent: () => Agent,
|
|
34
|
+
Encryption: () => Encryption,
|
|
34
35
|
NotteClient: () => NotteClient,
|
|
35
36
|
NotteFunction: () => NotteFunction,
|
|
36
37
|
NottePersona: () => NottePersona,
|
|
@@ -55,6 +56,7 @@ __export(index_exports, {
|
|
|
55
56
|
functionDelete: () => functionDelete,
|
|
56
57
|
functionDownloadUrl: () => functionDownloadUrl,
|
|
57
58
|
functionFork: () => functionFork,
|
|
59
|
+
functionMetadataUpdate: () => functionMetadataUpdate,
|
|
58
60
|
functionRunGetMetadata: () => functionRunGetMetadata,
|
|
59
61
|
functionRunStart: () => functionRunStart,
|
|
60
62
|
functionRunStop: () => functionRunStop,
|
|
@@ -76,6 +78,12 @@ __export(index_exports, {
|
|
|
76
78
|
listSecrets: () => listSecrets,
|
|
77
79
|
listSessions: () => listSessions,
|
|
78
80
|
listVaults: () => listVaults,
|
|
81
|
+
mailboxConnectToken: () => mailboxConnectToken,
|
|
82
|
+
mailboxDelete: () => mailboxDelete,
|
|
83
|
+
mailboxGet: () => mailboxGet,
|
|
84
|
+
mailboxList: () => mailboxList,
|
|
85
|
+
mailboxSync: () => mailboxSync,
|
|
86
|
+
mailboxUpdate: () => mailboxUpdate,
|
|
79
87
|
nudgePrompt: () => nudgePrompt,
|
|
80
88
|
pageExecute: () => pageExecute,
|
|
81
89
|
pageObserve: () => pageObserve,
|
|
@@ -86,6 +94,7 @@ __export(index_exports, {
|
|
|
86
94
|
personaEmailsList: () => personaEmailsList,
|
|
87
95
|
personaGet: () => personaGet,
|
|
88
96
|
personaSmsList: () => personaSmsList,
|
|
97
|
+
personaUpdate: () => personaUpdate,
|
|
89
98
|
profileCookiesGet: () => profileCookiesGet,
|
|
90
99
|
profileCookiesSet: () => profileCookiesSet,
|
|
91
100
|
profileCreate: () => profileCreate,
|
|
@@ -121,7 +130,7 @@ __export(index_exports, {
|
|
|
121
130
|
module.exports = __toCommonJS(index_exports);
|
|
122
131
|
|
|
123
132
|
// src/version.ts
|
|
124
|
-
var SDK_VERSION = true ? "0.0.
|
|
133
|
+
var SDK_VERSION = true ? "0.0.20" : "dev";
|
|
125
134
|
var SDK_PACKAGE_NAME = true ? "notte-sdk" : "notte-sdk";
|
|
126
135
|
|
|
127
136
|
// src/version-check.ts
|
|
@@ -1183,6 +1192,15 @@ var functionDownloadUrl = (options) => (options.client ?? client).get({
|
|
|
1183
1192
|
url: "/functions/{function_id}",
|
|
1184
1193
|
...options
|
|
1185
1194
|
});
|
|
1195
|
+
var functionMetadataUpdate = (options) => (options.client ?? client).patch({
|
|
1196
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1197
|
+
url: "/functions/{function_id}",
|
|
1198
|
+
...options,
|
|
1199
|
+
headers: {
|
|
1200
|
+
"Content-Type": "application/json",
|
|
1201
|
+
...options.headers
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1186
1204
|
var functionUpdate = (options) => (options.client ?? client).post({
|
|
1187
1205
|
...formDataBodySerializer,
|
|
1188
1206
|
security: [{ scheme: "bearer", type: "http" }],
|
|
@@ -1382,6 +1400,15 @@ var personaGet = (options) => (options.client ?? client).get({
|
|
|
1382
1400
|
url: "/personas/{persona_id}",
|
|
1383
1401
|
...options
|
|
1384
1402
|
});
|
|
1403
|
+
var personaUpdate = (options) => (options.client ?? client).patch({
|
|
1404
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1405
|
+
url: "/personas/{persona_id}",
|
|
1406
|
+
...options,
|
|
1407
|
+
headers: {
|
|
1408
|
+
"Content-Type": "application/json",
|
|
1409
|
+
...options.headers
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1385
1412
|
var personaEmailsList = (options) => (options.client ?? client).get({
|
|
1386
1413
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1387
1414
|
url: "/personas/{persona_id}/emails",
|
|
@@ -1397,6 +1424,48 @@ var personaSmsList = (options) => (options.client ?? client).get({
|
|
|
1397
1424
|
url: "/personas/{persona_id}/sms",
|
|
1398
1425
|
...options
|
|
1399
1426
|
});
|
|
1427
|
+
var mailboxConnectToken = (options) => (options.client ?? client).post({
|
|
1428
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1429
|
+
url: "/mailboxes/connect-token",
|
|
1430
|
+
...options,
|
|
1431
|
+
headers: {
|
|
1432
|
+
"Content-Type": "application/json",
|
|
1433
|
+
...options.headers
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
var mailboxSync = (options) => (options?.client ?? client).post({
|
|
1437
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1438
|
+
url: "/mailboxes/sync",
|
|
1439
|
+
...options,
|
|
1440
|
+
headers: {
|
|
1441
|
+
"Content-Type": "application/json",
|
|
1442
|
+
...options?.headers
|
|
1443
|
+
}
|
|
1444
|
+
});
|
|
1445
|
+
var mailboxList = (options) => (options?.client ?? client).get({
|
|
1446
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1447
|
+
url: "/mailboxes",
|
|
1448
|
+
...options
|
|
1449
|
+
});
|
|
1450
|
+
var mailboxDelete = (options) => (options.client ?? client).delete({
|
|
1451
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1452
|
+
url: "/mailboxes/{mailbox_id}",
|
|
1453
|
+
...options
|
|
1454
|
+
});
|
|
1455
|
+
var mailboxGet = (options) => (options.client ?? client).get({
|
|
1456
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1457
|
+
url: "/mailboxes/{mailbox_id}",
|
|
1458
|
+
...options
|
|
1459
|
+
});
|
|
1460
|
+
var mailboxUpdate = (options) => (options.client ?? client).patch({
|
|
1461
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1462
|
+
url: "/mailboxes/{mailbox_id}",
|
|
1463
|
+
...options,
|
|
1464
|
+
headers: {
|
|
1465
|
+
"Content-Type": "application/json",
|
|
1466
|
+
...options.headers
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1400
1469
|
var improvePrompt = (options) => (options.client ?? client).post({
|
|
1401
1470
|
url: "/prompts/improve",
|
|
1402
1471
|
...options,
|
|
@@ -1610,14 +1679,24 @@ var Session = class {
|
|
|
1610
1679
|
this.isActive = false;
|
|
1611
1680
|
this.response = null;
|
|
1612
1681
|
this.client = client2;
|
|
1613
|
-
const { open_viewer = false, ...sessionOptions } = options;
|
|
1682
|
+
const { open_viewer = false, headless, ...sessionOptions } = options;
|
|
1614
1683
|
this.options = sessionOptions;
|
|
1615
1684
|
this.openViewer = open_viewer;
|
|
1685
|
+
this.legacyHeadless = headless;
|
|
1616
1686
|
}
|
|
1617
1687
|
/**
|
|
1618
1688
|
* Start the session - creates a new session on the server
|
|
1619
1689
|
*/
|
|
1620
1690
|
async start() {
|
|
1691
|
+
if (this.legacyHeadless === false) {
|
|
1692
|
+
throw new Error(
|
|
1693
|
+
"Remote `headless: false` is no longer supported. `headless: true` sessions still include session replays and access to the live viewer."
|
|
1694
|
+
);
|
|
1695
|
+
}
|
|
1696
|
+
if (this.legacyHeadless === true) {
|
|
1697
|
+
console.warn("`headless: true` is deprecated and ignored; remote sessions always use the supported browser launch mode.");
|
|
1698
|
+
this.legacyHeadless = void 0;
|
|
1699
|
+
}
|
|
1621
1700
|
if (this.isActive) {
|
|
1622
1701
|
throw new Error("Session is already active");
|
|
1623
1702
|
}
|
|
@@ -1645,7 +1724,7 @@ var Session = class {
|
|
|
1645
1724
|
/**
|
|
1646
1725
|
* Stop the session - terminates the session on the server
|
|
1647
1726
|
*/
|
|
1648
|
-
async stop() {
|
|
1727
|
+
async stop(closeReason = "manual") {
|
|
1649
1728
|
if (!this.isActive || !this.sessionId) {
|
|
1650
1729
|
return;
|
|
1651
1730
|
}
|
|
@@ -1653,6 +1732,9 @@ var Session = class {
|
|
|
1653
1732
|
client: this.client.getClient(),
|
|
1654
1733
|
path: {
|
|
1655
1734
|
session_id: this.sessionId
|
|
1735
|
+
},
|
|
1736
|
+
query: {
|
|
1737
|
+
close_reason: closeReason
|
|
1656
1738
|
}
|
|
1657
1739
|
});
|
|
1658
1740
|
if (response?.error) {
|
|
@@ -1871,10 +1953,21 @@ var Session = class {
|
|
|
1871
1953
|
*/
|
|
1872
1954
|
async use(callback) {
|
|
1873
1955
|
await this.start();
|
|
1956
|
+
let callbackFailed = false;
|
|
1874
1957
|
try {
|
|
1875
1958
|
return await callback(this);
|
|
1959
|
+
} catch (error) {
|
|
1960
|
+
callbackFailed = true;
|
|
1961
|
+
throw error;
|
|
1876
1962
|
} finally {
|
|
1877
|
-
|
|
1963
|
+
try {
|
|
1964
|
+
await this.stop(callbackFailed ? "error" : "manual");
|
|
1965
|
+
} catch (stopError) {
|
|
1966
|
+
if (!callbackFailed) {
|
|
1967
|
+
throw stopError;
|
|
1968
|
+
}
|
|
1969
|
+
console.error("[Session] Failed to stop session after callback error:", stopError);
|
|
1970
|
+
}
|
|
1878
1971
|
}
|
|
1879
1972
|
}
|
|
1880
1973
|
/**
|
|
@@ -2806,6 +2899,59 @@ var NottePersona = class {
|
|
|
2806
2899
|
};
|
|
2807
2900
|
|
|
2808
2901
|
// src/functions.ts
|
|
2902
|
+
var import_promises = require("fs/promises");
|
|
2903
|
+
|
|
2904
|
+
// src/encryption.ts
|
|
2905
|
+
var import_node_crypto = require("crypto");
|
|
2906
|
+
var SALT_LENGTH = 16;
|
|
2907
|
+
var PBKDF2_ITERATIONS = 1e5;
|
|
2908
|
+
var PBKDF2_KEY_LENGTH = 32;
|
|
2909
|
+
var FERNET_VERSION = 128;
|
|
2910
|
+
var FERNET_IV_LENGTH = 16;
|
|
2911
|
+
var FERNET_HMAC_LENGTH = 32;
|
|
2912
|
+
var FERNET_HEADER_LENGTH = 1 + 8 + FERNET_IV_LENGTH;
|
|
2913
|
+
var Encryption = class {
|
|
2914
|
+
constructor(rootKey) {
|
|
2915
|
+
if (!rootKey) {
|
|
2916
|
+
throw new Error("Root key cannot be empty");
|
|
2917
|
+
}
|
|
2918
|
+
this.rootKey = rootKey;
|
|
2919
|
+
}
|
|
2920
|
+
decrypt(token) {
|
|
2921
|
+
const combined = Buffer.from(token, "base64url");
|
|
2922
|
+
if (combined.length <= SALT_LENGTH) {
|
|
2923
|
+
throw new Error("Invalid encrypted token: too short to contain a salt");
|
|
2924
|
+
}
|
|
2925
|
+
const salt = combined.subarray(0, SALT_LENGTH);
|
|
2926
|
+
const fernetToken = combined.subarray(SALT_LENGTH).toString("utf8");
|
|
2927
|
+
const key = (0, import_node_crypto.pbkdf2Sync)(this.rootKey, salt, PBKDF2_ITERATIONS, PBKDF2_KEY_LENGTH, "sha256");
|
|
2928
|
+
return decryptFernet(fernetToken, key);
|
|
2929
|
+
}
|
|
2930
|
+
};
|
|
2931
|
+
function decryptFernet(token, key) {
|
|
2932
|
+
const signingKey = key.subarray(0, 16);
|
|
2933
|
+
const encryptionKey = key.subarray(16);
|
|
2934
|
+
const data = Buffer.from(token, "base64url");
|
|
2935
|
+
if (data.length < FERNET_HEADER_LENGTH + FERNET_HMAC_LENGTH) {
|
|
2936
|
+
throw new Error("Invalid Fernet token: too short");
|
|
2937
|
+
}
|
|
2938
|
+
if (data[0] !== FERNET_VERSION) {
|
|
2939
|
+
throw new Error(`Invalid Fernet token: unsupported version 0x${data[0].toString(16)}`);
|
|
2940
|
+
}
|
|
2941
|
+
const signed = data.subarray(0, data.length - FERNET_HMAC_LENGTH);
|
|
2942
|
+
const signature = data.subarray(data.length - FERNET_HMAC_LENGTH);
|
|
2943
|
+
const expected = (0, import_node_crypto.createHmac)("sha256", signingKey).update(signed).digest();
|
|
2944
|
+
if (!(0, import_node_crypto.timingSafeEqual)(signature, expected)) {
|
|
2945
|
+
throw new Error("Invalid Fernet token: signature verification failed");
|
|
2946
|
+
}
|
|
2947
|
+
const iv = signed.subarray(9, FERNET_HEADER_LENGTH);
|
|
2948
|
+
const ciphertext = signed.subarray(FERNET_HEADER_LENGTH);
|
|
2949
|
+
const decipher = (0, import_node_crypto.createDecipheriv)("aes-128-cbc", encryptionKey, iv);
|
|
2950
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
// src/functions.ts
|
|
2954
|
+
var DOWNLOAD_TIMEOUT_MS = 3e4;
|
|
2809
2955
|
var NotteFunction = class {
|
|
2810
2956
|
constructor(client2, options) {
|
|
2811
2957
|
this.client = client2;
|
|
@@ -2871,6 +3017,72 @@ var NotteFunction = class {
|
|
|
2871
3017
|
throw new Error(`Failed to run function: ${error instanceof Error ? error.message : String(error)}`);
|
|
2872
3018
|
}
|
|
2873
3019
|
}
|
|
3020
|
+
/**
|
|
3021
|
+
* Get the download URL of the function code, decrypting it when the API
|
|
3022
|
+
* returns an encrypted one (Notte managed functions).
|
|
3023
|
+
*/
|
|
3024
|
+
async getUrl(options = {}) {
|
|
3025
|
+
let response;
|
|
3026
|
+
try {
|
|
3027
|
+
response = await functionDownloadUrl({
|
|
3028
|
+
client: this.client.getClient(),
|
|
3029
|
+
path: {
|
|
3030
|
+
function_id: this.functionId
|
|
3031
|
+
},
|
|
3032
|
+
query: options.version ? { version: options.version } : {}
|
|
3033
|
+
});
|
|
3034
|
+
} catch (error) {
|
|
3035
|
+
throw new Error(`Failed to get function download url: ${error instanceof Error ? error.message : String(error)}`);
|
|
3036
|
+
}
|
|
3037
|
+
if (response?.error) {
|
|
3038
|
+
throw new Error(`Failed to get function download url: ${formatError(response.error)}`);
|
|
3039
|
+
}
|
|
3040
|
+
const url = response.data.url;
|
|
3041
|
+
if (isHttpUrl(url)) {
|
|
3042
|
+
return url;
|
|
3043
|
+
}
|
|
3044
|
+
const decryptionKey = options.decryption_key ?? this.decryptionKey;
|
|
3045
|
+
if (!decryptionKey) {
|
|
3046
|
+
throw new Error(
|
|
3047
|
+
"Decryption key is required to decrypt the function download url. Set it when creating the function, i.e. client.NotteFunction({ function_id: '<your-function-id>', decryption_key: '<your-key>' })."
|
|
3048
|
+
);
|
|
3049
|
+
}
|
|
3050
|
+
let decrypted;
|
|
3051
|
+
try {
|
|
3052
|
+
decrypted = new Encryption(decryptionKey).decrypt(url);
|
|
3053
|
+
} catch (error) {
|
|
3054
|
+
throw new Error(`Failed to decrypt the function download url: ${error instanceof Error ? error.message : String(error)}. Contact support@notte.cc if you need help.`);
|
|
3055
|
+
}
|
|
3056
|
+
if (!isHttpUrl(decrypted)) {
|
|
3057
|
+
throw new Error("Failed to decrypt the function download url: the decrypted value is not a URL. Contact support@notte.cc if you need help.");
|
|
3058
|
+
}
|
|
3059
|
+
return decrypted;
|
|
3060
|
+
}
|
|
3061
|
+
/**
|
|
3062
|
+
* Download the function code as a python file. Returns the code, and writes
|
|
3063
|
+
* it to `path` when one is provided.
|
|
3064
|
+
*/
|
|
3065
|
+
async download(options = {}) {
|
|
3066
|
+
const { path } = options;
|
|
3067
|
+
if (path !== void 0 && !path.endsWith(".py")) {
|
|
3068
|
+
throw new Error(`Code file path must end with .py, got '${path}'`);
|
|
3069
|
+
}
|
|
3070
|
+
const url = await this.getUrl(options);
|
|
3071
|
+
let response;
|
|
3072
|
+
try {
|
|
3073
|
+
response = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
|
|
3074
|
+
} catch (error) {
|
|
3075
|
+
throw new Error(`Failed to download function code: ${error instanceof Error ? error.message : String(error)}`);
|
|
3076
|
+
}
|
|
3077
|
+
if (!response.ok) {
|
|
3078
|
+
throw new Error(`Failed to download function code: ${response.status} ${response.statusText}`);
|
|
3079
|
+
}
|
|
3080
|
+
const code = await response.text();
|
|
3081
|
+
if (path !== void 0) {
|
|
3082
|
+
await (0, import_promises.writeFile)(path, code, "utf8");
|
|
3083
|
+
}
|
|
3084
|
+
return code;
|
|
3085
|
+
}
|
|
2874
3086
|
/**
|
|
2875
3087
|
* Get the function ID
|
|
2876
3088
|
*/
|
|
@@ -2878,6 +3090,9 @@ var NotteFunction = class {
|
|
|
2878
3090
|
return this.functionId;
|
|
2879
3091
|
}
|
|
2880
3092
|
};
|
|
3093
|
+
function isHttpUrl(value) {
|
|
3094
|
+
return value.startsWith("https://") || value.startsWith("http://");
|
|
3095
|
+
}
|
|
2881
3096
|
|
|
2882
3097
|
// src/client.ts
|
|
2883
3098
|
var import_zod3 = require("zod");
|
|
@@ -3051,6 +3266,7 @@ var createClient2 = (config) => {
|
|
|
3051
3266
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3052
3267
|
0 && (module.exports = {
|
|
3053
3268
|
Agent,
|
|
3269
|
+
Encryption,
|
|
3054
3270
|
NotteClient,
|
|
3055
3271
|
NotteFunction,
|
|
3056
3272
|
NottePersona,
|
|
@@ -3074,6 +3290,7 @@ var createClient2 = (config) => {
|
|
|
3074
3290
|
functionDelete,
|
|
3075
3291
|
functionDownloadUrl,
|
|
3076
3292
|
functionFork,
|
|
3293
|
+
functionMetadataUpdate,
|
|
3077
3294
|
functionRunGetMetadata,
|
|
3078
3295
|
functionRunStart,
|
|
3079
3296
|
functionRunStop,
|
|
@@ -3095,6 +3312,12 @@ var createClient2 = (config) => {
|
|
|
3095
3312
|
listSecrets,
|
|
3096
3313
|
listSessions,
|
|
3097
3314
|
listVaults,
|
|
3315
|
+
mailboxConnectToken,
|
|
3316
|
+
mailboxDelete,
|
|
3317
|
+
mailboxGet,
|
|
3318
|
+
mailboxList,
|
|
3319
|
+
mailboxSync,
|
|
3320
|
+
mailboxUpdate,
|
|
3098
3321
|
nudgePrompt,
|
|
3099
3322
|
pageExecute,
|
|
3100
3323
|
pageObserve,
|
|
@@ -3105,6 +3328,7 @@ var createClient2 = (config) => {
|
|
|
3105
3328
|
personaEmailsList,
|
|
3106
3329
|
personaGet,
|
|
3107
3330
|
personaSmsList,
|
|
3331
|
+
personaUpdate,
|
|
3108
3332
|
profileCookiesGet,
|
|
3109
3333
|
profileCookiesSet,
|
|
3110
3334
|
profileCreate,
|