langchain.cjs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.RunnableTraceable = void 0;
  4. exports.getLangchainCallbacks = getLangchainCallbacks;
  5. // These `@langchain/core` imports are intentionally not peer dependencies
  6. // to avoid package manager issues around circular dependencies.
  7. // eslint-disable-next-line import/no-extraneous-dependencies
  8. const manager_1 = require("@langchain/core/callbacks/manager");
  9. // eslint-disable-next-line import/no-extraneous-dependencies
  10. const tracer_langchain_1 = require("@langchain/core/tracers/tracer_langchain");
  11. // eslint-disable-next-line import/no-extraneous-dependencies
  12. const runnables_1 = require("@langchain/core/runnables");
  13. const traceable_js_1 = require("./traceable.cjs");
  14. const asserts_js_1 = require("./utils/asserts.cjs");
  15. /**
  16. * Converts the current run tree active within a traceable-wrapped function
  17. * into a LangChain compatible callback manager. This is useful to handoff tracing
  18. * from LangSmith to LangChain Runnables and LLMs.
  19. *
  20. * @param {RunTree | undefined} currentRunTree Current RunTree from within a traceable-wrapped function. If not provided, the current run tree will be inferred from AsyncLocalStorage.
  21. * @returns {CallbackManager | undefined} Callback manager used by LangChain Runnable objects.
  22. */
  23. async function getLangchainCallbacks(currentRunTree) {
  24. const runTree = currentRunTree ?? (0, traceable_js_1.getCurrentRunTree)();
  25. if (!runTree)
  26. return undefined;
  27. // TODO: CallbackManager.configure() is only async due to LangChainTracer
  28. // factory being unnecessarily async.
  29. let callbacks = await manager_1.CallbackManager.configure();
  30. if (!callbacks && runTree.tracingEnabled) {
  31. callbacks = new manager_1.CallbackManager();
  32. }
  33. let langChainTracer = callbacks?.handlers.find((handler) => handler?.name === "langchain_tracer");
  34. if (!langChainTracer && runTree.tracingEnabled) {
  35. langChainTracer = new tracer_langchain_1.LangChainTracer();
  36. callbacks?.addHandler(langChainTracer);
  37. }
  38. const runMap = new Map();
  39. // find upward root run
  40. let rootRun = runTree;
  41. const rootVisited = new Set();
  42. while (rootRun.parent_run) {
  43. if (rootVisited.has(rootRun.id))
  44. break;
  45. rootVisited.add(rootRun.id);
  46. rootRun = rootRun.parent_run;
  47. }
  48. const queue = [rootRun];
  49. const visited = new Set();
  50. while (queue.length > 0) {
  51. const current = queue.shift();
  52. if (!current || visited.has(current.id))
  53. continue;
  54. visited.add(current.id);
  55. runMap.set(current.id, current);
  56. if (current.child_runs) {
  57. queue.push(...current.child_runs);
  58. }
  59. }
  60. if (callbacks != null) {
  61. Object.assign(callbacks, { _parentRunId: runTree.id });
  62. }
  63. if (langChainTracer != null) {
  64. if ("updateFromRunTree" in langChainTracer &&
  65. typeof langChainTracer === "function") {
  66. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  67. // @ts-ignore @langchain/core can use a different version of LangSmith
  68. langChainTracer.updateFromRunTree(runTree);
  69. }
  70. else {
  71. Object.assign(langChainTracer, {
  72. runMap,
  73. client: runTree.client,
  74. projectName: runTree.project_name || langChainTracer.projectName,
  75. exampleId: runTree.reference_example_id || langChainTracer.exampleId,
  76. });
  77. }
  78. }
  79. return callbacks;
  80. }
  81. /**
  82. * RunnableTraceable is a Runnable that wraps a traceable function.
  83. * This allows adding Langsmith traced functions into LangChain sequences.
  84. */
  85. class RunnableTraceable extends runnables_1.Runnable {
  86. constructor(fields) {
  87. super(fields);
  88. Object.defineProperty(this, "lc_serializable", {
  89. enumerable: true,
  90. configurable: true,
  91. writable: true,
  92. value: false
  93. });
  94. Object.defineProperty(this, "lc_namespace", {
  95. enumerable: true,
  96. configurable: true,
  97. writable: true,
  98. value: ["langchain_core", "runnables"]
  99. });
  100. Object.defineProperty(this, "func", {
  101. enumerable: true,
  102. configurable: true,
  103. writable: true,
  104. value: void 0
  105. });
  106. if (!(0, traceable_js_1.isTraceableFunction)(fields.func)) {
  107. throw new Error("RunnableTraceable requires a function that is wrapped in traceable higher-order function");
  108. }
  109. this.func = fields.func;
  110. }
  111. async invoke(input, options) {
  112. const [config] = this._getOptionsList(options ?? {}, 1);
  113. const callbacks = await (0, runnables_1.getCallbackManagerForConfig)(config);
  114. return (await this.func((0, runnables_1.patchConfig)(config, { callbacks }), input));
  115. }
  116. async *_streamIterator(input, options) {
  117. const result = await this.invoke(input, options);
  118. if ((0, asserts_js_1.isAsyncIterable)(result)) {
  119. for await (const item of result) {
  120. yield item;
  121. }
  122. return;
  123. }
  124. if ((0, asserts_js_1.isIteratorLike)(result)) {
  125. while (true) {
  126. const state = result.next();
  127. if (state.done)
  128. break;
  129. yield state.value;
  130. }
  131. return;
  132. }
  133. yield result;
  134. }
  135. static from(func) {
  136. return new RunnableTraceable({ func });
  137. }
  138. }
  139. exports.RunnableTraceable = RunnableTraceable;