UNPKG

@langchain/langgraph

Version:

LangGraph

139 lines 5.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEFAULT_MAX_RETRIES = exports.DEFAULT_MAX_INTERVAL = exports.DEFAULT_BACKOFF_FACTOR = exports.DEFAULT_INITIAL_INTERVAL = void 0; exports._runWithRetry = _runWithRetry; const constants_js_1 = require("../constants.cjs"); const errors_js_1 = require("../errors.cjs"); const config_js_1 = require("./utils/config.cjs"); const index_js_1 = require("./utils/index.cjs"); exports.DEFAULT_INITIAL_INTERVAL = 500; exports.DEFAULT_BACKOFF_FACTOR = 2; exports.DEFAULT_MAX_INTERVAL = 128000; exports.DEFAULT_MAX_RETRIES = 3; const DEFAULT_STATUS_NO_RETRY = [ 400, // Bad Request 401, // Unauthorized 402, // Payment Required 403, // Forbidden 404, // Not Found 405, // Method Not Allowed 406, // Not Acceptable 407, // Proxy Authentication Required 409, // Conflict ]; // eslint-disable-next-line @typescript-eslint/no-explicit-any const DEFAULT_RETRY_ON_HANDLER = (error) => { if (error.message.startsWith("Cancel") || error.message.startsWith("AbortError") || error.name === "AbortError") { return false; } // eslint-disable-next-line @typescript-eslint/no-explicit-any if (error?.code === "ECONNABORTED") { return false; } const status = // eslint-disable-next-line @typescript-eslint/no-explicit-any error?.response?.status ?? error?.status; if (status && DEFAULT_STATUS_NO_RETRY.includes(+status)) { return false; } // eslint-disable-next-line @typescript-eslint/no-explicit-any if (error?.error?.code === "insufficient_quota") { return false; } return true; }; async function _runWithRetry( // eslint-disable-next-line @typescript-eslint/no-explicit-any pregelTask, retryPolicy, configurable, signal) { const resolvedRetryPolicy = pregelTask.retry_policy ?? retryPolicy; let interval = resolvedRetryPolicy !== undefined ? resolvedRetryPolicy.initialInterval ?? exports.DEFAULT_INITIAL_INTERVAL : 0; let attempts = 0; let error; let result; let { config } = pregelTask; if (configurable) config = (0, index_js_1.patchConfigurable)(config, configurable); config = { ...config, signal }; // eslint-disable-next-line no-constant-condition while (true) { if (signal?.aborted) { // no need to throw here - we'll throw from the runner, instead. // there's just no point in retrying if the user has requested an abort. break; } // Clear any writes from previous attempts pregelTask.writes.splice(0, pregelTask.writes.length); error = undefined; try { result = await pregelTask.proc.invoke(pregelTask.input, config); break; } catch (e) { error = e; error.pregelTaskId = pregelTask.id; if ((0, errors_js_1.isParentCommand)(error)) { const ns = config?.configurable?.checkpoint_ns; const cmd = error.command; if (cmd.graph === ns) { // this command is for the current graph, handle it for (const writer of pregelTask.writers) { await writer.invoke(cmd, config); } error = undefined; break; } else if (cmd.graph === constants_js_1.Command.PARENT) { // this command is for the parent graph, assign it to the parent const parentNs = (0, config_js_1.getParentCheckpointNamespace)(ns); error.command = new constants_js_1.Command({ ...error.command, graph: parentNs, }); } } if ((0, errors_js_1.isGraphBubbleUp)(error)) { break; } if (resolvedRetryPolicy === undefined) { break; } attempts += 1; // check if we should give up if (attempts >= (resolvedRetryPolicy.maxAttempts ?? exports.DEFAULT_MAX_RETRIES)) { break; } const retryOn = resolvedRetryPolicy.retryOn ?? DEFAULT_RETRY_ON_HANDLER; if (!retryOn(error)) { break; } interval = Math.min(resolvedRetryPolicy.maxInterval ?? exports.DEFAULT_MAX_INTERVAL, interval * (resolvedRetryPolicy.backoffFactor ?? exports.DEFAULT_BACKOFF_FACTOR)); const intervalWithJitter = resolvedRetryPolicy.jitter ? Math.floor(interval + Math.random() * 1000) : interval; // sleep before retrying // eslint-disable-next-line no-promise-executor-return await new Promise((resolve) => setTimeout(resolve, intervalWithJitter)); // log the retry const errorName = error.name ?? // eslint-disable-next-line @typescript-eslint/no-explicit-any error.constructor.unminifiable_name ?? error.constructor.name; if (resolvedRetryPolicy?.logWarning ?? true) { console.log(`Retrying task "${String(pregelTask.name)}" after ${interval.toFixed(2)}ms (attempt ${attempts}) after ${errorName}: ${error}`); } // signal subgraphs to resume (if available) config = (0, index_js_1.patchConfigurable)(config, { [constants_js_1.CONFIG_KEY_RESUMING]: true }); } } return { task: pregelTask, result, error: error, signalAborted: signal?.aborted, }; } //# sourceMappingURL=retry.js.map