notte-sdk 1.9.3 → 1.9.5
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 +3 -1
- package/dist/index.d.mts +278 -17
- package/dist/index.d.ts +278 -17
- package/dist/index.js +278 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +274 -52
- package/dist/index.mjs.map +1 -1
- package/dist/proxy/core.js +4 -0
- package/dist/proxy/core.js.map +1 -1
- package/dist/proxy/core.mjs +4 -0
- package/dist/proxy/core.mjs.map +1 -1
- package/dist/proxy/next.js +4 -0
- package/dist/proxy/next.js.map +1 -1
- package/dist/proxy/next.mjs +4 -0
- package/dist/proxy/next.mjs.map +1 -1
- package/package.json +13 -6
package/dist/index.js
CHANGED
|
@@ -92,6 +92,7 @@ __export(index_exports, {
|
|
|
92
92
|
deleteSecret: () => deleteSecret,
|
|
93
93
|
deleteSessionFile: () => deleteSessionFile,
|
|
94
94
|
disconnectPaymentWallet: () => disconnectPaymentWallet,
|
|
95
|
+
downloadRunPayload: () => downloadRunPayload,
|
|
95
96
|
downloadSessionFile: () => downloadSessionFile,
|
|
96
97
|
functionCreate: () => functionCreate,
|
|
97
98
|
functionDelete: () => functionDelete,
|
|
@@ -148,6 +149,7 @@ __export(index_exports, {
|
|
|
148
149
|
personaSmsList: () => personaSmsList,
|
|
149
150
|
personaUpdate: () => personaUpdate,
|
|
150
151
|
prepareAgentRequest: () => prepareAgentRequest,
|
|
152
|
+
prepareRunPayloadUpload: () => prepareRunPayloadUpload,
|
|
151
153
|
processScrapeResponse: () => processScrapeResponse,
|
|
152
154
|
profileCookiesGet: () => profileCookiesGet,
|
|
153
155
|
profileCookiesSet: () => profileCookiesSet,
|
|
@@ -195,7 +197,7 @@ __export(index_exports, {
|
|
|
195
197
|
module.exports = __toCommonJS(index_exports);
|
|
196
198
|
|
|
197
199
|
// src/version.ts
|
|
198
|
-
var SDK_VERSION = true ? "1.9.
|
|
200
|
+
var SDK_VERSION = true ? "1.9.5" : "dev";
|
|
199
201
|
var SDK_PACKAGE_NAME = true ? "notte-sdk" : "notte-sdk";
|
|
200
202
|
|
|
201
203
|
// src/version-check.ts
|
|
@@ -1392,6 +1394,20 @@ var functionRunUpdateMetadata = (options) => (options.client ?? client).patch({
|
|
|
1392
1394
|
...options.headers
|
|
1393
1395
|
}
|
|
1394
1396
|
});
|
|
1397
|
+
var prepareRunPayloadUpload = (options) => (options.client ?? client).post({
|
|
1398
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1399
|
+
url: "/functions/{function_id}/runs/{run_id}/payloads/{field}/upload",
|
|
1400
|
+
...options,
|
|
1401
|
+
headers: {
|
|
1402
|
+
"Content-Type": "application/json",
|
|
1403
|
+
...options.headers
|
|
1404
|
+
}
|
|
1405
|
+
});
|
|
1406
|
+
var downloadRunPayload = (options) => (options.client ?? client).get({
|
|
1407
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1408
|
+
url: "/functions/{function_id}/runs/{run_id}/payloads/{field}",
|
|
1409
|
+
...options
|
|
1410
|
+
});
|
|
1395
1411
|
var listFunctionRunsByFunctionId = (options) => (options.client ?? client).get({
|
|
1396
1412
|
security: [{ scheme: "bearer", type: "http" }],
|
|
1397
1413
|
url: "/functions/{function_id}/runs",
|
|
@@ -1669,6 +1685,7 @@ var connectLinkSubmit = (options) => (options.client ?? client).post({
|
|
|
1669
1685
|
});
|
|
1670
1686
|
var connectLinkStatus = (options) => (options.client ?? client).get({ url: "/managed-auth/connect-links/status", ...options });
|
|
1671
1687
|
var improvePrompt = (options) => (options.client ?? client).post({
|
|
1688
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1672
1689
|
url: "/prompts/improve",
|
|
1673
1690
|
...options,
|
|
1674
1691
|
headers: {
|
|
@@ -1677,6 +1694,7 @@ var improvePrompt = (options) => (options.client ?? client).post({
|
|
|
1677
1694
|
}
|
|
1678
1695
|
});
|
|
1679
1696
|
var nudgePrompt = (options) => (options.client ?? client).post({
|
|
1697
|
+
security: [{ scheme: "bearer", type: "http" }],
|
|
1680
1698
|
url: "/prompts/nudge",
|
|
1681
1699
|
...options,
|
|
1682
1700
|
headers: {
|
|
@@ -2079,8 +2097,8 @@ function createResources(client2, getApiKey) {
|
|
|
2079
2097
|
return response.data;
|
|
2080
2098
|
},
|
|
2081
2099
|
/** sessionOffset: /sessions/{session_id}/offset. Returns the API response body. */
|
|
2082
|
-
offset: async (sessionId, requestOptions = {}) => {
|
|
2083
|
-
const response = await sessionOffset({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId } });
|
|
2100
|
+
offset: async (sessionId, query = void 0, requestOptions = {}) => {
|
|
2101
|
+
const response = await sessionOffset({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
|
|
2084
2102
|
return response.data;
|
|
2085
2103
|
},
|
|
2086
2104
|
/** pageScreenshot: /sessions/{session_id}/page/screenshot. Returns the API response body. */
|
|
@@ -2172,6 +2190,11 @@ function createResources(client2, getApiKey) {
|
|
|
2172
2190
|
const response = await functionScheduleDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId } });
|
|
2173
2191
|
return response.data;
|
|
2174
2192
|
},
|
|
2193
|
+
/** downloadRunPayload: /functions/{function_id}/runs/{run_id}/payloads/{field}. Returns the API response body. */
|
|
2194
|
+
downloadRunPayload: async (functionId, runId, field, requestOptions = {}) => {
|
|
2195
|
+
const response = await downloadRunPayload({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId, "run_id": runId, "field": field } });
|
|
2196
|
+
return response.data;
|
|
2197
|
+
},
|
|
2175
2198
|
/** functionDownloadUrl: /functions/{function_id}. Returns the API response body. */
|
|
2176
2199
|
downloadUrl: async (functionId, query = void 0, requestOptions = {}) => {
|
|
2177
2200
|
const response = await functionDownloadUrl({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, query });
|
|
@@ -2197,14 +2220,19 @@ function createResources(client2, getApiKey) {
|
|
|
2197
2220
|
const response = await functionMetadataUpdate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, body });
|
|
2198
2221
|
return response.data;
|
|
2199
2222
|
},
|
|
2223
|
+
/** prepareRunPayloadUpload: /functions/{function_id}/runs/{run_id}/payloads/{field}/upload. Returns the API response body. */
|
|
2224
|
+
prepareRunPayloadUpload: async (functionId, runId, field, body, requestOptions = {}) => {
|
|
2225
|
+
const response = await prepareRunPayloadUpload({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId, "run_id": runId, "field": field }, body });
|
|
2226
|
+
return response.data;
|
|
2227
|
+
},
|
|
2200
2228
|
/** functionRollback: /functions/{function_id}/rollback. Returns the API response body. */
|
|
2201
2229
|
rollback: async (functionId, body, query = void 0, requestOptions = {}) => {
|
|
2202
2230
|
const response = await functionRollback({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, body, query });
|
|
2203
2231
|
return response.data;
|
|
2204
2232
|
},
|
|
2205
2233
|
/** functionRunGetMetadata: /functions/{function_id}/runs/{run_id}. Returns the API response body. */
|
|
2206
|
-
runGetMetadata: async (functionId, runId, requestOptions = {}) => {
|
|
2207
|
-
const response = await functionRunGetMetadata({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId, "run_id": runId } });
|
|
2234
|
+
runGetMetadata: async (functionId, runId, requestOptions = {}, query = void 0) => {
|
|
2235
|
+
const response = await functionRunGetMetadata({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId, "run_id": runId }, query });
|
|
2208
2236
|
return response.data;
|
|
2209
2237
|
},
|
|
2210
2238
|
/** functionRunStart: /functions/{function_id}/runs/start. Returns the API response body. */
|
|
@@ -2428,6 +2456,12 @@ async function executeWithCaptcha(action, budgetSeconds, request) {
|
|
|
2428
2456
|
if (status.state === "cancelled" && status.cancel_reason === "navigation" && original) {
|
|
2429
2457
|
return { ...original, captcha: status };
|
|
2430
2458
|
}
|
|
2459
|
+
if (status.state === "cancelled" && status.cancel_reason === "navigation" && action.type === "wait" && result.action_executed === false) {
|
|
2460
|
+
params = { captcha_timeout_seconds: remaining() };
|
|
2461
|
+
requestAction = action;
|
|
2462
|
+
await pause();
|
|
2463
|
+
continue;
|
|
2464
|
+
}
|
|
2431
2465
|
if (status.state === "failed" || status.state === "cancelled") {
|
|
2432
2466
|
return failure(status.message || `CAPTCHA ${status.state}`, `captcha_${status.state}`);
|
|
2433
2467
|
}
|
|
@@ -2753,6 +2787,126 @@ function isNotFound(error) {
|
|
|
2753
2787
|
return typeof error === "object" && error !== null && error.code === "ENOENT";
|
|
2754
2788
|
}
|
|
2755
2789
|
|
|
2790
|
+
// src/utils.ts
|
|
2791
|
+
var import_node_child_process = require("child_process");
|
|
2792
|
+
function formatError(error) {
|
|
2793
|
+
if (typeof error === "object" && error !== null) {
|
|
2794
|
+
if ("message" in error && typeof error.message === "string") {
|
|
2795
|
+
return error.message;
|
|
2796
|
+
}
|
|
2797
|
+
try {
|
|
2798
|
+
return JSON.stringify(error, null, 2);
|
|
2799
|
+
} catch {
|
|
2800
|
+
return String(error);
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
if (error instanceof Error) {
|
|
2804
|
+
return error.message;
|
|
2805
|
+
}
|
|
2806
|
+
return String(error);
|
|
2807
|
+
}
|
|
2808
|
+
function openBrowser(url) {
|
|
2809
|
+
const platform = process.platform;
|
|
2810
|
+
let command;
|
|
2811
|
+
let args;
|
|
2812
|
+
if (platform === "darwin") {
|
|
2813
|
+
command = "open";
|
|
2814
|
+
args = [url];
|
|
2815
|
+
} else if (platform === "win32") {
|
|
2816
|
+
command = "rundll32";
|
|
2817
|
+
args = ["url.dll,FileProtocolHandler", url];
|
|
2818
|
+
} else {
|
|
2819
|
+
command = "xdg-open";
|
|
2820
|
+
args = [url];
|
|
2821
|
+
}
|
|
2822
|
+
const child = (0, import_node_child_process.spawn)(command, args, {
|
|
2823
|
+
detached: true,
|
|
2824
|
+
stdio: "ignore"
|
|
2825
|
+
});
|
|
2826
|
+
child.on("error", () => {
|
|
2827
|
+
});
|
|
2828
|
+
child.unref();
|
|
2829
|
+
}
|
|
2830
|
+
var SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2831
|
+
"items",
|
|
2832
|
+
"additionalItems",
|
|
2833
|
+
"additionalProperties",
|
|
2834
|
+
"contains",
|
|
2835
|
+
"propertyNames",
|
|
2836
|
+
"not",
|
|
2837
|
+
"if",
|
|
2838
|
+
"then",
|
|
2839
|
+
"else",
|
|
2840
|
+
"unevaluatedItems",
|
|
2841
|
+
"unevaluatedProperties"
|
|
2842
|
+
]);
|
|
2843
|
+
var SCHEMA_ARRAY_KEYWORDS = /* @__PURE__ */ new Set(["anyOf", "oneOf", "allOf", "prefixItems"]);
|
|
2844
|
+
var TYPE_SCOPED_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2845
|
+
"items",
|
|
2846
|
+
"prefixItems",
|
|
2847
|
+
"additionalItems",
|
|
2848
|
+
"contains",
|
|
2849
|
+
"unevaluatedItems",
|
|
2850
|
+
"properties",
|
|
2851
|
+
"patternProperties",
|
|
2852
|
+
"required",
|
|
2853
|
+
"additionalProperties",
|
|
2854
|
+
"propertyNames",
|
|
2855
|
+
"unevaluatedProperties",
|
|
2856
|
+
"format"
|
|
2857
|
+
]);
|
|
2858
|
+
var SCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set(["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"]);
|
|
2859
|
+
function normalizeJsonSchema(schema) {
|
|
2860
|
+
if (schema === null || typeof schema !== "object" || Array.isArray(schema)) return schema;
|
|
2861
|
+
const out = {};
|
|
2862
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
2863
|
+
if (SCHEMA_KEYWORDS.has(key) || key === "items" && Array.isArray(value)) {
|
|
2864
|
+
out[key] = Array.isArray(value) ? value.map(normalizeJsonSchema) : normalizeJsonSchema(value);
|
|
2865
|
+
} else if (SCHEMA_ARRAY_KEYWORDS.has(key) && Array.isArray(value)) {
|
|
2866
|
+
out[key] = value.map(normalizeJsonSchema);
|
|
2867
|
+
} else if (SCHEMA_MAP_KEYWORDS.has(key) && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
2868
|
+
out[key] = Object.fromEntries(
|
|
2869
|
+
Object.entries(value).map(([name, sub]) => [name, normalizeJsonSchema(sub)])
|
|
2870
|
+
);
|
|
2871
|
+
} else {
|
|
2872
|
+
out[key] = value;
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
if (Array.isArray(out.type)) {
|
|
2876
|
+
const { type, anyOf: existing, ...rest } = out;
|
|
2877
|
+
const types = type;
|
|
2878
|
+
const parent = {};
|
|
2879
|
+
const scoped = {};
|
|
2880
|
+
for (const [key, value] of Object.entries(rest)) {
|
|
2881
|
+
(TYPE_SCOPED_KEYWORDS.has(key) ? scoped : parent)[key] = value;
|
|
2882
|
+
}
|
|
2883
|
+
const typed = (t) => t === "null" ? { type: t } : { type: t, ...scoped };
|
|
2884
|
+
let branches;
|
|
2885
|
+
if (Array.isArray(existing)) {
|
|
2886
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2887
|
+
branches = [];
|
|
2888
|
+
const push = (b) => {
|
|
2889
|
+
const key = JSON.stringify(b);
|
|
2890
|
+
if (!seen.has(key)) {
|
|
2891
|
+
seen.add(key);
|
|
2892
|
+
branches.push(b);
|
|
2893
|
+
}
|
|
2894
|
+
};
|
|
2895
|
+
for (const branch of existing) {
|
|
2896
|
+
if (typeof branch.type === "string") {
|
|
2897
|
+
if (types.includes(branch.type)) push(branch.type === "null" ? branch : { ...scoped, ...branch });
|
|
2898
|
+
} else {
|
|
2899
|
+
for (const t of types) push({ ...typed(t), ...branch });
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
} else {
|
|
2903
|
+
branches = types.map(typed);
|
|
2904
|
+
}
|
|
2905
|
+
return { ...parent, anyOf: branches };
|
|
2906
|
+
}
|
|
2907
|
+
return out;
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2756
2910
|
// src/scrape.ts
|
|
2757
2911
|
function isZodSchema(value) {
|
|
2758
2912
|
return typeof value === "object" && value !== null && typeof value.parse === "function";
|
|
@@ -2768,7 +2922,7 @@ async function buildScrapeBody(options) {
|
|
|
2768
2922
|
body.response_format = json_schema;
|
|
2769
2923
|
} else {
|
|
2770
2924
|
const { z: z2 } = await import("zod");
|
|
2771
|
-
body.response_format = z2.toJSONSchema(response_format);
|
|
2925
|
+
body.response_format = normalizeJsonSchema(z2.toJSONSchema(response_format));
|
|
2772
2926
|
}
|
|
2773
2927
|
} else if (response_format) {
|
|
2774
2928
|
body.response_format = response_format;
|
|
@@ -2805,47 +2959,6 @@ function processScrapeResponse(scrapeResponse, options) {
|
|
|
2805
2959
|
return scrapeResponse.markdown;
|
|
2806
2960
|
}
|
|
2807
2961
|
|
|
2808
|
-
// src/utils.ts
|
|
2809
|
-
var import_node_child_process = require("child_process");
|
|
2810
|
-
function formatError(error) {
|
|
2811
|
-
if (typeof error === "object" && error !== null) {
|
|
2812
|
-
if ("message" in error && typeof error.message === "string") {
|
|
2813
|
-
return error.message;
|
|
2814
|
-
}
|
|
2815
|
-
try {
|
|
2816
|
-
return JSON.stringify(error, null, 2);
|
|
2817
|
-
} catch {
|
|
2818
|
-
return String(error);
|
|
2819
|
-
}
|
|
2820
|
-
}
|
|
2821
|
-
if (error instanceof Error) {
|
|
2822
|
-
return error.message;
|
|
2823
|
-
}
|
|
2824
|
-
return String(error);
|
|
2825
|
-
}
|
|
2826
|
-
function openBrowser(url) {
|
|
2827
|
-
const platform = process.platform;
|
|
2828
|
-
let command;
|
|
2829
|
-
let args;
|
|
2830
|
-
if (platform === "darwin") {
|
|
2831
|
-
command = "open";
|
|
2832
|
-
args = [url];
|
|
2833
|
-
} else if (platform === "win32") {
|
|
2834
|
-
command = "rundll32";
|
|
2835
|
-
args = ["url.dll,FileProtocolHandler", url];
|
|
2836
|
-
} else {
|
|
2837
|
-
command = "xdg-open";
|
|
2838
|
-
args = [url];
|
|
2839
|
-
}
|
|
2840
|
-
const child = (0, import_node_child_process.spawn)(command, args, {
|
|
2841
|
-
detached: true,
|
|
2842
|
-
stdio: "ignore"
|
|
2843
|
-
});
|
|
2844
|
-
child.on("error", () => {
|
|
2845
|
-
});
|
|
2846
|
-
child.unref();
|
|
2847
|
-
}
|
|
2848
|
-
|
|
2849
2962
|
// src/session.ts
|
|
2850
2963
|
var SESSION_START_TRIES = 3;
|
|
2851
2964
|
var CLUSTER_OVERLOAD_RETRY_DELAY_MS = 3e4;
|
|
@@ -3595,7 +3708,7 @@ function prepareAgentRequest(data) {
|
|
|
3595
3708
|
const apiData = { ...data };
|
|
3596
3709
|
const rf = data.response_format;
|
|
3597
3710
|
if (rf && typeof rf.parse === "function" && typeof rf.safeParse === "function") {
|
|
3598
|
-
apiData.response_format = import_zod.z.toJSONSchema(rf);
|
|
3711
|
+
apiData.response_format = normalizeJsonSchema(import_zod.z.toJSONSchema(rf));
|
|
3599
3712
|
return { apiData, zodSchema: rf };
|
|
3600
3713
|
}
|
|
3601
3714
|
return { apiData, zodSchema: null };
|
|
@@ -4641,6 +4754,90 @@ function decryptFernet(token, key) {
|
|
|
4641
4754
|
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
4642
4755
|
}
|
|
4643
4756
|
|
|
4757
|
+
// src/run-payloads.ts
|
|
4758
|
+
var import_node_crypto2 = require("crypto");
|
|
4759
|
+
var INLINE_FIELD_BYTES = 1024 * 1024;
|
|
4760
|
+
var MAX_PAYLOAD_BYTES = 256 * 1024 * 1024;
|
|
4761
|
+
async function offloadRunPayloads(client2, path, fields) {
|
|
4762
|
+
const data = { ...fields };
|
|
4763
|
+
const references = {};
|
|
4764
|
+
if (data.result != null && typeof data.result !== "string") data.result = JSON.stringify(data.result);
|
|
4765
|
+
for (const field of ["result", "logs", "variables"]) {
|
|
4766
|
+
if (data[field] == null) continue;
|
|
4767
|
+
const payload = Buffer.from(JSON.stringify(data[field]), "utf8");
|
|
4768
|
+
if (payload.length > MAX_PAYLOAD_BYTES) throw new Error(`Function run ${field} exceeds the payload limit`);
|
|
4769
|
+
if (payload.length <= INLINE_FIELD_BYTES) continue;
|
|
4770
|
+
const checksum = (0, import_node_crypto2.createHash)("sha256").update(payload).digest("base64");
|
|
4771
|
+
const prepared = await client2.post({
|
|
4772
|
+
url: "/functions/{function_id}/runs/{run_id}/payloads/{field}/upload",
|
|
4773
|
+
path: { ...path, field },
|
|
4774
|
+
body: { size_bytes: payload.length, sha256: checksum },
|
|
4775
|
+
headers: { "Content-Type": "application/json" },
|
|
4776
|
+
throwOnError: true
|
|
4777
|
+
});
|
|
4778
|
+
const upload = prepared.data;
|
|
4779
|
+
if (upload.reference.size_bytes !== payload.length || upload.reference.sha256 !== checksum) {
|
|
4780
|
+
throw new Error("Run payload upload reference does not match the local payload");
|
|
4781
|
+
}
|
|
4782
|
+
if (new URL(upload.url).protocol !== "https:") throw new Error("Invalid run payload URL");
|
|
4783
|
+
const response = await fetch(upload.url, {
|
|
4784
|
+
method: "PUT",
|
|
4785
|
+
body: payload,
|
|
4786
|
+
headers: upload.headers,
|
|
4787
|
+
redirect: "error",
|
|
4788
|
+
signal: AbortSignal.timeout(3e5)
|
|
4789
|
+
});
|
|
4790
|
+
await response.body?.cancel();
|
|
4791
|
+
if (!response.ok) throw new Error(`Run payload upload failed (${response.status})`);
|
|
4792
|
+
references[field] = upload.reference;
|
|
4793
|
+
if (field === "result" && typeof data.result === "string") data.result_preview = data.result.slice(0, 16e3);
|
|
4794
|
+
delete data[field];
|
|
4795
|
+
}
|
|
4796
|
+
if (Object.keys(references).length) data.payloads = references;
|
|
4797
|
+
return data;
|
|
4798
|
+
}
|
|
4799
|
+
async function resolveRunPayloads(input) {
|
|
4800
|
+
const run = { ...input };
|
|
4801
|
+
for (const [field, reference] of Object.entries(run.payloads ?? {})) {
|
|
4802
|
+
if (!["result", "logs", "variables"].includes(field)) throw new Error("Unknown run payload field");
|
|
4803
|
+
if (!Number.isSafeInteger(reference.size_bytes) || reference.size_bytes <= 0 || reference.size_bytes > 256 * 1024 * 1024) {
|
|
4804
|
+
throw new Error("Invalid run payload size");
|
|
4805
|
+
}
|
|
4806
|
+
const url = run.payload_urls?.[field];
|
|
4807
|
+
if (!url || new URL(url).protocol !== "https:") throw new Error("Invalid run payload URL");
|
|
4808
|
+
const response = await fetch(url, { redirect: "error", signal: AbortSignal.timeout(3e5) });
|
|
4809
|
+
if (!response.ok || !response.body) throw new Error(`Run payload download failed (${response.status})`);
|
|
4810
|
+
const reader = response.body.getReader();
|
|
4811
|
+
const chunks = [];
|
|
4812
|
+
const hash = (0, import_node_crypto2.createHash)("sha256");
|
|
4813
|
+
let size = 0;
|
|
4814
|
+
try {
|
|
4815
|
+
while (true) {
|
|
4816
|
+
const { done, value: value2 } = await reader.read();
|
|
4817
|
+
if (done) break;
|
|
4818
|
+
size += value2.length;
|
|
4819
|
+
if (size > reference.size_bytes) throw new Error("Run payload exceeds its declared size");
|
|
4820
|
+
hash.update(value2);
|
|
4821
|
+
chunks.push(value2);
|
|
4822
|
+
}
|
|
4823
|
+
} finally {
|
|
4824
|
+
await reader.cancel();
|
|
4825
|
+
reader.releaseLock();
|
|
4826
|
+
}
|
|
4827
|
+
if (size !== reference.size_bytes || hash.digest("base64") !== reference.sha256) {
|
|
4828
|
+
throw new Error("Run payload failed size/checksum verification");
|
|
4829
|
+
}
|
|
4830
|
+
const value = JSON.parse(Buffer.concat(chunks, size).toString("utf8"));
|
|
4831
|
+
if (field === "result" && value !== null && typeof value !== "string") throw new Error("Invalid stored result");
|
|
4832
|
+
if (field === "logs" && (!Array.isArray(value) || !value.every((line) => typeof line === "string"))) throw new Error("Invalid stored logs");
|
|
4833
|
+
if (field === "variables" && value !== null && (typeof value !== "object" || Array.isArray(value))) throw new Error("Invalid stored variables");
|
|
4834
|
+
Object.assign(run, { [field]: value });
|
|
4835
|
+
}
|
|
4836
|
+
delete run.payloads;
|
|
4837
|
+
delete run.payload_urls;
|
|
4838
|
+
return run;
|
|
4839
|
+
}
|
|
4840
|
+
|
|
4644
4841
|
// src/functions.ts
|
|
4645
4842
|
var DOWNLOAD_TIMEOUT_MS = 3e4;
|
|
4646
4843
|
var FUNCTION_RUN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
@@ -4868,10 +5065,35 @@ var NotteFunction = class {
|
|
|
4868
5065
|
*/
|
|
4869
5066
|
async getRun(functionRunId) {
|
|
4870
5067
|
const functionId = await this.ensureInitialized();
|
|
4871
|
-
const response = await
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
5068
|
+
const response = await this.client.getClient().get({
|
|
5069
|
+
url: "/functions/{function_id}/runs/{run_id}",
|
|
5070
|
+
path: { function_id: functionId, run_id: functionRunId },
|
|
5071
|
+
query: { payload_mode: "references" },
|
|
5072
|
+
throwOnError: true
|
|
5073
|
+
});
|
|
5074
|
+
return resolveRunPayloads(response.data);
|
|
5075
|
+
}
|
|
5076
|
+
/**
|
|
5077
|
+
* Update a run, uploading fields above 1 MiB directly to private storage.
|
|
5078
|
+
*
|
|
5079
|
+
* @param functionRunId - ID of a run belonging to this function.
|
|
5080
|
+
* @param fields - Status and fields to update. Omitted fields remain unchanged.
|
|
5081
|
+
* @returns Confirmation of the persisted update.
|
|
5082
|
+
* @throws Error if a field exceeds 256 MiB or an upload fails; the update is not finalized.
|
|
5083
|
+
* @example
|
|
5084
|
+
* await fn.updateRun(runId, { status: 'closed', result: { records } });
|
|
5085
|
+
*/
|
|
5086
|
+
async updateRun(functionRunId, fields) {
|
|
5087
|
+
const functionId = await this.ensureInitialized();
|
|
5088
|
+
const client2 = this.client.getClient();
|
|
5089
|
+
const path = { function_id: functionId, run_id: functionRunId };
|
|
5090
|
+
const body = await offloadRunPayloads(client2, path, fields);
|
|
5091
|
+
const response = await client2.patch({
|
|
5092
|
+
url: "/functions/{function_id}/runs/{run_id}",
|
|
5093
|
+
path,
|
|
5094
|
+
body,
|
|
5095
|
+
headers: { "Content-Type": "application/json" },
|
|
5096
|
+
throwOnError: true
|
|
4875
5097
|
});
|
|
4876
5098
|
return response.data;
|
|
4877
5099
|
}
|
|
@@ -5228,7 +5450,7 @@ async function readFunctionStream(body, onLog, path, signal) {
|
|
|
5228
5450
|
var import_node_fs2 = require("fs");
|
|
5229
5451
|
var import_promises6 = require("fs/promises");
|
|
5230
5452
|
var import_node_path4 = require("path");
|
|
5231
|
-
var
|
|
5453
|
+
var import_node_crypto3 = require("crypto");
|
|
5232
5454
|
var import_node_stream = require("stream");
|
|
5233
5455
|
var import_promises7 = require("stream/promises");
|
|
5234
5456
|
var FileNotFoundError = class extends NotteError {
|
|
@@ -5495,7 +5717,7 @@ var RemoteFileStorage = class _RemoteFileStorage {
|
|
|
5495
5717
|
}
|
|
5496
5718
|
}
|
|
5497
5719
|
const body = await files.stream(fileId);
|
|
5498
|
-
const temporary = (0, import_node_path4.join)(localDir, `.${safeName}.${(0,
|
|
5720
|
+
const temporary = (0, import_node_path4.join)(localDir, `.${safeName}.${(0, import_node_crypto3.randomBytes)(8).toString("hex")}.part`);
|
|
5499
5721
|
try {
|
|
5500
5722
|
await (0, import_promises7.pipeline)(
|
|
5501
5723
|
import_node_stream.Readable.fromWeb(body),
|
|
@@ -6274,6 +6496,7 @@ var createClient2 = (config) => {
|
|
|
6274
6496
|
deleteSecret,
|
|
6275
6497
|
deleteSessionFile,
|
|
6276
6498
|
disconnectPaymentWallet,
|
|
6499
|
+
downloadRunPayload,
|
|
6277
6500
|
downloadSessionFile,
|
|
6278
6501
|
functionCreate,
|
|
6279
6502
|
functionDelete,
|
|
@@ -6330,6 +6553,7 @@ var createClient2 = (config) => {
|
|
|
6330
6553
|
personaSmsList,
|
|
6331
6554
|
personaUpdate,
|
|
6332
6555
|
prepareAgentRequest,
|
|
6556
|
+
prepareRunPayloadUpload,
|
|
6333
6557
|
processScrapeResponse,
|
|
6334
6558
|
profileCookiesGet,
|
|
6335
6559
|
profileCookiesSet,
|