{"version":3,"file":"tracer_langchain.cjs","names":["AIMessage","mergeUsageMetadata","BaseTracer","getDefaultLangChainClientSingleton","RunTree"],"sources":["../../src/tracers/tracer_langchain.ts"],"sourcesContent":["import {\n  type Client,\n  type LangSmithTracingClientInterface,\n  getDefaultProjectName,\n} from \"langsmith\";\nimport { RunTree, type RunTreeConfig } from \"langsmith/run_trees\";\nimport { getCurrentRunTree } from \"langsmith/singletons/traceable\";\n\nimport {\n  BaseRun,\n  RunCreate,\n  RunUpdate as BaseRunUpdate,\n  KVMap,\n} from \"langsmith/schemas\";\nimport { BaseTracer, Run as BaseTracerRun } from \"./base.js\";\nimport { BaseCallbackHandlerInput } from \"../callbacks/base.js\";\nimport { getDefaultLangChainClientSingleton } from \"../singletons/tracer.js\";\nimport { ChatGeneration } from \"../outputs.js\";\nimport { AIMessage } from \"../messages/ai.js\";\nimport { mergeUsageMetadata, UsageMetadata } from \"../messages/metadata.js\";\n\nexport interface Run extends BaseRun {\n  id: string;\n  child_runs: this[];\n  child_execution_order: number;\n  dotted_order?: string;\n  trace_id?: string;\n}\n\nexport interface RunCreate2 extends RunCreate {\n  trace_id?: string;\n  dotted_order?: string;\n}\n\nexport interface RunUpdate extends BaseRunUpdate {\n  events: BaseRun[\"events\"];\n  inputs: KVMap;\n  trace_id?: string;\n  dotted_order?: string;\n}\n\nexport interface LangChainTracerFields extends BaseCallbackHandlerInput {\n  exampleId?: string;\n  projectName?: string;\n  client?: LangSmithTracingClientInterface;\n  replicas?: RunTreeConfig[\"replicas\"];\n}\n\n/**\n * Extract usage_metadata from chat generations.\n *\n * Iterates through generations to find and aggregates all usage_metadata\n * found in chat messages. This is typically present in chat model outputs.\n */\nfunction _getUsageMetadataFromGenerations(\n  generations: ChatGeneration[][]\n): UsageMetadata | undefined {\n  let output: UsageMetadata | undefined = undefined;\n  for (const generationBatch of generations) {\n    for (const generation of generationBatch) {\n      if (\n        AIMessage.isInstance(generation.message) &&\n        generation.message.usage_metadata !== undefined\n      ) {\n        output = mergeUsageMetadata(output, generation.message.usage_metadata);\n      }\n    }\n  }\n  return output;\n}\n\nexport class LangChainTracer\n  extends BaseTracer\n  implements LangChainTracerFields\n{\n  name = \"langchain_tracer\";\n\n  projectName?: string;\n\n  exampleId?: string;\n\n  client: LangSmithTracingClientInterface;\n\n  replicas?: RunTreeConfig[\"replicas\"];\n\n  usesRunTreeMap = true;\n\n  constructor(fields: LangChainTracerFields = {}) {\n    super(fields);\n    const { exampleId, projectName, client, replicas } = fields;\n\n    this.projectName = projectName ?? getDefaultProjectName();\n    this.replicas = replicas;\n    this.exampleId = exampleId;\n    this.client = client ?? getDefaultLangChainClientSingleton();\n\n    const traceableTree = LangChainTracer.getTraceableRunTree();\n    if (traceableTree) {\n      this.updateFromRunTree(traceableTree);\n    }\n  }\n\n  protected async persistRun(_run: Run): Promise<void> {\n    // empty\n  }\n\n  async onRunCreate(run: Run): Promise<void> {\n    if (!run.extra?.lc_defers_inputs) {\n      const runTree = this.getRunTreeWithTracingConfig(run.id);\n      await runTree?.postRun();\n    }\n  }\n\n  async onRunUpdate(run: Run): Promise<void> {\n    const runTree = this.getRunTreeWithTracingConfig(run.id);\n    if (run.extra?.lc_defers_inputs) {\n      await runTree?.postRun();\n    } else {\n      await runTree?.patchRun();\n    }\n  }\n\n  onLLMEnd(run: BaseTracerRun): void {\n    // Extract usage_metadata from outputs and store in extra.metadata\n    const outputs = run.outputs as\n      | { generations?: ChatGeneration[][] }\n      | undefined;\n    if (outputs?.generations) {\n      const usageMetadata = _getUsageMetadataFromGenerations(\n        outputs.generations\n      );\n      if (usageMetadata !== undefined) {\n        run.extra = run.extra ?? {};\n        const metadata =\n          (run.extra.metadata as Record<string, unknown> | undefined) ?? {};\n        metadata.usage_metadata = usageMetadata;\n        run.extra.metadata = metadata;\n      }\n    }\n  }\n\n  getRun(id: string): Run | undefined {\n    return this.runTreeMap.get(id);\n  }\n\n  updateFromRunTree(runTree: RunTree) {\n    this.runTreeMap.set(runTree.id, runTree);\n    let rootRun: RunTree = runTree;\n    const visited = new Set<string>();\n    while (rootRun.parent_run) {\n      if (visited.has(rootRun.id)) break;\n      visited.add(rootRun.id);\n\n      if (!rootRun.parent_run) break;\n      rootRun = rootRun.parent_run as RunTree;\n    }\n    visited.clear();\n\n    const queue = [rootRun];\n    while (queue.length > 0) {\n      const current = queue.shift();\n      if (!current || visited.has(current.id)) continue;\n      visited.add(current.id);\n\n      this.runTreeMap.set(current.id, current);\n      if (current.child_runs) {\n        queue.push(...current.child_runs);\n      }\n    }\n\n    this.client = runTree.client ?? this.client;\n    this.replicas = runTree.replicas ?? this.replicas;\n    this.projectName = runTree.project_name ?? this.projectName;\n    this.exampleId = runTree.reference_example_id ?? this.exampleId;\n  }\n\n  getRunTreeWithTracingConfig(id: string): RunTree | undefined {\n    const runTree = this.runTreeMap.get(id);\n    if (!runTree) return undefined;\n\n    return new RunTree({\n      ...runTree,\n      client: this.client as Client,\n      project_name: this.projectName,\n      replicas: this.replicas,\n      reference_example_id: this.exampleId,\n      tracingEnabled: true,\n    });\n  }\n\n  static getTraceableRunTree(): RunTree | undefined {\n    try {\n      return (\n        // The type cast here provides forward compatibility. Old versions of LangSmith will just\n        // ignore the permitAbsentRunTree arg.\n        (\n          getCurrentRunTree as (\n            permitAbsentRunTree: boolean\n          ) => ReturnType<typeof getCurrentRunTree> | undefined\n        )(true)\n      );\n    } catch {\n      return undefined;\n    }\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAsDA,SAAS,iCACP,aAC2B;CAC3B,IAAI,SAAoC,KAAA;AACxC,MAAK,MAAM,mBAAmB,YAC5B,MAAK,MAAM,cAAc,gBACvB,KACEA,WAAAA,UAAU,WAAW,WAAW,QAAQ,IACxC,WAAW,QAAQ,mBAAmB,KAAA,EAEtC,UAASC,iBAAAA,mBAAmB,QAAQ,WAAW,QAAQ,eAAe;AAI5E,QAAO;;AAGT,IAAa,kBAAb,MAAa,wBACHC,qBAAAA,WAEV;CACE,OAAO;CAEP;CAEA;CAEA;CAEA;CAEA,iBAAiB;CAEjB,YAAY,SAAgC,EAAE,EAAE;AAC9C,QAAM,OAAO;EACb,MAAM,EAAE,WAAW,aAAa,QAAQ,aAAa;AAErD,OAAK,cAAc,gBAAA,GAAA,UAAA,wBAAsC;AACzD,OAAK,WAAW;AAChB,OAAK,YAAY;AACjB,OAAK,SAAS,UAAUC,eAAAA,oCAAoC;EAE5D,MAAM,gBAAgB,gBAAgB,qBAAqB;AAC3D,MAAI,cACF,MAAK,kBAAkB,cAAc;;CAIzC,MAAgB,WAAW,MAA0B;CAIrD,MAAM,YAAY,KAAyB;AACzC,MAAI,CAAC,IAAI,OAAO,iBAEd,OADgB,KAAK,4BAA4B,IAAI,GAAG,EACzC,SAAS;;CAI5B,MAAM,YAAY,KAAyB;EACzC,MAAM,UAAU,KAAK,4BAA4B,IAAI,GAAG;AACxD,MAAI,IAAI,OAAO,iBACb,OAAM,SAAS,SAAS;MAExB,OAAM,SAAS,UAAU;;CAI7B,SAAS,KAA0B;EAEjC,MAAM,UAAU,IAAI;AAGpB,MAAI,SAAS,aAAa;GACxB,MAAM,gBAAgB,iCACpB,QAAQ,YACT;AACD,OAAI,kBAAkB,KAAA,GAAW;AAC/B,QAAI,QAAQ,IAAI,SAAS,EAAE;IAC3B,MAAM,WACH,IAAI,MAAM,YAAoD,EAAE;AACnE,aAAS,iBAAiB;AAC1B,QAAI,MAAM,WAAW;;;;CAK3B,OAAO,IAA6B;AAClC,SAAO,KAAK,WAAW,IAAI,GAAG;;CAGhC,kBAAkB,SAAkB;AAClC,OAAK,WAAW,IAAI,QAAQ,IAAI,QAAQ;EACxC,IAAI,UAAmB;EACvB,MAAM,0BAAU,IAAI,KAAa;AACjC,SAAO,QAAQ,YAAY;AACzB,OAAI,QAAQ,IAAI,QAAQ,GAAG,CAAE;AAC7B,WAAQ,IAAI,QAAQ,GAAG;AAEvB,OAAI,CAAC,QAAQ,WAAY;AACzB,aAAU,QAAQ;;AAEpB,UAAQ,OAAO;EAEf,MAAM,QAAQ,CAAC,QAAQ;AACvB,SAAO,MAAM,SAAS,GAAG;GACvB,MAAM,UAAU,MAAM,OAAO;AAC7B,OAAI,CAAC,WAAW,QAAQ,IAAI,QAAQ,GAAG,CAAE;AACzC,WAAQ,IAAI,QAAQ,GAAG;AAEvB,QAAK,WAAW,IAAI,QAAQ,IAAI,QAAQ;AACxC,OAAI,QAAQ,WACV,OAAM,KAAK,GAAG,QAAQ,WAAW;;AAIrC,OAAK,SAAS,QAAQ,UAAU,KAAK;AACrC,OAAK,WAAW,QAAQ,YAAY,KAAK;AACzC,OAAK,cAAc,QAAQ,gBAAgB,KAAK;AAChD,OAAK,YAAY,QAAQ,wBAAwB,KAAK;;CAGxD,4BAA4B,IAAiC;EAC3D,MAAM,UAAU,KAAK,WAAW,IAAI,GAAG;AACvC,MAAI,CAAC,QAAS,QAAO,KAAA;AAErB,SAAO,IAAIC,oBAAAA,QAAQ;GACjB,GAAG;GACH,QAAQ,KAAK;GACb,cAAc,KAAK;GACnB,UAAU,KAAK;GACf,sBAAsB,KAAK;GAC3B,gBAAgB;GACjB,CAAC;;CAGJ,OAAO,sBAA2C;AAChD,MAAI;AACF,WAAA,GAAA,+BAAA,mBAOI,KAAK;UAEH;AACN"}