{"version":3,"file":"debug.cjs","names":["INTERRUPT","findSubgraphPregel","readChannels"],"sources":["../../src/pregel/debug.ts"],"sourcesContent":["import { RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n  CheckpointMetadata,\n  CheckpointPendingWrite,\n  PendingWrite,\n} from \"@langchain/langgraph-checkpoint\";\nimport { BaseChannel } from \"../channels/base.js\";\nimport {\n  ERROR,\n  Interrupt,\n  INTERRUPT,\n  RETURN,\n  TAG_HIDDEN,\n} from \"../constants.js\";\nimport { EmptyChannelError } from \"../errors.js\";\nimport {\n  PregelExecutableTask,\n  PregelTaskDescription,\n  StateSnapshot,\n} from \"./types.js\";\nimport { readChannels } from \"./io.js\";\nimport { findSubgraphPregel } from \"./utils/subgraph.js\";\n\ntype ConsoleColors = {\n  start: string;\n  end: string;\n};\n\ntype ConsoleColorMap = {\n  [key: string]: ConsoleColors;\n};\n\nconst COLORS_MAP: ConsoleColorMap = {\n  blue: {\n    start: \"\\x1b[34m\",\n    end: \"\\x1b[0m\",\n  },\n  green: {\n    start: \"\\x1b[32m\",\n    end: \"\\x1b[0m\",\n  },\n  yellow: {\n    start: \"\\x1b[33;1m\",\n    end: \"\\x1b[0m\",\n  },\n};\n\n/**\n * Wrap some text in a color for printing to the console.\n */\nexport const wrap = (color: ConsoleColors, text: string): string =>\n  `${color.start}${text}${color.end}`;\n\nexport function printCheckpoint<Value>(\n  step: number,\n  channels: Record<string, BaseChannel<Value>>\n) {\n  console.log(\n    [\n      `${wrap(COLORS_MAP.blue, \"[langgraph/checkpoint]\")}`,\n      `Finishing step ${step}. Channel values:\\n`,\n      `\\n${JSON.stringify(\n        Object.fromEntries(_readChannels<Value>(channels)),\n        null,\n        2\n      )}`,\n    ].join(\"\")\n  );\n}\n\nexport function* _readChannels<Value>(\n  channels: Record<string, BaseChannel<Value>>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): IterableIterator<[string, any]> {\n  for (const [name, channel] of Object.entries(channels)) {\n    try {\n      yield [name, channel.get()];\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    } catch (error: any) {\n      if (error.name === EmptyChannelError.unminifiable_name) {\n        // Skip the channel if it's empty\n        continue;\n      } else {\n        throw error; // Re-throw the error if it's not an EmptyChannelError\n      }\n    }\n  }\n}\n\nexport function* mapDebugTasks<N extends PropertyKey, C extends PropertyKey>(\n  tasks: readonly PregelExecutableTask<N, C>[]\n) {\n  for (const { id, name, input, config, triggers, writes } of tasks) {\n    if (config?.tags?.includes(TAG_HIDDEN)) continue;\n\n    const interrupts = writes\n      .filter(([writeId, n]) => {\n        return writeId === id && n === INTERRUPT;\n      })\n      .map(([, v]) => {\n        return v;\n      });\n    yield { id, name, input, triggers, interrupts };\n  }\n}\n\nfunction isMultipleChannelWrite(\n  value: unknown\n): value is { $writes: unknown[] } {\n  if (typeof value !== \"object\" || value === null) return false;\n  return \"$writes\" in value && Array.isArray(value.$writes);\n}\n\nfunction mapTaskResultWrites(writes: PendingWrite<unknown>[]) {\n  const result: Record<string, unknown> = {};\n\n  for (const [channel, value] of writes) {\n    const strChannel = String(channel);\n\n    if (strChannel in result) {\n      const channelWrites = isMultipleChannelWrite(result[strChannel])\n        ? result[strChannel].$writes\n        : [result[strChannel]];\n\n      channelWrites.push(value);\n      result[strChannel] = { $writes: channelWrites };\n    } else {\n      result[strChannel] = value;\n    }\n  }\n  return result;\n}\n\nexport function* mapDebugTaskResults<\n  N extends PropertyKey,\n  C extends PropertyKey,\n>(\n  tasks: readonly [PregelExecutableTask<N, C>, PendingWrite<C>[]][],\n  streamChannels: PropertyKey | Array<PropertyKey>\n) {\n  for (const [{ id, name, config }, writes] of tasks) {\n    if (config?.tags?.includes(TAG_HIDDEN)) continue;\n    yield {\n      id,\n      name,\n      result: mapTaskResultWrites(\n        writes.filter(([channel]) => {\n          return Array.isArray(streamChannels)\n            ? streamChannels.includes(channel)\n            : channel === streamChannels;\n        })\n      ),\n      interrupts: writes.filter((w) => w[0] === INTERRUPT).map((w) => w[1]),\n    };\n  }\n}\n\ntype ChannelKey = string | number | symbol;\n\nexport function* mapDebugCheckpoint<\n  N extends PropertyKey,\n  C extends PropertyKey,\n>(\n  config: RunnableConfig,\n  channels: Record<string, BaseChannel>,\n  streamChannels: string | string[],\n  metadata: CheckpointMetadata,\n  tasks: readonly PregelExecutableTask<N, C>[],\n  pendingWrites: CheckpointPendingWrite[],\n  parentConfig: RunnableConfig | undefined,\n  outputKeys: ChannelKey | ChannelKey[]\n) {\n  function formatConfig(config: RunnableConfig) {\n    // https://stackoverflow.com/a/78298178\n    type CamelToSnake<\n      T extends string,\n      A extends string = \"\",\n    > = T extends `${infer F}${infer R}`\n      ? CamelToSnake<\n          R,\n          `${A}${F extends Lowercase<F> ? F : `_${Lowercase<F>}`}`\n        >\n      : A;\n\n    // make sure the config is consistent with Python\n    const pyConfig: Partial<\n      Record<CamelToSnake<keyof RunnableConfig>, unknown>\n    > = {};\n\n    if (config.callbacks != null) pyConfig.callbacks = config.callbacks;\n    if (config.configurable != null)\n      pyConfig.configurable = config.configurable;\n    if (config.maxConcurrency != null)\n      pyConfig.max_concurrency = config.maxConcurrency;\n\n    if (config.metadata != null) pyConfig.metadata = config.metadata;\n    if (config.recursionLimit != null)\n      pyConfig.recursion_limit = config.recursionLimit;\n    if (config.runId != null) pyConfig.run_id = config.runId;\n    if (config.runName != null) pyConfig.run_name = config.runName;\n    if (config.tags != null) pyConfig.tags = config.tags;\n\n    return pyConfig;\n  }\n\n  const parentNs = config.configurable?.checkpoint_ns;\n  const taskStates: Record<string, RunnableConfig | StateSnapshot> = {};\n\n  for (const task of tasks) {\n    const candidates = task.subgraphs?.length ? task.subgraphs : [task.proc];\n    if (!candidates.find(findSubgraphPregel)) continue;\n\n    let taskNs = `${task.name as string}:${task.id}`;\n    if (parentNs) taskNs = `${parentNs}|${taskNs}`;\n\n    taskStates[task.id] = {\n      configurable: {\n        thread_id: config.configurable?.thread_id,\n        checkpoint_ns: taskNs,\n      },\n    };\n  }\n\n  yield {\n    config: formatConfig(config),\n    values: readChannels(channels, streamChannels),\n    metadata,\n    next: tasks.map((task) => task.name),\n    tasks: tasksWithWrites(tasks, pendingWrites, taskStates, outputKeys),\n    parentConfig: parentConfig ? formatConfig(parentConfig) : undefined,\n  };\n}\n\nexport function tasksWithWrites<N extends PropertyKey, C extends PropertyKey>(\n  tasks: PregelTaskDescription[] | readonly PregelExecutableTask<N, C>[],\n  pendingWrites: CheckpointPendingWrite[],\n  states: Record<string, RunnableConfig | StateSnapshot> | undefined,\n  outputKeys: ChannelKey[] | ChannelKey\n): PregelTaskDescription[] {\n  return tasks.map((task): PregelTaskDescription => {\n    const error = pendingWrites.find(\n      ([id, n]) => id === task.id && n === ERROR\n    )?.[2];\n\n    const interrupts = pendingWrites\n      .filter(([id, n]) => id === task.id && n === INTERRUPT)\n      .map(([, , v]) => v) as Interrupt[];\n\n    const result = (() => {\n      if (error || interrupts.length || !pendingWrites.length) return undefined;\n\n      const idx = pendingWrites.findIndex(\n        ([tid, n]) => tid === task.id && n === RETURN\n      );\n\n      if (idx >= 0) return pendingWrites[idx][2];\n\n      if (typeof outputKeys === \"string\") {\n        return pendingWrites.find(\n          ([tid, n]) => tid === task.id && n === outputKeys\n        )?.[2];\n      }\n\n      if (Array.isArray(outputKeys)) {\n        const results = pendingWrites\n          .filter(([tid, n]) => tid === task.id && outputKeys.includes(n))\n          .map(([, n, v]) => [n, v] as PendingWrite<C>);\n\n        if (!results.length) return undefined;\n        return mapTaskResultWrites(results);\n      }\n\n      return undefined;\n    })();\n\n    if (error) {\n      return {\n        id: task.id,\n        name: task.name as string,\n        path: task.path,\n        error,\n        interrupts,\n        result,\n      };\n    }\n\n    const taskState = states?.[task.id];\n    return {\n      id: task.id,\n      name: task.name as string,\n      path: task.path,\n      interrupts,\n      ...(taskState !== undefined ? { state: taskState } : {}),\n      result,\n    };\n  });\n}\n\nexport function printStepCheckpoint(\n  step: number,\n  channels: Record<string, BaseChannel<unknown>>,\n  whitelist: string[]\n): void {\n  console.log(\n    [\n      `${wrap(COLORS_MAP.blue, `[${step}:checkpoint]`)}`,\n      `\\x1b[1m State at the end of step ${step}:\\x1b[0m\\n`,\n      JSON.stringify(readChannels(channels, whitelist), null, 2),\n    ].join(\"\")\n  );\n}\n\nexport function printStepTasks<N extends PropertyKey, C extends PropertyKey>(\n  step: number,\n  nextTasks: readonly PregelExecutableTask<N, C>[]\n): void {\n  const nTasks = nextTasks.length;\n  console.log(\n    [\n      `${wrap(COLORS_MAP.blue, `[${step}:tasks]`)}`,\n      `\\x1b[1m Starting step ${step} with ${nTasks} task${\n        nTasks === 1 ? \"\" : \"s\"\n      }:\\x1b[0m\\n`,\n      nextTasks\n        .map(\n          (task) =>\n            `- ${wrap(COLORS_MAP.green, String(task.name))} -> ${JSON.stringify(\n              task.input,\n              null,\n              2\n            )}`\n        )\n        .join(\"\\n\"),\n    ].join(\"\")\n  );\n}\n\nexport function printStepWrites(\n  step: number,\n  writes: PendingWrite[],\n  whitelist: string[]\n): void {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const byChannel: Record<string, any[]> = {};\n\n  for (const [channel, value] of writes) {\n    if (whitelist.includes(channel)) {\n      if (!byChannel[channel]) {\n        byChannel[channel] = [];\n      }\n      byChannel[channel].push(value);\n    }\n  }\n\n  console.log(\n    [\n      `${wrap(COLORS_MAP.blue, `[${step}:writes]`)}`,\n      `\\x1b[1m Finished step ${step} with writes to ${\n        Object.keys(byChannel).length\n      } channel${Object.keys(byChannel).length !== 1 ? \"s\" : \"\"}:\\x1b[0m\\n`,\n      Object.entries(byChannel)\n        .map(\n          ([name, vals]) =>\n            `- ${wrap(COLORS_MAP.yellow, name)} -> ${vals\n              .map((v) => JSON.stringify(v))\n              .join(\", \")}`\n        )\n        .join(\"\\n\"),\n    ].join(\"\")\n  );\n}\n"],"mappings":"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"}