{"version":3,"file":"config.cjs","names":["CallbackManager","ensureHandler","AsyncLocalStorageProviderSingleton"],"sources":["../../src/runnables/config.ts"],"sourcesContent":["import { CallbackManager, ensureHandler } from \"../callbacks/manager.js\";\nimport { AsyncLocalStorageProviderSingleton } from \"../singletons/index.js\";\nimport { RunnableConfig } from \"./types.js\";\n\nexport const DEFAULT_RECURSION_LIMIT = 25;\n\nexport { type RunnableConfig };\n\nconst CONFIGURABLE_TO_TRACING_METADATA_EXCLUDED_KEYS = new Set([\"api_key\"]);\nconst PRIMITIVES = new Set([\"string\", \"number\", \"boolean\"]);\n\nexport function _getTracingInheritableMetadataFromConfig(\n  config: RunnableConfig\n): Record<string, unknown> | undefined {\n  const configurable = config.configurable ?? {};\n  const metadata = config.metadata ?? {};\n  const langSmithMetadata: Record<string, unknown> = {};\n  for (const [key, value] of Object.entries(configurable)) {\n    if (\n      !key.startsWith(\"__\") &&\n      !Object.prototype.hasOwnProperty.call(metadata, key) &&\n      !CONFIGURABLE_TO_TRACING_METADATA_EXCLUDED_KEYS.has(key) &&\n      PRIMITIVES.has(typeof value)\n    ) {\n      langSmithMetadata[key] = value;\n    }\n  }\n  return Object.keys(langSmithMetadata).length > 0\n    ? langSmithMetadata\n    : undefined;\n}\n\nexport async function getCallbackManagerForConfig(config?: RunnableConfig) {\n  return CallbackManager._configureSync(\n    config?.callbacks,\n    undefined,\n    config?.tags,\n    undefined,\n    config?.metadata,\n    undefined,\n    {\n      tracerInheritableMetadata: config\n        ? _getTracingInheritableMetadataFromConfig(config)\n        : undefined,\n    }\n  );\n}\n\nexport function mergeConfigs<CallOptions extends RunnableConfig>(\n  ...configs: (CallOptions | RunnableConfig | undefined | null)[]\n): Partial<CallOptions> {\n  // We do not want to call ensureConfig on the empty state here as this may cause\n  // double loading of callbacks if async local storage is being used.\n  const copy: Partial<CallOptions> = {};\n  for (const options of configs.filter((c): c is CallOptions => !!c)) {\n    for (const key of Object.keys(options)) {\n      if (key === \"metadata\") {\n        copy[key] = { ...copy[key], ...options[key] };\n      } else if (key === \"tags\") {\n        const baseKeys: string[] = copy[key] ?? [];\n        copy[key] = [...new Set(baseKeys.concat(options[key] ?? []))];\n      } else if (key === \"configurable\") {\n        copy[key] = { ...copy[key], ...options[key] };\n      } else if (key === \"timeout\") {\n        if (copy.timeout === undefined) {\n          copy.timeout = options.timeout;\n        } else if (options.timeout !== undefined) {\n          copy.timeout = Math.min(copy.timeout, options.timeout);\n        }\n      } else if (key === \"signal\") {\n        if (copy.signal === undefined) {\n          copy.signal = options.signal;\n        } else if (options.signal !== undefined) {\n          if (\"any\" in AbortSignal) {\n            // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n            copy.signal = (AbortSignal as any).any([\n              copy.signal,\n              options.signal,\n            ]);\n          } else {\n            copy.signal = options.signal;\n          }\n        }\n      } else if (key === \"callbacks\") {\n        const baseCallbacks = copy.callbacks;\n        const providedCallbacks = options.callbacks;\n        // callbacks can be either undefined, Array<handler> or manager\n        // so merging two callbacks values has 6 cases\n        if (Array.isArray(providedCallbacks)) {\n          if (!baseCallbacks) {\n            copy.callbacks = providedCallbacks;\n          } else if (Array.isArray(baseCallbacks)) {\n            copy.callbacks = baseCallbacks.concat(providedCallbacks);\n          } else {\n            // baseCallbacks is a manager\n            const manager = baseCallbacks.copy();\n            for (const callback of providedCallbacks) {\n              manager.addHandler(ensureHandler(callback), true);\n            }\n            copy.callbacks = manager;\n          }\n        } else if (providedCallbacks) {\n          // providedCallbacks is a manager\n          if (!baseCallbacks) {\n            copy.callbacks = providedCallbacks;\n          } else if (Array.isArray(baseCallbacks)) {\n            const manager = providedCallbacks.copy();\n            for (const callback of baseCallbacks) {\n              manager.addHandler(ensureHandler(callback), true);\n            }\n            copy.callbacks = manager;\n          } else {\n            // baseCallbacks is also a manager\n            copy.callbacks = new CallbackManager(\n              providedCallbacks._parentRunId,\n              {\n                handlers: baseCallbacks.handlers.concat(\n                  providedCallbacks.handlers\n                ),\n                inheritableHandlers: baseCallbacks.inheritableHandlers.concat(\n                  providedCallbacks.inheritableHandlers\n                ),\n                tags: Array.from(\n                  new Set(baseCallbacks.tags.concat(providedCallbacks.tags))\n                ),\n                inheritableTags: Array.from(\n                  new Set(\n                    baseCallbacks.inheritableTags.concat(\n                      providedCallbacks.inheritableTags\n                    )\n                  )\n                ),\n                metadata: {\n                  ...baseCallbacks.metadata,\n                  ...providedCallbacks.metadata,\n                },\n              }\n            );\n          }\n        }\n      } else {\n        const typedKey = key as keyof CallOptions;\n        copy[typedKey] = options[typedKey] ?? copy[typedKey];\n      }\n    }\n  }\n  return copy as Partial<CallOptions>;\n}\n\n/**\n * Ensure that a passed config is an object with all required keys present.\n */\nexport function ensureConfig<CallOptions extends RunnableConfig>(\n  config?: CallOptions\n): CallOptions {\n  const implicitConfig = AsyncLocalStorageProviderSingleton.getRunnableConfig();\n  let empty: RunnableConfig = {\n    tags: [],\n    metadata: {},\n    recursionLimit: 25,\n    runId: undefined,\n  };\n  if (implicitConfig) {\n    // Don't allow runId and runName to be loaded implicitly, as this can cause\n    // child runs to improperly inherit their parents' run ids.\n    const { runId, runName, ...rest } = implicitConfig;\n    empty = Object.entries(rest).reduce(\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      (currentConfig: Record<string, any>, [key, value]) => {\n        if (value !== undefined) {\n          currentConfig[key] = value;\n        }\n        return currentConfig;\n      },\n      empty\n    );\n  }\n  if (config) {\n    empty = Object.entries(config).reduce(\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      (currentConfig: Record<string, any>, [key, value]) => {\n        if (value !== undefined) {\n          currentConfig[key] = value;\n        }\n        return currentConfig;\n      },\n      empty\n    );\n  }\n  if (empty?.configurable) {\n    if (\n      typeof empty.configurable.model === \"string\" &&\n      empty.metadata?.model === undefined\n    ) {\n      if (!empty.metadata) {\n        empty.metadata = {};\n      }\n      empty.metadata.model = empty.configurable.model;\n    }\n  }\n  if (empty.timeout !== undefined) {\n    if (empty.timeout <= 0) {\n      throw new Error(\"Timeout must be a positive number\");\n    }\n    const originalTimeoutMs = empty.timeout;\n    const timeoutSignal = AbortSignal.timeout(originalTimeoutMs);\n    // Preserve the numeric timeout for downstream consumers that need to pass\n    // an explicit timeout value to underlying SDKs in addition to an AbortSignal.\n    // We store it in metadata to avoid changing the public config shape.\n    if (!empty.metadata) {\n      empty.metadata = {};\n    }\n    // Do not overwrite if already set upstream.\n    if (empty.metadata.timeoutMs === undefined) {\n      empty.metadata.timeoutMs = originalTimeoutMs;\n    }\n    if (empty.signal !== undefined) {\n      if (\"any\" in AbortSignal) {\n        // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n        empty.signal = (AbortSignal as any).any([empty.signal, timeoutSignal]);\n      }\n    } else {\n      empty.signal = timeoutSignal;\n    }\n\n    /**\n     * We are deleting the timeout key for the following reasons:\n     * - Idempotent normalization: ensureConfig may be called multiple times down the stack. If timeout remains,\n     *   each call would synthesize new timeout signals and combine them, changing the effective timeout unpredictably.\n     * - Single enforcement path: downstream code relies on signal to enforce cancellation. Leaving timeout means two\n     *   competing mechanisms (numeric timeout and signal) can be applied, sometimes with different semantics.\n     * - Propagation to children: pickRunnableConfigKeys would keep forwarding timeout to nested runnables, causing\n     *   repeated re-normalization and stacked timeouts.\n     * - Backward compatibility: a lot of components and tests assume ensureConfig removes timeout post-normalization;\n     *   changing that would be a breaking change.\n     */\n    delete empty.timeout;\n  }\n  return empty as CallOptions;\n}\n\n/**\n * Helper function that patches runnable configs with updated properties.\n */\nexport function patchConfig<CallOptions extends RunnableConfig>(\n  config: Partial<CallOptions> = {},\n  {\n    callbacks,\n    maxConcurrency,\n    recursionLimit,\n    runName,\n    configurable,\n    runId,\n  }: RunnableConfig = {}\n): Partial<CallOptions> {\n  const newConfig = ensureConfig(config);\n  if (callbacks !== undefined) {\n    /**\n     * If we're replacing callbacks we need to unset runName\n     * since that should apply only to the same run as the original callbacks\n     */\n    delete newConfig.runName;\n    newConfig.callbacks = callbacks;\n  }\n  if (recursionLimit !== undefined) {\n    newConfig.recursionLimit = recursionLimit;\n  }\n  if (maxConcurrency !== undefined) {\n    newConfig.maxConcurrency = maxConcurrency;\n  }\n  if (runName !== undefined) {\n    newConfig.runName = runName;\n  }\n  if (configurable !== undefined) {\n    newConfig.configurable = { ...newConfig.configurable, ...configurable };\n  }\n  if (runId !== undefined) {\n    delete newConfig.runId;\n  }\n  return newConfig;\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function pickRunnableConfigKeys<CallOptions extends Record<string, any>>(\n  config?: CallOptions\n): Partial<RunnableConfig> | undefined {\n  if (!config) return undefined;\n\n  return {\n    configurable: config.configurable,\n    recursionLimit: config.recursionLimit,\n    callbacks: config.callbacks,\n    tags: config.tags,\n    metadata: config.metadata,\n    maxConcurrency: config.maxConcurrency,\n    timeout: config.timeout,\n    signal: config.signal,\n    // @ts-expect-error - Store is a LangGraph-specific property\n    // which wewant to pass through to all runnables.\n    // (eg. tools should have access to writing to the store)\n    store: config.store,\n  };\n}\n"],"mappings":"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"}