{"version":3,"file":"runner.cjs","names":["isGraphInterrupt","isGraphBubbleUp","combineAbortSignals","patchConfigurable","CONFIG_KEY_ABORT_SIGNALS","_runWithRetry","CONFIG_KEY_CALL","INTERRUPT","RESUME","ERROR","NO_WRITES","CONFIG_KEY_SCRATCHPAD","Call","RETURN"],"sources":["../../src/pregel/runner.ts"],"sourcesContent":["import { PendingWrite } from \"@langchain/langgraph-checkpoint\";\nimport {\n  Call,\n  PregelAbortSignals,\n  PregelExecutableTask,\n  PregelScratchpad,\n} from \"./types.js\";\nimport {\n  CachePolicy,\n  combineAbortSignals,\n  patchConfigurable,\n  RetryPolicy,\n} from \"./utils/index.js\";\nimport {\n  CONFIG_KEY_SCRATCHPAD,\n  ERROR,\n  INTERRUPT,\n  RESUME,\n  NO_WRITES,\n  TAG_HIDDEN,\n  RETURN,\n  CONFIG_KEY_CALL,\n  CONFIG_KEY_ABORT_SIGNALS,\n} from \"../constants.js\";\nimport { GraphBubbleUp, isGraphBubbleUp, isGraphInterrupt } from \"../errors.js\";\nimport { _runWithRetry, SettledPregelTask } from \"./retry.js\";\nimport { PregelLoop } from \"./loop.js\";\n\nconst PROMISE_ADDED_SYMBOL = Symbol.for(\"promiseAdded\");\n\nfunction createPromiseBarrier() {\n  const barrier: {\n    next: () => void;\n    wait: Promise<unknown>;\n  } = {\n    next: () => void 0,\n    wait: Promise.resolve(PROMISE_ADDED_SYMBOL),\n  };\n\n  function waitHandler(resolve: (value: typeof PROMISE_ADDED_SYMBOL) => void) {\n    barrier.next = () => {\n      barrier.wait = new Promise(waitHandler);\n      resolve(PROMISE_ADDED_SYMBOL);\n    };\n  }\n  barrier.wait = new Promise(waitHandler);\n  return barrier;\n}\n\n/**\n * Options for the {@link PregelRunner#tick} method.\n */\nexport type TickOptions = {\n  /**\n   * The deadline before which all tasks must be completed.\n   */\n  timeout?: number;\n\n  /**\n   * An optional {@link AbortSignal} to cancel processing of tasks.\n   */\n  signal?: AbortSignal;\n\n  /**\n   * The {@link RetryPolicy} to use for the tick.\n   */\n  retryPolicy?: RetryPolicy;\n\n  /**\n   * An optional callback to be called after all task writes are completed.\n   */\n  onStepWrite?: (step: number, writes: PendingWrite[]) => void;\n\n  /**\n   * The maximum number of tasks to execute concurrently.\n   */\n  maxConcurrency?: number;\n};\n\n/**\n * Responsible for handling task execution on each tick of the {@link PregelLoop}.\n */\nexport class PregelRunner {\n  private nodeFinished?: (id: string) => void;\n\n  private loop: PregelLoop;\n\n  /**\n   * Construct a new PregelRunner, which executes tasks from the provided PregelLoop.\n   * @param loop - The PregelLoop that produces tasks for this runner to execute.\n   */\n  constructor({\n    loop,\n    nodeFinished,\n  }: {\n    loop: PregelLoop;\n    nodeFinished?: (id: string) => void;\n  }) {\n    this.loop = loop;\n    this.nodeFinished = nodeFinished;\n  }\n\n  /**\n   * Execute tasks from the current step of the PregelLoop.\n   *\n   * Note: this method does NOT call {@link PregelLoop}#tick. That must be handled externally.\n   * @param options - Options for the execution.\n   */\n  async tick(options: TickOptions = {}) {\n    const { timeout, retryPolicy, onStepWrite, maxConcurrency } = options;\n\n    const nodeErrors: Set<Error> = new Set();\n    let graphBubbleUp: GraphBubbleUp | undefined;\n\n    const exceptionSignalController = new AbortController();\n    const exceptionSignal = exceptionSignalController.signal;\n    const stepTimeoutSignal = timeout\n      ? AbortSignal.timeout(timeout)\n      : undefined;\n\n    // Start task execution\n    const pendingTasks = Object.values(this.loop.tasks).filter(\n      (t) => t.writes.length === 0\n    );\n\n    const { signals, disposeCombinedSignal } = this._initializeAbortSignals({\n      exceptionSignal,\n      stepTimeoutSignal,\n      signal: options.signal,\n    });\n\n    const taskStream = this._executeTasksWithRetry(pendingTasks, {\n      signals,\n      retryPolicy,\n      maxConcurrency,\n    });\n\n    for await (const { task, error, signalAborted } of taskStream) {\n      this._commit(task, error);\n      if (isGraphInterrupt(error)) {\n        graphBubbleUp = error;\n      } else if (isGraphBubbleUp(error) && !isGraphInterrupt(graphBubbleUp)) {\n        graphBubbleUp = error;\n      } else if (error && (nodeErrors.size === 0 || !signalAborted)) {\n        /*\n         * The goal here is to capture the exception that causes the graph to terminate early. In\n         * theory it's possible for multiple nodes to throw, so this also handles the edge case of\n         * capturing concurrent exceptions thrown before the node saw an abort. This is checked via\n         * the signalAborted flag, which records the state of the abort signal at the time the node\n         * execution finished.\n         *\n         * There is a case however where one node throws some error causing us to trigger an abort,\n         * which then causes other concurrently executing nodes to throw their own AbortErrors. In\n         * this case we don't care about reporting the abort errors thrown by the other nodes,\n         * because they don't tell the user anything about what caused the graph execution to\n         * terminate early, so we ignore them (and any other errors that occur after the node sees\n         * an abort signal).\n         */\n        exceptionSignalController.abort();\n        nodeErrors.add(error);\n      }\n    }\n\n    disposeCombinedSignal?.();\n\n    onStepWrite?.(\n      this.loop.step,\n      Object.values(this.loop.tasks)\n        .map((task) => task.writes)\n        .flat()\n    );\n\n    if (nodeErrors.size === 1) {\n      throw Array.from(nodeErrors)[0];\n    } else if (nodeErrors.size > 1) {\n      throw new AggregateError(\n        Array.from(nodeErrors),\n        `Multiple errors occurred during superstep ${this.loop.step}. See the \"errors\" field of this exception for more details.`\n      );\n    }\n\n    if (isGraphInterrupt(graphBubbleUp)) {\n      throw graphBubbleUp;\n    }\n\n    if (isGraphBubbleUp(graphBubbleUp) && this.loop.isNested) {\n      throw graphBubbleUp;\n    }\n  }\n\n  /**\n   * Initializes the current AbortSignals for the PregelRunner, handling the various ways that\n   * AbortSignals must be chained together so that the PregelLoop can be interrupted if necessary\n   * while still allowing nodes to gracefully exit.\n   *\n   * This method must only be called once per PregelRunner#tick. It has the side effect of updating\n   * the PregelLoop#config with the new AbortSignals so they may be propagated correctly to future\n   * ticks and subgraph calls.\n   *\n   * @param options - Options for the initialization.\n   * @returns The current abort signals.\n   * @internal\n   */\n  private _initializeAbortSignals({\n    exceptionSignal,\n    stepTimeoutSignal,\n    signal,\n  }: {\n    exceptionSignal: AbortSignal;\n    stepTimeoutSignal?: AbortSignal;\n    signal?: AbortSignal;\n  }): { signals: PregelAbortSignals; disposeCombinedSignal?: () => void } {\n    const previousSignals = (this.loop.config.configurable?.[\n      CONFIG_KEY_ABORT_SIGNALS\n    ] ?? {}) as PregelAbortSignals;\n\n    // We always inherit the external abort signal from AsyncLocalStorage,\n    // since that's the only way the signal is inherited by the subgraph calls.\n    const externalAbortSignal = previousSignals.externalAbortSignal ?? signal;\n\n    // inherit the step timeout signal from parent graph\n    const timeoutAbortSignal =\n      stepTimeoutSignal ?? previousSignals.timeoutAbortSignal;\n\n    const { signal: composedAbortSignal, dispose: disposeCombinedSignal } =\n      combineAbortSignals(\n        externalAbortSignal,\n        timeoutAbortSignal,\n        exceptionSignal\n      );\n\n    const signals: PregelAbortSignals = {\n      externalAbortSignal,\n      timeoutAbortSignal,\n      composedAbortSignal,\n    };\n\n    this.loop.config = patchConfigurable(this.loop.config, {\n      [CONFIG_KEY_ABORT_SIGNALS]: signals,\n    });\n\n    return { signals, disposeCombinedSignal };\n  }\n\n  /**\n   * Concurrently executes tasks with the requested retry policy, yielding a {@link SettledPregelTask} for each task as it completes.\n   * @param tasks - The tasks to execute.\n   * @param options - Options for the execution.\n   */\n  private async *_executeTasksWithRetry(\n    tasks: PregelExecutableTask<string, string>[],\n    options?: {\n      signals?: PregelAbortSignals;\n      retryPolicy?: RetryPolicy;\n      maxConcurrency?: number;\n    }\n  ): AsyncGenerator<SettledPregelTask> {\n    const { retryPolicy, maxConcurrency, signals } = options ?? {};\n\n    const barrier = createPromiseBarrier();\n    const executingTasksMap: Record<\n      string,\n      Promise<{\n        task: PregelExecutableTask<string, string>;\n        result?: unknown;\n        error?: Error;\n      }>\n    > = {};\n\n    const thisCall = {\n      executingTasksMap,\n      barrier,\n      retryPolicy,\n      scheduleTask: async (\n        task: PregelExecutableTask<string, string>,\n        writeIdx: number,\n        call?: Call\n      ) => this.loop.acceptPush(task, writeIdx, call),\n    };\n\n    if (signals?.composedAbortSignal?.aborted) {\n      // note: don't use throwIfAborted here because it throws a DOMException,\n      // which isn't consistent with how we throw on abort below.\n      throw new Error(\"Abort\");\n    }\n\n    let startedTasksCount = 0;\n\n    let listener: (() => void) | undefined;\n    const timeoutOrCancelSignal = combineAbortSignals(\n      signals?.externalAbortSignal,\n      signals?.timeoutAbortSignal\n    );\n\n    const abortPromise = timeoutOrCancelSignal.signal\n      ? new Promise<never>((_resolve, reject) => {\n          listener = () => reject(new Error(\"Abort\"));\n          timeoutOrCancelSignal.signal?.addEventListener(\"abort\", listener, {\n            once: true,\n          });\n        })\n      : undefined;\n\n    while (\n      (startedTasksCount === 0 || Object.keys(executingTasksMap).length > 0) &&\n      tasks.length\n    ) {\n      for (\n        ;\n        Object.values(executingTasksMap).length <\n          (maxConcurrency ?? tasks.length) && startedTasksCount < tasks.length;\n        startedTasksCount += 1\n      ) {\n        const task = tasks[startedTasksCount];\n\n        executingTasksMap[task.id] = _runWithRetry(\n          task,\n          retryPolicy,\n          { [CONFIG_KEY_CALL]: call?.bind(thisCall, this, task) },\n          signals?.composedAbortSignal\n        ).catch((error) => {\n          return {\n            task,\n            error,\n            signalAborted: signals?.composedAbortSignal?.aborted,\n          };\n        });\n      }\n\n      const settledTask = await Promise.race([\n        ...Object.values(executingTasksMap),\n        ...(abortPromise ? [abortPromise] : []),\n        barrier.wait,\n      ]);\n\n      if (settledTask === PROMISE_ADDED_SYMBOL) {\n        continue;\n      }\n\n      yield settledTask as SettledPregelTask;\n\n      if (listener != null) {\n        timeoutOrCancelSignal.signal?.removeEventListener(\"abort\", listener);\n        timeoutOrCancelSignal.dispose?.();\n      }\n\n      delete executingTasksMap[(settledTask as SettledPregelTask).task.id];\n    }\n  }\n\n  /**\n   * Determines what writes to apply based on whether the task completed successfully, and what type of error occurred.\n   *\n   * Throws an error if the error is a {@link GraphBubbleUp} error and {@link PregelLoop}#isNested is true.\n   *\n   * @param task - The task to commit.\n   * @param error - The error that occurred, if any.\n   */\n  private _commit(task: PregelExecutableTask<string, string>, error?: Error) {\n    if (error !== undefined) {\n      if (isGraphInterrupt(error)) {\n        if (error.interrupts.length) {\n          const interrupts: PendingWrite<string>[] = error.interrupts.map(\n            (interrupt) => [INTERRUPT, interrupt]\n          );\n          const resumes = task.writes.filter((w) => w[0] === RESUME);\n          if (resumes.length) {\n            interrupts.push(...resumes);\n          }\n          this.loop.putWrites(task.id, interrupts);\n        }\n      } else if (isGraphBubbleUp(error) && task.writes.length) {\n        this.loop.putWrites(task.id, task.writes);\n      } else {\n        this.loop.putWrites(task.id, [\n          [ERROR, { message: error.message, name: error.name }],\n        ]);\n      }\n    } else {\n      if (\n        this.nodeFinished &&\n        (task.config?.tags == null || !task.config.tags.includes(TAG_HIDDEN))\n      ) {\n        this.nodeFinished(String(task.name));\n      }\n\n      if (task.writes.length === 0) {\n        // Add no writes marker\n        task.writes.push([NO_WRITES, null]);\n      }\n\n      // Save task writes to checkpointer\n      this.loop.putWrites(task.id, task.writes);\n    }\n  }\n}\n\nasync function call(\n  this: {\n    executingTasksMap: Record<\n      string,\n      Promise<{\n        task: PregelExecutableTask<string, string>;\n        result?: unknown;\n        error?: Error;\n      }>\n    >;\n\n    barrier: {\n      next: () => void;\n      wait: Promise<unknown>;\n    };\n\n    retryPolicy?: RetryPolicy;\n\n    scheduleTask: (\n      task: PregelExecutableTask<string, string>,\n      writeIdx: number,\n      call?: Call\n    ) => Promise<PregelExecutableTask<string, string> | void>;\n  },\n  runner: PregelRunner,\n  task: PregelExecutableTask<string, string>,\n  func: (...args: unknown[]) => unknown | Promise<unknown>,\n  name: string,\n  input: unknown,\n  options: {\n    retry?: RetryPolicy;\n    cache?: CachePolicy;\n    callbacks?: unknown;\n  } = {}\n): Promise<unknown> {\n  // Schedule PUSH tasks, collect promises\n  const scratchpad = task.config?.configurable?.[CONFIG_KEY_SCRATCHPAD] as\n    | PregelScratchpad<unknown>\n    | undefined;\n\n  if (!scratchpad) {\n    throw new Error(\n      `BUG: No scratchpad found on task ${task.name}__${task.id}`\n    );\n  }\n\n  const cnt = scratchpad.callCounter;\n  scratchpad.callCounter += 1;\n\n  // schedule the next task, if the callback returns one\n  const wcall = new Call({\n    func,\n    name,\n    input,\n    cache: options.cache,\n    retry: options.retry,\n    callbacks: options.callbacks,\n  });\n  const nextTask = await this.scheduleTask(task, cnt, wcall);\n  if (!nextTask) return undefined;\n\n  // Check if this task is already running\n  const existingPromise = this.executingTasksMap[nextTask.id];\n\n  if (existingPromise !== undefined) {\n    // If the parent task was retried, the next task might already be running\n    return existingPromise;\n  }\n\n  if (nextTask.writes.length > 0) {\n    // If it already ran, return the result\n    const returns = nextTask.writes.filter(([c]) => c === RETURN);\n    const errors = nextTask.writes.filter(([c]) => c === ERROR);\n\n    if (returns.length > 0) {\n      // Task completed successfully\n      if (returns.length === 1) return Promise.resolve(returns[0][1]);\n\n      // should be unreachable\n      throw new Error(\n        `BUG: multiple returns found for task ${nextTask.name}__${nextTask.id}`\n      );\n    }\n\n    if (errors.length > 0) {\n      // Task failed\n      if (errors.length === 1) {\n        const errorValue = errors[0][1];\n        const error =\n          // eslint-disable-next-line no-instanceof/no-instanceof\n          errorValue instanceof Error\n            ? errorValue\n            : new Error(String(errorValue));\n\n        return Promise.reject(error);\n      }\n\n      // the only way this should happen is if the task executes multiple times and writes aren't cleared\n      throw new Error(\n        `BUG: multiple errors found for task ${nextTask.name}__${nextTask.id}`\n      );\n    }\n\n    return undefined;\n  } else {\n    // Schedule the next task with retry\n    const prom = _runWithRetry<string, string>(nextTask, options.retry, {\n      [CONFIG_KEY_CALL]: call.bind(this, runner, nextTask),\n    });\n\n    this.executingTasksMap[nextTask.id] = prom;\n    this.barrier.next();\n\n    return prom.then(({ result, error }) => {\n      if (error) return Promise.reject(error);\n      return result;\n    });\n  }\n}\n"],"mappings":"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"}