@langchain/core 1.1.40 → 1.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/callbacks/base.cjs +3 -3
  3. package/dist/callbacks/base.cjs.map +1 -1
  4. package/dist/callbacks/base.js +3 -2
  5. package/dist/callbacks/base.js.map +1 -1
  6. package/dist/callbacks/manager.cjs +8 -7
  7. package/dist/callbacks/manager.cjs.map +1 -1
  8. package/dist/callbacks/manager.js +2 -1
  9. package/dist/callbacks/manager.js.map +1 -1
  10. package/dist/indexing/base.cjs +4 -4
  11. package/dist/indexing/base.cjs.map +1 -1
  12. package/dist/indexing/base.js +2 -1
  13. package/dist/indexing/base.js.map +1 -1
  14. package/dist/language_models/base.cjs +9 -1
  15. package/dist/language_models/base.cjs.map +1 -1
  16. package/dist/language_models/base.d.cts +5 -0
  17. package/dist/language_models/base.d.cts.map +1 -1
  18. package/dist/language_models/base.d.ts +5 -0
  19. package/dist/language_models/base.d.ts.map +1 -1
  20. package/dist/language_models/base.js +9 -1
  21. package/dist/language_models/base.js.map +1 -1
  22. package/dist/language_models/chat_models.cjs +18 -6
  23. package/dist/language_models/chat_models.cjs.map +1 -1
  24. package/dist/language_models/chat_models.d.cts.map +1 -1
  25. package/dist/language_models/chat_models.d.ts.map +1 -1
  26. package/dist/language_models/chat_models.js +18 -6
  27. package/dist/language_models/chat_models.js.map +1 -1
  28. package/dist/language_models/llms.cjs +18 -6
  29. package/dist/language_models/llms.cjs.map +1 -1
  30. package/dist/language_models/llms.d.cts.map +1 -1
  31. package/dist/language_models/llms.d.ts.map +1 -1
  32. package/dist/language_models/llms.js +18 -6
  33. package/dist/language_models/llms.js.map +1 -1
  34. package/dist/load/import_map.cjs +2 -0
  35. package/dist/load/import_map.cjs.map +1 -1
  36. package/dist/load/import_map.js +2 -0
  37. package/dist/load/import_map.js.map +1 -1
  38. package/dist/runnables/base.cjs +3 -2
  39. package/dist/runnables/base.cjs.map +1 -1
  40. package/dist/runnables/base.js +2 -1
  41. package/dist/runnables/base.js.map +1 -1
  42. package/dist/runnables/graph.cjs +8 -6
  43. package/dist/runnables/graph.cjs.map +1 -1
  44. package/dist/runnables/graph.js +3 -1
  45. package/dist/runnables/graph.js.map +1 -1
  46. package/dist/tracers/tracer_langchain.cjs +23 -5
  47. package/dist/tracers/tracer_langchain.cjs.map +1 -1
  48. package/dist/tracers/tracer_langchain.d.cts +13 -1
  49. package/dist/tracers/tracer_langchain.d.cts.map +1 -1
  50. package/dist/tracers/tracer_langchain.d.ts +13 -1
  51. package/dist/tracers/tracer_langchain.d.ts.map +1 -1
  52. package/dist/tracers/tracer_langchain.js +23 -6
  53. package/dist/tracers/tracer_langchain.js.map +1 -1
  54. package/dist/utils/uuid/index.cjs +44 -0
  55. package/dist/utils/uuid/index.cjs.map +1 -0
  56. package/dist/utils/uuid/index.d.cts +12 -0
  57. package/dist/utils/uuid/index.d.ts +12 -0
  58. package/dist/utils/uuid/index.js +28 -0
  59. package/dist/utils/uuid/index.js.map +1 -0
  60. package/dist/utils/uuid/max.cjs +6 -0
  61. package/dist/utils/uuid/max.cjs.map +1 -0
  62. package/dist/utils/uuid/max.d.cts +5 -0
  63. package/dist/utils/uuid/max.d.cts.map +1 -0
  64. package/dist/utils/uuid/max.d.ts +5 -0
  65. package/dist/utils/uuid/max.d.ts.map +1 -0
  66. package/dist/utils/uuid/max.js +6 -0
  67. package/dist/utils/uuid/max.js.map +1 -0
  68. package/dist/utils/uuid/nil.cjs +6 -0
  69. package/dist/utils/uuid/nil.cjs.map +1 -0
  70. package/dist/utils/uuid/nil.d.cts +5 -0
  71. package/dist/utils/uuid/nil.d.cts.map +1 -0
  72. package/dist/utils/uuid/nil.d.ts +5 -0
  73. package/dist/utils/uuid/nil.d.ts.map +1 -0
  74. package/dist/utils/uuid/nil.js +6 -0
  75. package/dist/utils/uuid/nil.js.map +1 -0
  76. package/dist/utils/uuid/parse.cjs +11 -0
  77. package/dist/utils/uuid/parse.cjs.map +1 -0
  78. package/dist/utils/uuid/parse.d.cts +7 -0
  79. package/dist/utils/uuid/parse.d.cts.map +1 -0
  80. package/dist/utils/uuid/parse.d.ts +7 -0
  81. package/dist/utils/uuid/parse.d.ts.map +1 -0
  82. package/dist/utils/uuid/parse.js +11 -0
  83. package/dist/utils/uuid/parse.js.map +1 -0
  84. package/dist/utils/uuid/regex.cjs +6 -0
  85. package/dist/utils/uuid/regex.cjs.map +1 -0
  86. package/dist/utils/uuid/regex.js +6 -0
  87. package/dist/utils/uuid/regex.js.map +1 -0
  88. package/dist/utils/uuid/rng.cjs +9 -0
  89. package/dist/utils/uuid/rng.cjs.map +1 -0
  90. package/dist/utils/uuid/rng.js +9 -0
  91. package/dist/utils/uuid/rng.js.map +1 -0
  92. package/dist/utils/uuid/sha1.cjs +71 -0
  93. package/dist/utils/uuid/sha1.cjs.map +1 -0
  94. package/dist/utils/uuid/sha1.js +71 -0
  95. package/dist/utils/uuid/sha1.js.map +1 -0
  96. package/dist/utils/uuid/stringify.cjs +21 -0
  97. package/dist/utils/uuid/stringify.cjs.map +1 -0
  98. package/dist/utils/uuid/stringify.d.cts +5 -0
  99. package/dist/utils/uuid/stringify.d.cts.map +1 -0
  100. package/dist/utils/uuid/stringify.d.ts +5 -0
  101. package/dist/utils/uuid/stringify.d.ts.map +1 -0
  102. package/dist/utils/uuid/stringify.js +20 -0
  103. package/dist/utils/uuid/stringify.js.map +1 -0
  104. package/dist/utils/uuid/types.d.cts +26 -0
  105. package/dist/utils/uuid/types.d.cts.map +1 -0
  106. package/dist/utils/uuid/types.d.ts +26 -0
  107. package/dist/utils/uuid/types.d.ts.map +1 -0
  108. package/dist/utils/uuid/v1.cjs +69 -0
  109. package/dist/utils/uuid/v1.cjs.map +1 -0
  110. package/dist/utils/uuid/v1.d.cts +8 -0
  111. package/dist/utils/uuid/v1.d.cts.map +1 -0
  112. package/dist/utils/uuid/v1.d.ts +8 -0
  113. package/dist/utils/uuid/v1.d.ts.map +1 -0
  114. package/dist/utils/uuid/v1.js +69 -0
  115. package/dist/utils/uuid/v1.js.map +1 -0
  116. package/dist/utils/uuid/v35.cjs +36 -0
  117. package/dist/utils/uuid/v35.cjs.map +1 -0
  118. package/dist/utils/uuid/v35.js +34 -0
  119. package/dist/utils/uuid/v35.js.map +1 -0
  120. package/dist/utils/uuid/v4.cjs +25 -0
  121. package/dist/utils/uuid/v4.cjs.map +1 -0
  122. package/dist/utils/uuid/v4.d.cts +8 -0
  123. package/dist/utils/uuid/v4.d.cts.map +1 -0
  124. package/dist/utils/uuid/v4.d.ts +8 -0
  125. package/dist/utils/uuid/v4.d.ts.map +1 -0
  126. package/dist/utils/uuid/v4.js +25 -0
  127. package/dist/utils/uuid/v4.js.map +1 -0
  128. package/dist/utils/uuid/v5.cjs +12 -0
  129. package/dist/utils/uuid/v5.cjs.map +1 -0
  130. package/dist/utils/uuid/v5.d.cts +14 -0
  131. package/dist/utils/uuid/v5.d.cts.map +1 -0
  132. package/dist/utils/uuid/v5.d.ts +14 -0
  133. package/dist/utils/uuid/v5.d.ts.map +1 -0
  134. package/dist/utils/uuid/v5.js +12 -0
  135. package/dist/utils/uuid/v5.js.map +1 -0
  136. package/dist/utils/uuid/v7.cjs +57 -0
  137. package/dist/utils/uuid/v7.cjs.map +1 -0
  138. package/dist/utils/uuid/v7.d.cts +8 -0
  139. package/dist/utils/uuid/v7.d.cts.map +1 -0
  140. package/dist/utils/uuid/v7.d.ts +8 -0
  141. package/dist/utils/uuid/v7.d.ts.map +1 -0
  142. package/dist/utils/uuid/v7.js +57 -0
  143. package/dist/utils/uuid/v7.js.map +1 -0
  144. package/dist/utils/uuid/validate.cjs +9 -0
  145. package/dist/utils/uuid/validate.cjs.map +1 -0
  146. package/dist/utils/uuid/validate.d.cts +5 -0
  147. package/dist/utils/uuid/validate.d.cts.map +1 -0
  148. package/dist/utils/uuid/validate.d.ts +5 -0
  149. package/dist/utils/uuid/validate.d.ts.map +1 -0
  150. package/dist/utils/uuid/validate.js +9 -0
  151. package/dist/utils/uuid/validate.js.map +1 -0
  152. package/dist/utils/uuid/version.cjs +10 -0
  153. package/dist/utils/uuid/version.cjs.map +1 -0
  154. package/dist/utils/uuid/version.d.cts +5 -0
  155. package/dist/utils/uuid/version.d.cts.map +1 -0
  156. package/dist/utils/uuid/version.d.ts +5 -0
  157. package/dist/utils/uuid/version.d.ts.map +1 -0
  158. package/dist/utils/uuid/version.js +10 -0
  159. package/dist/utils/uuid/version.js.map +1 -0
  160. package/package.json +12 -2
  161. package/utils/uuid.cjs +1 -0
  162. package/utils/uuid.d.cts +1 -0
  163. package/utils/uuid.d.ts +1 -0
  164. package/utils/uuid.js +1 -0
@@ -1,13 +1,15 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_validate = require("../utils/uuid/validate.cjs");
4
+ const require_v4 = require("../utils/uuid/v4.cjs");
5
+ require("../utils/uuid/index.cjs");
3
6
  const require_utils = require("./utils.cjs");
4
7
  const require_graph_mermaid = require("./graph_mermaid.cjs");
5
8
  const require_utils_json_schema = require("../utils/json_schema.cjs");
6
- let uuid = require("uuid");
7
9
  //#region src/runnables/graph.ts
8
10
  var graph_exports = /* @__PURE__ */ require_runtime.__exportAll({ Graph: () => Graph });
9
11
  function nodeDataStr(id, data) {
10
- if (id !== void 0 && !(0, uuid.validate)(id)) return id;
12
+ if (id !== void 0 && !require_validate.default(id)) return id;
11
13
  else if (require_utils.isRunnableInterface(data)) try {
12
14
  let dataStr = data.getName();
13
15
  dataStr = dataStr.startsWith("Runnable") ? dataStr.slice(8) : dataStr;
@@ -43,7 +45,7 @@ var Graph = class Graph {
43
45
  toJSON() {
44
46
  const stableNodeIds = {};
45
47
  Object.values(this.nodes).forEach((node, i) => {
46
- stableNodeIds[node.id] = (0, uuid.validate)(node.id) ? i : node.id;
48
+ stableNodeIds[node.id] = require_validate.default(node.id) ? i : node.id;
47
49
  });
48
50
  return {
49
51
  nodes: Object.values(this.nodes).map((node) => ({
@@ -63,7 +65,7 @@ var Graph = class Graph {
63
65
  }
64
66
  addNode(data, id, metadata) {
65
67
  if (id !== void 0 && this.nodes[id] !== void 0) throw new Error(`Node with id ${id} already exists`);
66
- const nodeId = id ?? (0, uuid.v4)();
68
+ const nodeId = id ?? require_v4.default();
67
69
  const node = {
68
70
  id: nodeId,
69
71
  data,
@@ -101,7 +103,7 @@ var Graph = class Graph {
101
103
  */
102
104
  extend(graph, prefix = "") {
103
105
  let finalPrefix = prefix;
104
- if (Object.values(graph.nodes).map((node) => node.id).every(uuid.validate)) finalPrefix = "";
106
+ if (Object.values(graph.nodes).map((node) => node.id).every(require_validate.default)) finalPrefix = "";
105
107
  const prefixed = (id) => {
106
108
  return finalPrefix ? `${finalPrefix}:${id}` : id;
107
109
  };
@@ -149,7 +151,7 @@ var Graph = class Graph {
149
151
  });
150
152
  const getNodeId = (nodeId) => {
151
153
  const label = nodeLabels[nodeId];
152
- if ((0, uuid.validate)(nodeId) && nodeLabelCounts.get(label) === 1) return label;
154
+ if (require_validate.default(nodeId) && nodeLabelCounts.get(label) === 1) return label;
153
155
  else return nodeId;
154
156
  };
155
157
  return new Graph({
@@ -1 +1 @@
1
- {"version":3,"file":"graph.cjs","names":["isRunnableInterface","toJsonSchema","isUuid","drawMermaid","drawMermaidImage"],"sources":["../../src/runnables/graph.ts"],"sourcesContent":["import { v4 as uuidv4, validate as isUuid } from \"uuid\";\nimport type {\n RunnableInterface,\n RunnableIOSchema,\n Node,\n Edge,\n} from \"./types.js\";\nimport { isRunnableInterface } from \"./utils.js\";\nimport { drawMermaid, drawMermaidImage } from \"./graph_mermaid.js\";\nimport { toJsonSchema } from \"../utils/json_schema.js\";\n\nexport { Node, Edge };\n\nfunction nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n}\n\nfunction nodeDataJson(node: Node) {\n // if node.data implements Runnable\n if (isRunnableInterface(node.data)) {\n return {\n type: \"runnable\",\n data: {\n id: node.data.lc_id,\n name: node.data.getName(),\n },\n };\n } else {\n return {\n type: \"schema\",\n data: { ...toJsonSchema(node.data.schema), title: node.data.name },\n };\n }\n}\n\nexport class Graph {\n nodes: Record<string, Node> = {};\n\n edges: Edge[] = [];\n\n constructor(params?: { nodes: Record<string, Node>; edges: Edge[] }) {\n this.nodes = params?.nodes ?? this.nodes;\n this.edges = params?.edges ?? this.edges;\n }\n\n // Convert the graph to a JSON-serializable format.\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n toJSON(): Record<string, any> {\n const stableNodeIds: Record<string, string | number> = {};\n Object.values(this.nodes).forEach((node, i) => {\n stableNodeIds[node.id] = isUuid(node.id) ? i : node.id;\n });\n\n return {\n nodes: Object.values(this.nodes).map((node) => ({\n id: stableNodeIds[node.id],\n ...nodeDataJson(node),\n })),\n edges: this.edges.map((edge) => {\n const item: Record<string, unknown> = {\n source: stableNodeIds[edge.source],\n target: stableNodeIds[edge.target],\n };\n\n if (typeof edge.data !== \"undefined\") {\n item.data = edge.data;\n }\n\n if (typeof edge.conditional !== \"undefined\") {\n item.conditional = edge.conditional;\n }\n return item;\n }),\n };\n }\n\n addNode(\n data: RunnableInterface | RunnableIOSchema,\n id?: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n metadata?: Record<string, any>\n ): Node {\n if (id !== undefined && this.nodes[id] !== undefined) {\n throw new Error(`Node with id ${id} already exists`);\n }\n const nodeId = id ?? uuidv4();\n const node: Node = {\n id: nodeId,\n data,\n name: nodeDataStr(id, data),\n metadata,\n };\n this.nodes[nodeId] = node;\n return node;\n }\n\n removeNode(node: Node): void {\n // Remove the node from the nodes map\n delete this.nodes[node.id];\n\n // Filter out edges connected to the node\n this.edges = this.edges.filter(\n (edge) => edge.source !== node.id && edge.target !== node.id\n );\n }\n\n addEdge(\n source: Node,\n target: Node,\n data?: string,\n conditional?: boolean\n ): Edge {\n if (this.nodes[source.id] === undefined) {\n throw new Error(`Source node ${source.id} not in graph`);\n }\n if (this.nodes[target.id] === undefined) {\n throw new Error(`Target node ${target.id} not in graph`);\n }\n const edge: Edge = {\n source: source.id,\n target: target.id,\n data,\n conditional,\n };\n this.edges.push(edge);\n return edge;\n }\n\n firstNode(): Node | undefined {\n return _firstNode(this);\n }\n\n lastNode(): Node | undefined {\n return _lastNode(this);\n }\n\n /**\n * Add all nodes and edges from another graph.\n * Note this doesn't check for duplicates, nor does it connect the graphs.\n */\n extend(graph: Graph, prefix = \"\") {\n let finalPrefix = prefix;\n const nodeIds = Object.values(graph.nodes).map((node) => node.id);\n if (nodeIds.every(isUuid)) {\n finalPrefix = \"\";\n }\n\n const prefixed = (id: string) => {\n return finalPrefix ? `${finalPrefix}:${id}` : id;\n };\n\n Object.entries(graph.nodes).forEach(([key, value]) => {\n this.nodes[prefixed(key)] = { ...value, id: prefixed(key) };\n });\n\n const newEdges = graph.edges.map((edge) => {\n return {\n ...edge,\n source: prefixed(edge.source),\n target: prefixed(edge.target),\n };\n });\n // Add all edges from the other graph\n this.edges = [...this.edges, ...newEdges];\n const first = graph.firstNode();\n const last = graph.lastNode();\n return [\n first ? { id: prefixed(first.id), data: first.data } : undefined,\n last ? { id: prefixed(last.id), data: last.data } : undefined,\n ];\n }\n\n trimFirstNode(): void {\n const firstNode = this.firstNode();\n if (firstNode && _firstNode(this, [firstNode.id])) {\n this.removeNode(firstNode);\n }\n }\n\n trimLastNode(): void {\n const lastNode = this.lastNode();\n if (lastNode && _lastNode(this, [lastNode.id])) {\n this.removeNode(lastNode);\n }\n }\n\n /**\n * Return a new graph with all nodes re-identified,\n * using their unique, readable names where possible.\n */\n reid(): Graph {\n const nodeLabels: Record<string, string> = Object.fromEntries(\n Object.values(this.nodes).map((node) => [node.id, node.name])\n );\n const nodeLabelCounts = new Map<string, number>();\n Object.values(nodeLabels).forEach((label) => {\n nodeLabelCounts.set(label, (nodeLabelCounts.get(label) || 0) + 1);\n });\n\n const getNodeId = (nodeId: string): string => {\n const label = nodeLabels[nodeId];\n if (isUuid(nodeId) && nodeLabelCounts.get(label) === 1) {\n return label;\n } else {\n return nodeId;\n }\n };\n\n return new Graph({\n nodes: Object.fromEntries(\n Object.entries(this.nodes).map(([id, node]) => [\n getNodeId(id),\n { ...node, id: getNodeId(id) },\n ])\n ),\n edges: this.edges.map((edge) => ({\n ...edge,\n source: getNodeId(edge.source),\n target: getNodeId(edge.target),\n })),\n });\n }\n\n drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }): string {\n const {\n withStyles,\n curveStyle,\n nodeColors = {\n default: \"fill:#f2f0ff,line-height:1.2\",\n first: \"fill-opacity:0\",\n last: \"fill:#bfb6fc\",\n },\n wrapLabelNWords,\n } = params ?? {};\n const graph = this.reid();\n const firstNode = graph.firstNode();\n\n const lastNode = graph.lastNode();\n\n return drawMermaid(graph.nodes, graph.edges, {\n firstNode: firstNode?.id,\n lastNode: lastNode?.id,\n withStyles,\n curveStyle,\n nodeColors,\n wrapLabelNWords,\n });\n }\n\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }): Promise<Blob> {\n const mermaidSyntax = this.drawMermaid(params);\n return drawMermaidImage(mermaidSyntax, {\n backgroundColor: params?.backgroundColor,\n });\n }\n}\n/**\n * Find the single node that is not a target of any edge.\n * Exclude nodes/sources with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the origin.\n */\nfunction _firstNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const targets = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.source))\n .map((edge) => edge.target)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !targets.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n\n/**\n * Find the single node that is not a source of any edge.\n * Exclude nodes/targets with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the destination.\n */\nfunction _lastNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const sources = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.target))\n .map((edge) => edge.source)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !sources.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"graph.cjs","names":["isUuid","isRunnableInterface","toJsonSchema","uuidv4","drawMermaid","drawMermaidImage"],"sources":["../../src/runnables/graph.ts"],"sourcesContent":["import { v4 as uuidv4, validate as isUuid } from \"../utils/uuid/index.js\";\nimport type {\n RunnableInterface,\n RunnableIOSchema,\n Node,\n Edge,\n} from \"./types.js\";\nimport { isRunnableInterface } from \"./utils.js\";\nimport { drawMermaid, drawMermaidImage } from \"./graph_mermaid.js\";\nimport { toJsonSchema } from \"../utils/json_schema.js\";\n\nexport { Node, Edge };\n\nfunction nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n}\n\nfunction nodeDataJson(node: Node) {\n // if node.data implements Runnable\n if (isRunnableInterface(node.data)) {\n return {\n type: \"runnable\",\n data: {\n id: node.data.lc_id,\n name: node.data.getName(),\n },\n };\n } else {\n return {\n type: \"schema\",\n data: { ...toJsonSchema(node.data.schema), title: node.data.name },\n };\n }\n}\n\nexport class Graph {\n nodes: Record<string, Node> = {};\n\n edges: Edge[] = [];\n\n constructor(params?: { nodes: Record<string, Node>; edges: Edge[] }) {\n this.nodes = params?.nodes ?? this.nodes;\n this.edges = params?.edges ?? this.edges;\n }\n\n // Convert the graph to a JSON-serializable format.\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n toJSON(): Record<string, any> {\n const stableNodeIds: Record<string, string | number> = {};\n Object.values(this.nodes).forEach((node, i) => {\n stableNodeIds[node.id] = isUuid(node.id) ? i : node.id;\n });\n\n return {\n nodes: Object.values(this.nodes).map((node) => ({\n id: stableNodeIds[node.id],\n ...nodeDataJson(node),\n })),\n edges: this.edges.map((edge) => {\n const item: Record<string, unknown> = {\n source: stableNodeIds[edge.source],\n target: stableNodeIds[edge.target],\n };\n\n if (typeof edge.data !== \"undefined\") {\n item.data = edge.data;\n }\n\n if (typeof edge.conditional !== \"undefined\") {\n item.conditional = edge.conditional;\n }\n return item;\n }),\n };\n }\n\n addNode(\n data: RunnableInterface | RunnableIOSchema,\n id?: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n metadata?: Record<string, any>\n ): Node {\n if (id !== undefined && this.nodes[id] !== undefined) {\n throw new Error(`Node with id ${id} already exists`);\n }\n const nodeId = id ?? uuidv4();\n const node: Node = {\n id: nodeId,\n data,\n name: nodeDataStr(id, data),\n metadata,\n };\n this.nodes[nodeId] = node;\n return node;\n }\n\n removeNode(node: Node): void {\n // Remove the node from the nodes map\n delete this.nodes[node.id];\n\n // Filter out edges connected to the node\n this.edges = this.edges.filter(\n (edge) => edge.source !== node.id && edge.target !== node.id\n );\n }\n\n addEdge(\n source: Node,\n target: Node,\n data?: string,\n conditional?: boolean\n ): Edge {\n if (this.nodes[source.id] === undefined) {\n throw new Error(`Source node ${source.id} not in graph`);\n }\n if (this.nodes[target.id] === undefined) {\n throw new Error(`Target node ${target.id} not in graph`);\n }\n const edge: Edge = {\n source: source.id,\n target: target.id,\n data,\n conditional,\n };\n this.edges.push(edge);\n return edge;\n }\n\n firstNode(): Node | undefined {\n return _firstNode(this);\n }\n\n lastNode(): Node | undefined {\n return _lastNode(this);\n }\n\n /**\n * Add all nodes and edges from another graph.\n * Note this doesn't check for duplicates, nor does it connect the graphs.\n */\n extend(graph: Graph, prefix = \"\") {\n let finalPrefix = prefix;\n const nodeIds = Object.values(graph.nodes).map((node) => node.id);\n if (nodeIds.every(isUuid)) {\n finalPrefix = \"\";\n }\n\n const prefixed = (id: string) => {\n return finalPrefix ? `${finalPrefix}:${id}` : id;\n };\n\n Object.entries(graph.nodes).forEach(([key, value]) => {\n this.nodes[prefixed(key)] = { ...value, id: prefixed(key) };\n });\n\n const newEdges = graph.edges.map((edge) => {\n return {\n ...edge,\n source: prefixed(edge.source),\n target: prefixed(edge.target),\n };\n });\n // Add all edges from the other graph\n this.edges = [...this.edges, ...newEdges];\n const first = graph.firstNode();\n const last = graph.lastNode();\n return [\n first ? { id: prefixed(first.id), data: first.data } : undefined,\n last ? { id: prefixed(last.id), data: last.data } : undefined,\n ];\n }\n\n trimFirstNode(): void {\n const firstNode = this.firstNode();\n if (firstNode && _firstNode(this, [firstNode.id])) {\n this.removeNode(firstNode);\n }\n }\n\n trimLastNode(): void {\n const lastNode = this.lastNode();\n if (lastNode && _lastNode(this, [lastNode.id])) {\n this.removeNode(lastNode);\n }\n }\n\n /**\n * Return a new graph with all nodes re-identified,\n * using their unique, readable names where possible.\n */\n reid(): Graph {\n const nodeLabels: Record<string, string> = Object.fromEntries(\n Object.values(this.nodes).map((node) => [node.id, node.name])\n );\n const nodeLabelCounts = new Map<string, number>();\n Object.values(nodeLabels).forEach((label) => {\n nodeLabelCounts.set(label, (nodeLabelCounts.get(label) || 0) + 1);\n });\n\n const getNodeId = (nodeId: string): string => {\n const label = nodeLabels[nodeId];\n if (isUuid(nodeId) && nodeLabelCounts.get(label) === 1) {\n return label;\n } else {\n return nodeId;\n }\n };\n\n return new Graph({\n nodes: Object.fromEntries(\n Object.entries(this.nodes).map(([id, node]) => [\n getNodeId(id),\n { ...node, id: getNodeId(id) },\n ])\n ),\n edges: this.edges.map((edge) => ({\n ...edge,\n source: getNodeId(edge.source),\n target: getNodeId(edge.target),\n })),\n });\n }\n\n drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }): string {\n const {\n withStyles,\n curveStyle,\n nodeColors = {\n default: \"fill:#f2f0ff,line-height:1.2\",\n first: \"fill-opacity:0\",\n last: \"fill:#bfb6fc\",\n },\n wrapLabelNWords,\n } = params ?? {};\n const graph = this.reid();\n const firstNode = graph.firstNode();\n\n const lastNode = graph.lastNode();\n\n return drawMermaid(graph.nodes, graph.edges, {\n firstNode: firstNode?.id,\n lastNode: lastNode?.id,\n withStyles,\n curveStyle,\n nodeColors,\n wrapLabelNWords,\n });\n }\n\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }): Promise<Blob> {\n const mermaidSyntax = this.drawMermaid(params);\n return drawMermaidImage(mermaidSyntax, {\n backgroundColor: params?.backgroundColor,\n });\n }\n}\n/**\n * Find the single node that is not a target of any edge.\n * Exclude nodes/sources with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the origin.\n */\nfunction _firstNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const targets = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.source))\n .map((edge) => edge.target)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !targets.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n\n/**\n * Find the single node that is not a source of any edge.\n * Exclude nodes/targets with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the destination.\n */\nfunction _lastNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const sources = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.target))\n .map((edge) => edge.source)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !sources.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n"],"mappings":"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"}
@@ -1,8 +1,10 @@
1
1
  import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
+ import validate from "../utils/uuid/validate.js";
3
+ import v4 from "../utils/uuid/v4.js";
4
+ import "../utils/uuid/index.js";
2
5
  import { isRunnableInterface } from "./utils.js";
3
6
  import { drawMermaid, drawMermaidImage } from "./graph_mermaid.js";
4
7
  import { toJsonSchema } from "../utils/json_schema.js";
5
- import { v4, validate } from "uuid";
6
8
  //#region src/runnables/graph.ts
7
9
  var graph_exports = /* @__PURE__ */ __exportAll({ Graph: () => Graph });
8
10
  function nodeDataStr(id, data) {
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","names":["isUuid","uuidv4"],"sources":["../../src/runnables/graph.ts"],"sourcesContent":["import { v4 as uuidv4, validate as isUuid } from \"uuid\";\nimport type {\n RunnableInterface,\n RunnableIOSchema,\n Node,\n Edge,\n} from \"./types.js\";\nimport { isRunnableInterface } from \"./utils.js\";\nimport { drawMermaid, drawMermaidImage } from \"./graph_mermaid.js\";\nimport { toJsonSchema } from \"../utils/json_schema.js\";\n\nexport { Node, Edge };\n\nfunction nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n}\n\nfunction nodeDataJson(node: Node) {\n // if node.data implements Runnable\n if (isRunnableInterface(node.data)) {\n return {\n type: \"runnable\",\n data: {\n id: node.data.lc_id,\n name: node.data.getName(),\n },\n };\n } else {\n return {\n type: \"schema\",\n data: { ...toJsonSchema(node.data.schema), title: node.data.name },\n };\n }\n}\n\nexport class Graph {\n nodes: Record<string, Node> = {};\n\n edges: Edge[] = [];\n\n constructor(params?: { nodes: Record<string, Node>; edges: Edge[] }) {\n this.nodes = params?.nodes ?? this.nodes;\n this.edges = params?.edges ?? this.edges;\n }\n\n // Convert the graph to a JSON-serializable format.\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n toJSON(): Record<string, any> {\n const stableNodeIds: Record<string, string | number> = {};\n Object.values(this.nodes).forEach((node, i) => {\n stableNodeIds[node.id] = isUuid(node.id) ? i : node.id;\n });\n\n return {\n nodes: Object.values(this.nodes).map((node) => ({\n id: stableNodeIds[node.id],\n ...nodeDataJson(node),\n })),\n edges: this.edges.map((edge) => {\n const item: Record<string, unknown> = {\n source: stableNodeIds[edge.source],\n target: stableNodeIds[edge.target],\n };\n\n if (typeof edge.data !== \"undefined\") {\n item.data = edge.data;\n }\n\n if (typeof edge.conditional !== \"undefined\") {\n item.conditional = edge.conditional;\n }\n return item;\n }),\n };\n }\n\n addNode(\n data: RunnableInterface | RunnableIOSchema,\n id?: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n metadata?: Record<string, any>\n ): Node {\n if (id !== undefined && this.nodes[id] !== undefined) {\n throw new Error(`Node with id ${id} already exists`);\n }\n const nodeId = id ?? uuidv4();\n const node: Node = {\n id: nodeId,\n data,\n name: nodeDataStr(id, data),\n metadata,\n };\n this.nodes[nodeId] = node;\n return node;\n }\n\n removeNode(node: Node): void {\n // Remove the node from the nodes map\n delete this.nodes[node.id];\n\n // Filter out edges connected to the node\n this.edges = this.edges.filter(\n (edge) => edge.source !== node.id && edge.target !== node.id\n );\n }\n\n addEdge(\n source: Node,\n target: Node,\n data?: string,\n conditional?: boolean\n ): Edge {\n if (this.nodes[source.id] === undefined) {\n throw new Error(`Source node ${source.id} not in graph`);\n }\n if (this.nodes[target.id] === undefined) {\n throw new Error(`Target node ${target.id} not in graph`);\n }\n const edge: Edge = {\n source: source.id,\n target: target.id,\n data,\n conditional,\n };\n this.edges.push(edge);\n return edge;\n }\n\n firstNode(): Node | undefined {\n return _firstNode(this);\n }\n\n lastNode(): Node | undefined {\n return _lastNode(this);\n }\n\n /**\n * Add all nodes and edges from another graph.\n * Note this doesn't check for duplicates, nor does it connect the graphs.\n */\n extend(graph: Graph, prefix = \"\") {\n let finalPrefix = prefix;\n const nodeIds = Object.values(graph.nodes).map((node) => node.id);\n if (nodeIds.every(isUuid)) {\n finalPrefix = \"\";\n }\n\n const prefixed = (id: string) => {\n return finalPrefix ? `${finalPrefix}:${id}` : id;\n };\n\n Object.entries(graph.nodes).forEach(([key, value]) => {\n this.nodes[prefixed(key)] = { ...value, id: prefixed(key) };\n });\n\n const newEdges = graph.edges.map((edge) => {\n return {\n ...edge,\n source: prefixed(edge.source),\n target: prefixed(edge.target),\n };\n });\n // Add all edges from the other graph\n this.edges = [...this.edges, ...newEdges];\n const first = graph.firstNode();\n const last = graph.lastNode();\n return [\n first ? { id: prefixed(first.id), data: first.data } : undefined,\n last ? { id: prefixed(last.id), data: last.data } : undefined,\n ];\n }\n\n trimFirstNode(): void {\n const firstNode = this.firstNode();\n if (firstNode && _firstNode(this, [firstNode.id])) {\n this.removeNode(firstNode);\n }\n }\n\n trimLastNode(): void {\n const lastNode = this.lastNode();\n if (lastNode && _lastNode(this, [lastNode.id])) {\n this.removeNode(lastNode);\n }\n }\n\n /**\n * Return a new graph with all nodes re-identified,\n * using their unique, readable names where possible.\n */\n reid(): Graph {\n const nodeLabels: Record<string, string> = Object.fromEntries(\n Object.values(this.nodes).map((node) => [node.id, node.name])\n );\n const nodeLabelCounts = new Map<string, number>();\n Object.values(nodeLabels).forEach((label) => {\n nodeLabelCounts.set(label, (nodeLabelCounts.get(label) || 0) + 1);\n });\n\n const getNodeId = (nodeId: string): string => {\n const label = nodeLabels[nodeId];\n if (isUuid(nodeId) && nodeLabelCounts.get(label) === 1) {\n return label;\n } else {\n return nodeId;\n }\n };\n\n return new Graph({\n nodes: Object.fromEntries(\n Object.entries(this.nodes).map(([id, node]) => [\n getNodeId(id),\n { ...node, id: getNodeId(id) },\n ])\n ),\n edges: this.edges.map((edge) => ({\n ...edge,\n source: getNodeId(edge.source),\n target: getNodeId(edge.target),\n })),\n });\n }\n\n drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }): string {\n const {\n withStyles,\n curveStyle,\n nodeColors = {\n default: \"fill:#f2f0ff,line-height:1.2\",\n first: \"fill-opacity:0\",\n last: \"fill:#bfb6fc\",\n },\n wrapLabelNWords,\n } = params ?? {};\n const graph = this.reid();\n const firstNode = graph.firstNode();\n\n const lastNode = graph.lastNode();\n\n return drawMermaid(graph.nodes, graph.edges, {\n firstNode: firstNode?.id,\n lastNode: lastNode?.id,\n withStyles,\n curveStyle,\n nodeColors,\n wrapLabelNWords,\n });\n }\n\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }): Promise<Blob> {\n const mermaidSyntax = this.drawMermaid(params);\n return drawMermaidImage(mermaidSyntax, {\n backgroundColor: params?.backgroundColor,\n });\n }\n}\n/**\n * Find the single node that is not a target of any edge.\n * Exclude nodes/sources with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the origin.\n */\nfunction _firstNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const targets = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.source))\n .map((edge) => edge.target)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !targets.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n\n/**\n * Find the single node that is not a source of any edge.\n * Exclude nodes/targets with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the destination.\n */\nfunction _lastNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const sources = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.target))\n .map((edge) => edge.source)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !sources.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","names":["isUuid","uuidv4"],"sources":["../../src/runnables/graph.ts"],"sourcesContent":["import { v4 as uuidv4, validate as isUuid } from \"../utils/uuid/index.js\";\nimport type {\n RunnableInterface,\n RunnableIOSchema,\n Node,\n Edge,\n} from \"./types.js\";\nimport { isRunnableInterface } from \"./utils.js\";\nimport { drawMermaid, drawMermaidImage } from \"./graph_mermaid.js\";\nimport { toJsonSchema } from \"../utils/json_schema.js\";\n\nexport { Node, Edge };\n\nfunction nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n}\n\nfunction nodeDataJson(node: Node) {\n // if node.data implements Runnable\n if (isRunnableInterface(node.data)) {\n return {\n type: \"runnable\",\n data: {\n id: node.data.lc_id,\n name: node.data.getName(),\n },\n };\n } else {\n return {\n type: \"schema\",\n data: { ...toJsonSchema(node.data.schema), title: node.data.name },\n };\n }\n}\n\nexport class Graph {\n nodes: Record<string, Node> = {};\n\n edges: Edge[] = [];\n\n constructor(params?: { nodes: Record<string, Node>; edges: Edge[] }) {\n this.nodes = params?.nodes ?? this.nodes;\n this.edges = params?.edges ?? this.edges;\n }\n\n // Convert the graph to a JSON-serializable format.\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n toJSON(): Record<string, any> {\n const stableNodeIds: Record<string, string | number> = {};\n Object.values(this.nodes).forEach((node, i) => {\n stableNodeIds[node.id] = isUuid(node.id) ? i : node.id;\n });\n\n return {\n nodes: Object.values(this.nodes).map((node) => ({\n id: stableNodeIds[node.id],\n ...nodeDataJson(node),\n })),\n edges: this.edges.map((edge) => {\n const item: Record<string, unknown> = {\n source: stableNodeIds[edge.source],\n target: stableNodeIds[edge.target],\n };\n\n if (typeof edge.data !== \"undefined\") {\n item.data = edge.data;\n }\n\n if (typeof edge.conditional !== \"undefined\") {\n item.conditional = edge.conditional;\n }\n return item;\n }),\n };\n }\n\n addNode(\n data: RunnableInterface | RunnableIOSchema,\n id?: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n metadata?: Record<string, any>\n ): Node {\n if (id !== undefined && this.nodes[id] !== undefined) {\n throw new Error(`Node with id ${id} already exists`);\n }\n const nodeId = id ?? uuidv4();\n const node: Node = {\n id: nodeId,\n data,\n name: nodeDataStr(id, data),\n metadata,\n };\n this.nodes[nodeId] = node;\n return node;\n }\n\n removeNode(node: Node): void {\n // Remove the node from the nodes map\n delete this.nodes[node.id];\n\n // Filter out edges connected to the node\n this.edges = this.edges.filter(\n (edge) => edge.source !== node.id && edge.target !== node.id\n );\n }\n\n addEdge(\n source: Node,\n target: Node,\n data?: string,\n conditional?: boolean\n ): Edge {\n if (this.nodes[source.id] === undefined) {\n throw new Error(`Source node ${source.id} not in graph`);\n }\n if (this.nodes[target.id] === undefined) {\n throw new Error(`Target node ${target.id} not in graph`);\n }\n const edge: Edge = {\n source: source.id,\n target: target.id,\n data,\n conditional,\n };\n this.edges.push(edge);\n return edge;\n }\n\n firstNode(): Node | undefined {\n return _firstNode(this);\n }\n\n lastNode(): Node | undefined {\n return _lastNode(this);\n }\n\n /**\n * Add all nodes and edges from another graph.\n * Note this doesn't check for duplicates, nor does it connect the graphs.\n */\n extend(graph: Graph, prefix = \"\") {\n let finalPrefix = prefix;\n const nodeIds = Object.values(graph.nodes).map((node) => node.id);\n if (nodeIds.every(isUuid)) {\n finalPrefix = \"\";\n }\n\n const prefixed = (id: string) => {\n return finalPrefix ? `${finalPrefix}:${id}` : id;\n };\n\n Object.entries(graph.nodes).forEach(([key, value]) => {\n this.nodes[prefixed(key)] = { ...value, id: prefixed(key) };\n });\n\n const newEdges = graph.edges.map((edge) => {\n return {\n ...edge,\n source: prefixed(edge.source),\n target: prefixed(edge.target),\n };\n });\n // Add all edges from the other graph\n this.edges = [...this.edges, ...newEdges];\n const first = graph.firstNode();\n const last = graph.lastNode();\n return [\n first ? { id: prefixed(first.id), data: first.data } : undefined,\n last ? { id: prefixed(last.id), data: last.data } : undefined,\n ];\n }\n\n trimFirstNode(): void {\n const firstNode = this.firstNode();\n if (firstNode && _firstNode(this, [firstNode.id])) {\n this.removeNode(firstNode);\n }\n }\n\n trimLastNode(): void {\n const lastNode = this.lastNode();\n if (lastNode && _lastNode(this, [lastNode.id])) {\n this.removeNode(lastNode);\n }\n }\n\n /**\n * Return a new graph with all nodes re-identified,\n * using their unique, readable names where possible.\n */\n reid(): Graph {\n const nodeLabels: Record<string, string> = Object.fromEntries(\n Object.values(this.nodes).map((node) => [node.id, node.name])\n );\n const nodeLabelCounts = new Map<string, number>();\n Object.values(nodeLabels).forEach((label) => {\n nodeLabelCounts.set(label, (nodeLabelCounts.get(label) || 0) + 1);\n });\n\n const getNodeId = (nodeId: string): string => {\n const label = nodeLabels[nodeId];\n if (isUuid(nodeId) && nodeLabelCounts.get(label) === 1) {\n return label;\n } else {\n return nodeId;\n }\n };\n\n return new Graph({\n nodes: Object.fromEntries(\n Object.entries(this.nodes).map(([id, node]) => [\n getNodeId(id),\n { ...node, id: getNodeId(id) },\n ])\n ),\n edges: this.edges.map((edge) => ({\n ...edge,\n source: getNodeId(edge.source),\n target: getNodeId(edge.target),\n })),\n });\n }\n\n drawMermaid(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }): string {\n const {\n withStyles,\n curveStyle,\n nodeColors = {\n default: \"fill:#f2f0ff,line-height:1.2\",\n first: \"fill-opacity:0\",\n last: \"fill:#bfb6fc\",\n },\n wrapLabelNWords,\n } = params ?? {};\n const graph = this.reid();\n const firstNode = graph.firstNode();\n\n const lastNode = graph.lastNode();\n\n return drawMermaid(graph.nodes, graph.edges, {\n firstNode: firstNode?.id,\n lastNode: lastNode?.id,\n withStyles,\n curveStyle,\n nodeColors,\n wrapLabelNWords,\n });\n }\n\n async drawMermaidPng(params?: {\n withStyles?: boolean;\n curveStyle?: string;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n backgroundColor?: string;\n }): Promise<Blob> {\n const mermaidSyntax = this.drawMermaid(params);\n return drawMermaidImage(mermaidSyntax, {\n backgroundColor: params?.backgroundColor,\n });\n }\n}\n/**\n * Find the single node that is not a target of any edge.\n * Exclude nodes/sources with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the origin.\n */\nfunction _firstNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const targets = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.source))\n .map((edge) => edge.target)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !targets.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n\n/**\n * Find the single node that is not a source of any edge.\n * Exclude nodes/targets with ids in the exclude list.\n * If there is no such node, or there are multiple, return undefined.\n * When drawing the graph, this node would be the destination.\n */\nfunction _lastNode(graph: Graph, exclude: string[] = []): Node | undefined {\n const sources = new Set(\n graph.edges\n .filter((edge) => !exclude.includes(edge.target))\n .map((edge) => edge.source)\n );\n\n const found: Node[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (!exclude.includes(node.id) && !sources.has(node.id)) {\n found.push(node);\n }\n }\n return found.length === 1 ? found[0] : undefined;\n}\n"],"mappings":"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"}
@@ -8,7 +8,22 @@ let langsmith_run_trees = require("langsmith/run_trees");
8
8
  let langsmith = require("langsmith");
9
9
  let langsmith_singletons_traceable = require("langsmith/singletons/traceable");
10
10
  //#region src/tracers/tracer_langchain.ts
11
- var tracer_langchain_exports = /* @__PURE__ */ require_runtime.__exportAll({ LangChainTracer: () => LangChainTracer });
11
+ var tracer_langchain_exports = /* @__PURE__ */ require_runtime.__exportAll({
12
+ LangChainTracer: () => LangChainTracer,
13
+ OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS: () => OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS
14
+ });
15
+ /**
16
+ * Keys that should be inherited from `tracerInheritableMetadata` even when
17
+ * the run already has a value for them. This lets nested contexts
18
+ * (e.g. a subagent invoked from inside a parent agent) override a
19
+ * LangSmith-only tracing metadata value that was set by an ancestor.
20
+ *
21
+ * Keep this list very small: every key here loses the default
22
+ * "first wins" protection and is always clobbered by the nearest
23
+ * enclosing tracer config. Only keys that are strictly for LangSmith
24
+ * tracing bookkeeping should be added.
25
+ */
26
+ const OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS = new Set(["ls_agent_type"]);
12
27
  /**
13
28
  * Extract usage_metadata from chat generations.
14
29
  *
@@ -71,7 +86,7 @@ var LangChainTracer = class LangChainTracer extends require_tracers_base.BaseTra
71
86
  else if (this.tracingMetadata === void 0) mergedMetadata = { ...metadata };
72
87
  else {
73
88
  mergedMetadata = { ...this.tracingMetadata };
74
- for (const [key, value] of Object.entries(metadata)) if (!Object.prototype.hasOwnProperty.call(mergedMetadata, key)) mergedMetadata[key] = value;
89
+ for (const [key, value] of Object.entries(metadata)) if (!Object.prototype.hasOwnProperty.call(mergedMetadata, key) || OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)) mergedMetadata[key] = value;
75
90
  }
76
91
  const mergedTags = tags ? Array.from(new Set([...this.tracingTags, ...tags])) : [...this.tracingTags];
77
92
  const copied = new LangChainTracer({
@@ -147,9 +162,11 @@ function _patchMissingTracingDefaults(tracer, run) {
147
162
  run.extra ??= {};
148
163
  const metadata = run.extra.metadata ?? {};
149
164
  let didPatchMetadata = false;
150
- for (const [key, value] of Object.entries(tracer.tracingMetadata)) if (!Object.prototype.hasOwnProperty.call(metadata, key)) {
151
- metadata[key] = value;
152
- didPatchMetadata = true;
165
+ for (const [key, value] of Object.entries(tracer.tracingMetadata)) if (!Object.prototype.hasOwnProperty.call(metadata, key) || OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)) {
166
+ if (metadata[key] !== value) {
167
+ metadata[key] = value;
168
+ didPatchMetadata = true;
169
+ }
153
170
  }
154
171
  if (didPatchMetadata) run.extra.metadata = metadata;
155
172
  }
@@ -157,6 +174,7 @@ function _patchMissingTracingDefaults(tracer, run) {
157
174
  }
158
175
  //#endregion
159
176
  exports.LangChainTracer = LangChainTracer;
177
+ exports.OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS = OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS;
160
178
  Object.defineProperty(exports, "tracer_langchain_exports", {
161
179
  enumerable: true,
162
180
  get: function() {
@@ -1 +1 @@
1
- {"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 metadata?: Record<string, unknown>;\n tags?: string[];\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 tracingMetadata?: Record<string, unknown>;\n\n tracingTags: string[] = [];\n\n constructor(protected fields: LangChainTracerFields = {}) {\n super(fields);\n const { exampleId, projectName, client, replicas, metadata, tags } = fields;\n\n this.projectName = projectName ?? getDefaultProjectName();\n this.replicas = replicas;\n this.exampleId = exampleId;\n this.client = client ?? getDefaultLangChainClientSingleton();\n this.tracingMetadata = metadata ? { ...metadata } : undefined;\n this.tracingTags = tags ?? [];\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 _patchMissingTracingDefaults(this, run);\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 _patchMissingTracingDefaults(this, run);\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 copyWithTracingConfig({\n metadata,\n tags,\n }: {\n metadata?: Record<string, unknown>;\n tags?: string[];\n }): LangChainTracer {\n let mergedMetadata: Record<string, unknown> | undefined;\n if (metadata === undefined) {\n mergedMetadata = this.tracingMetadata\n ? { ...this.tracingMetadata }\n : undefined;\n } else if (this.tracingMetadata === undefined) {\n mergedMetadata = { ...metadata };\n } else {\n mergedMetadata = { ...this.tracingMetadata };\n for (const [key, value] of Object.entries(metadata)) {\n if (!Object.prototype.hasOwnProperty.call(mergedMetadata, key)) {\n mergedMetadata[key] = value;\n }\n }\n }\n\n const mergedTags = tags\n ? Array.from(new Set([...this.tracingTags, ...tags]))\n : [...this.tracingTags];\n\n const copied = new LangChainTracer({\n ...this.fields,\n metadata: mergedMetadata,\n tags: mergedTags,\n });\n copied.runMap = this.runMap;\n copied.runTreeMap = this.runTreeMap;\n return copied;\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 this.fields = {\n ...this.fields,\n client: this.client,\n replicas: this.replicas,\n projectName: this.projectName,\n exampleId: this.exampleId,\n };\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 static [Symbol.hasInstance](instance: unknown): boolean {\n if (typeof instance !== \"object\" || instance === null) {\n return false;\n }\n const candidate = instance as Record<string, unknown>;\n return (\n \"name\" in candidate &&\n candidate.name === \"langchain_tracer\" &&\n \"copyWithTracingConfig\" in candidate &&\n typeof candidate.copyWithTracingConfig === \"function\" &&\n \"getRunTreeWithTracingConfig\" in candidate &&\n typeof candidate.getRunTreeWithTracingConfig === \"function\"\n );\n }\n}\n\nfunction _patchMissingTracingDefaults(tracer: LangChainTracer, run: Run): void {\n if (tracer.tracingMetadata) {\n run.extra ??= {};\n const metadata: Record<string, unknown> =\n (run.extra.metadata as Record<string, unknown> | undefined) ?? {};\n let didPatchMetadata = false;\n for (const [key, value] of Object.entries(tracer.tracingMetadata)) {\n if (!Object.prototype.hasOwnProperty.call(metadata, key)) {\n metadata[key] = value;\n didPatchMetadata = true;\n }\n }\n if (didPatchMetadata) {\n run.extra.metadata = metadata;\n }\n }\n\n if (tracer.tracingTags.length > 0) {\n run.tags = Array.from(\n new Set([...(run.tags ?? []), ...tracer.tracingTags])\n );\n }\n}\n"],"mappings":"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"}
1
+ {"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 metadata?: Record<string, unknown>;\n tags?: string[];\n}\n\n/**\n * Keys that should be inherited from `tracerInheritableMetadata` even when\n * the run already has a value for them. This lets nested contexts\n * (e.g. a subagent invoked from inside a parent agent) override a\n * LangSmith-only tracing metadata value that was set by an ancestor.\n *\n * Keep this list very small: every key here loses the default\n * \"first wins\" protection and is always clobbered by the nearest\n * enclosing tracer config. Only keys that are strictly for LangSmith\n * tracing bookkeeping should be added.\n */\nexport const OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS = new Set<string>([\n \"ls_agent_type\",\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 tracingMetadata?: Record<string, unknown>;\n\n tracingTags: string[] = [];\n\n constructor(protected fields: LangChainTracerFields = {}) {\n super(fields);\n const { exampleId, projectName, client, replicas, metadata, tags } = fields;\n\n this.projectName = projectName ?? getDefaultProjectName();\n this.replicas = replicas;\n this.exampleId = exampleId;\n this.client = client ?? getDefaultLangChainClientSingleton();\n this.tracingMetadata = metadata ? { ...metadata } : undefined;\n this.tracingTags = tags ?? [];\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 _patchMissingTracingDefaults(this, run);\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 _patchMissingTracingDefaults(this, run);\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 copyWithTracingConfig({\n metadata,\n tags,\n }: {\n metadata?: Record<string, unknown>;\n tags?: string[];\n }): LangChainTracer {\n let mergedMetadata: Record<string, unknown> | undefined;\n if (metadata === undefined) {\n mergedMetadata = this.tracingMetadata\n ? { ...this.tracingMetadata }\n : undefined;\n } else if (this.tracingMetadata === undefined) {\n mergedMetadata = { ...metadata };\n } else {\n mergedMetadata = { ...this.tracingMetadata };\n for (const [key, value] of Object.entries(metadata)) {\n // For allowlisted LangSmith-only inheritable metadata keys (e.g.\n // `ls_agent_type`), nested callers are allowed to OVERRIDE the\n // value inherited from an ancestor. For all other keys we keep\n // the existing \"first wins\" behavior so that ancestor-provided\n // tracing metadata is not accidentally clobbered by child runs.\n if (\n !Object.prototype.hasOwnProperty.call(mergedMetadata, key) ||\n OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)\n ) {\n mergedMetadata[key] = value;\n }\n }\n }\n\n const mergedTags = tags\n ? Array.from(new Set([...this.tracingTags, ...tags]))\n : [...this.tracingTags];\n\n const copied = new LangChainTracer({\n ...this.fields,\n metadata: mergedMetadata,\n tags: mergedTags,\n });\n copied.runMap = this.runMap;\n copied.runTreeMap = this.runTreeMap;\n return copied;\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 this.fields = {\n ...this.fields,\n client: this.client,\n replicas: this.replicas,\n projectName: this.projectName,\n exampleId: this.exampleId,\n };\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 static [Symbol.hasInstance](instance: unknown): boolean {\n if (typeof instance !== \"object\" || instance === null) {\n return false;\n }\n const candidate = instance as Record<string, unknown>;\n return (\n \"name\" in candidate &&\n candidate.name === \"langchain_tracer\" &&\n \"copyWithTracingConfig\" in candidate &&\n typeof candidate.copyWithTracingConfig === \"function\" &&\n \"getRunTreeWithTracingConfig\" in candidate &&\n typeof candidate.getRunTreeWithTracingConfig === \"function\"\n );\n }\n}\n\nfunction _patchMissingTracingDefaults(tracer: LangChainTracer, run: Run): void {\n if (tracer.tracingMetadata) {\n run.extra ??= {};\n const metadata: Record<string, unknown> =\n (run.extra.metadata as Record<string, unknown> | undefined) ?? {};\n let didPatchMetadata = false;\n for (const [key, value] of Object.entries(tracer.tracingMetadata)) {\n // `OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS` are a small, LangSmith-only\n // allowlist that bypasses the \"first wins\" merge so a nested caller\n // (e.g. a subagent) can override a parent-set value.\n if (\n !Object.prototype.hasOwnProperty.call(metadata, key) ||\n OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)\n ) {\n if (metadata[key] !== value) {\n metadata[key] = value;\n didPatchMetadata = true;\n }\n }\n }\n if (didPatchMetadata) {\n run.extra.metadata = metadata;\n }\n }\n\n if (tracer.tracingTags.length > 0) {\n run.tags = Array.from(\n new Set([...(run.tags ?? []), ...tracer.tracingTags])\n );\n }\n}\n"],"mappings":"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"}
@@ -30,6 +30,18 @@ interface LangChainTracerFields extends BaseCallbackHandlerInput {
30
30
  metadata?: Record<string, unknown>;
31
31
  tags?: string[];
32
32
  }
33
+ /**
34
+ * Keys that should be inherited from `tracerInheritableMetadata` even when
35
+ * the run already has a value for them. This lets nested contexts
36
+ * (e.g. a subagent invoked from inside a parent agent) override a
37
+ * LangSmith-only tracing metadata value that was set by an ancestor.
38
+ *
39
+ * Keep this list very small: every key here loses the default
40
+ * "first wins" protection and is always clobbered by the nearest
41
+ * enclosing tracer config. Only keys that are strictly for LangSmith
42
+ * tracing bookkeeping should be added.
43
+ */
44
+ declare const OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS: Set<string>;
33
45
  declare class LangChainTracer extends BaseTracer implements LangChainTracerFields {
34
46
  protected fields: LangChainTracerFields;
35
47
  name: string;
@@ -59,5 +71,5 @@ declare class LangChainTracer extends BaseTracer implements LangChainTracerField
59
71
  static [Symbol.hasInstance](instance: unknown): boolean;
60
72
  }
61
73
  //#endregion
62
- export { LangChainTracer, LangChainTracerFields, Run, RunCreate2, RunUpdate };
74
+ export { LangChainTracer, LangChainTracerFields, OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS, Run, RunCreate2, RunUpdate };
63
75
  //# sourceMappingURL=tracer_langchain.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracer_langchain.d.cts","names":[],"sources":["../../src/tracers/tracer_langchain.ts"],"mappings":";;;;;;;UAqBiB,GAAA,SAAY,OAAA;EAC3B,EAAA;EACA,UAAA;EACA,qBAAA;EACA,YAAA;EACA,QAAA;AAAA;AAAA,UAGe,UAAA,SAAmB,SAAA;EAClC,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,SAAA,SAAkB,WAAA;EACjC,MAAA,EAAQ,OAAA;EACR,MAAA,EAAQ,KAAA;EACR,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,qBAAA,SAA8B,wBAAA;EAC7C,SAAA;EACA,WAAA;EACA,MAAA,GAAS,+BAAA;EACT,QAAA,GAAW,aAAA;EACX,QAAA,GAAW,MAAA;EACX,IAAA;AAAA;AAAA,cA0BW,eAAA,SACH,UAAA,YACG,qBAAA;EAAA,UAkBW,MAAA,EAAQ,qBAAA;EAhB9B,IAAA;EAEA,WAAA;EAEA,SAAA;EAEA,MAAA,EAAQ,+BAAA;EAER,QAAA,GAAW,aAAA;EAEX,cAAA;EAEA,eAAA,GAAkB,MAAA;EAElB,WAAA;EAEA,WAAA,CAAsB,MAAA,GAAQ,qBAAA;EAAA,UAiBd,UAAA,CAAW,IAAA,EAAM,GAAA,GAAM,OAAA;EAIjC,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAQvB,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAU7B,QAAA,CAAS,GAAA,EAAK,KAAA;EAmBd,qBAAA,CAAA;IACE,QAAA;IACA;EAAA;IAEA,QAAA,GAAW,MAAA;IACX,IAAA;EAAA,IACE,eAAA;EA+BJ,MAAA,CAAO,EAAA,WAAa,GAAA;EAIpB,iBAAA,CAAkB,OAAA,EAAS,OAAA;EAsC3B,2BAAA,CAA4B,EAAA,WAAa,OAAA;EAAA,OAclC,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAgBtB,MAAA,CAAO,WAAA,EAAa,QAAA;AAAA"}
1
+ {"version":3,"file":"tracer_langchain.d.cts","names":[],"sources":["../../src/tracers/tracer_langchain.ts"],"mappings":";;;;;;;UAqBiB,GAAA,SAAY,OAAA;EAC3B,EAAA;EACA,UAAA;EACA,qBAAA;EACA,YAAA;EACA,QAAA;AAAA;AAAA,UAGe,UAAA,SAAmB,SAAA;EAClC,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,SAAA,SAAkB,WAAA;EACjC,MAAA,EAAQ,OAAA;EACR,MAAA,EAAQ,KAAA;EACR,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,qBAAA,SAA8B,wBAAA;EAC7C,SAAA;EACA,WAAA;EACA,MAAA,GAAS,+BAAA;EACT,QAAA,GAAW,aAAA;EACX,QAAA,GAAW,MAAA;EACX,IAAA;AAAA;;;;;;;;;;;;cAcW,+CAAA,EAA+C,GAAA;AAAA,cA2B/C,eAAA,SACH,UAAA,YACG,qBAAA;EAAA,UAkBW,MAAA,EAAQ,qBAAA;EAhB9B,IAAA;EAEA,WAAA;EAEA,SAAA;EAEA,MAAA,EAAQ,+BAAA;EAER,QAAA,GAAW,aAAA;EAEX,cAAA;EAEA,eAAA,GAAkB,MAAA;EAElB,WAAA;EAEA,WAAA,CAAsB,MAAA,GAAQ,qBAAA;EAAA,UAiBd,UAAA,CAAW,IAAA,EAAM,GAAA,GAAM,OAAA;EAIjC,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAQvB,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAU7B,QAAA,CAAS,GAAA,EAAK,KAAA;EAmBd,qBAAA,CAAA;IACE,QAAA;IACA;EAAA;IAEA,QAAA,GAAW,MAAA;IACX,IAAA;EAAA,IACE,eAAA;EAuCJ,MAAA,CAAO,EAAA,WAAa,GAAA;EAIpB,iBAAA,CAAkB,OAAA,EAAS,OAAA;EAsC3B,2BAAA,CAA4B,EAAA,WAAa,OAAA;EAAA,OAclC,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAgBtB,MAAA,CAAO,WAAA,EAAa,QAAA;AAAA"}
@@ -30,6 +30,18 @@ interface LangChainTracerFields extends BaseCallbackHandlerInput {
30
30
  metadata?: Record<string, unknown>;
31
31
  tags?: string[];
32
32
  }
33
+ /**
34
+ * Keys that should be inherited from `tracerInheritableMetadata` even when
35
+ * the run already has a value for them. This lets nested contexts
36
+ * (e.g. a subagent invoked from inside a parent agent) override a
37
+ * LangSmith-only tracing metadata value that was set by an ancestor.
38
+ *
39
+ * Keep this list very small: every key here loses the default
40
+ * "first wins" protection and is always clobbered by the nearest
41
+ * enclosing tracer config. Only keys that are strictly for LangSmith
42
+ * tracing bookkeeping should be added.
43
+ */
44
+ declare const OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS: Set<string>;
33
45
  declare class LangChainTracer extends BaseTracer implements LangChainTracerFields {
34
46
  protected fields: LangChainTracerFields;
35
47
  name: string;
@@ -59,5 +71,5 @@ declare class LangChainTracer extends BaseTracer implements LangChainTracerField
59
71
  static [Symbol.hasInstance](instance: unknown): boolean;
60
72
  }
61
73
  //#endregion
62
- export { LangChainTracer, LangChainTracerFields, Run, RunCreate2, RunUpdate };
74
+ export { LangChainTracer, LangChainTracerFields, OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS, Run, RunCreate2, RunUpdate };
63
75
  //# sourceMappingURL=tracer_langchain.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracer_langchain.d.ts","names":[],"sources":["../../src/tracers/tracer_langchain.ts"],"mappings":";;;;;;;UAqBiB,GAAA,SAAY,OAAA;EAC3B,EAAA;EACA,UAAA;EACA,qBAAA;EACA,YAAA;EACA,QAAA;AAAA;AAAA,UAGe,UAAA,SAAmB,SAAA;EAClC,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,SAAA,SAAkB,WAAA;EACjC,MAAA,EAAQ,OAAA;EACR,MAAA,EAAQ,KAAA;EACR,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,qBAAA,SAA8B,wBAAA;EAC7C,SAAA;EACA,WAAA;EACA,MAAA,GAAS,+BAAA;EACT,QAAA,GAAW,aAAA;EACX,QAAA,GAAW,MAAA;EACX,IAAA;AAAA;AAAA,cA0BW,eAAA,SACH,UAAA,YACG,qBAAA;EAAA,UAkBW,MAAA,EAAQ,qBAAA;EAhB9B,IAAA;EAEA,WAAA;EAEA,SAAA;EAEA,MAAA,EAAQ,+BAAA;EAER,QAAA,GAAW,aAAA;EAEX,cAAA;EAEA,eAAA,GAAkB,MAAA;EAElB,WAAA;EAEA,WAAA,CAAsB,MAAA,GAAQ,qBAAA;EAAA,UAiBd,UAAA,CAAW,IAAA,EAAM,GAAA,GAAM,OAAA;EAIjC,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAQvB,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAU7B,QAAA,CAAS,GAAA,EAAK,KAAA;EAmBd,qBAAA,CAAA;IACE,QAAA;IACA;EAAA;IAEA,QAAA,GAAW,MAAA;IACX,IAAA;EAAA,IACE,eAAA;EA+BJ,MAAA,CAAO,EAAA,WAAa,GAAA;EAIpB,iBAAA,CAAkB,OAAA,EAAS,OAAA;EAsC3B,2BAAA,CAA4B,EAAA,WAAa,OAAA;EAAA,OAclC,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAgBtB,MAAA,CAAO,WAAA,EAAa,QAAA;AAAA"}
1
+ {"version":3,"file":"tracer_langchain.d.ts","names":[],"sources":["../../src/tracers/tracer_langchain.ts"],"mappings":";;;;;;;UAqBiB,GAAA,SAAY,OAAA;EAC3B,EAAA;EACA,UAAA;EACA,qBAAA;EACA,YAAA;EACA,QAAA;AAAA;AAAA,UAGe,UAAA,SAAmB,SAAA;EAClC,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,SAAA,SAAkB,WAAA;EACjC,MAAA,EAAQ,OAAA;EACR,MAAA,EAAQ,KAAA;EACR,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,qBAAA,SAA8B,wBAAA;EAC7C,SAAA;EACA,WAAA;EACA,MAAA,GAAS,+BAAA;EACT,QAAA,GAAW,aAAA;EACX,QAAA,GAAW,MAAA;EACX,IAAA;AAAA;;;;;;;;;;;;cAcW,+CAAA,EAA+C,GAAA;AAAA,cA2B/C,eAAA,SACH,UAAA,YACG,qBAAA;EAAA,UAkBW,MAAA,EAAQ,qBAAA;EAhB9B,IAAA;EAEA,WAAA;EAEA,SAAA;EAEA,MAAA,EAAQ,+BAAA;EAER,QAAA,GAAW,aAAA;EAEX,cAAA;EAEA,eAAA,GAAkB,MAAA;EAElB,WAAA;EAEA,WAAA,CAAsB,MAAA,GAAQ,qBAAA;EAAA,UAiBd,UAAA,CAAW,IAAA,EAAM,GAAA,GAAM,OAAA;EAIjC,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAQvB,WAAA,CAAY,GAAA,EAAK,GAAA,GAAM,OAAA;EAU7B,QAAA,CAAS,GAAA,EAAK,KAAA;EAmBd,qBAAA,CAAA;IACE,QAAA;IACA;EAAA;IAEA,QAAA,GAAW,MAAA;IACX,IAAA;EAAA,IACE,eAAA;EAuCJ,MAAA,CAAO,EAAA,WAAa,GAAA;EAIpB,iBAAA,CAAkB,OAAA,EAAS,OAAA;EAsC3B,2BAAA,CAA4B,EAAA,WAAa,OAAA;EAAA,OAclC,mBAAA,CAAA,GAAuB,OAAA;EAAA,QAgBtB,MAAA,CAAO,WAAA,EAAa,QAAA;AAAA"}
@@ -7,7 +7,22 @@ import { RunTree } from "langsmith/run_trees";
7
7
  import { getDefaultProjectName } from "langsmith";
8
8
  import { getCurrentRunTree } from "langsmith/singletons/traceable";
9
9
  //#region src/tracers/tracer_langchain.ts
10
- var tracer_langchain_exports = /* @__PURE__ */ __exportAll({ LangChainTracer: () => LangChainTracer });
10
+ var tracer_langchain_exports = /* @__PURE__ */ __exportAll({
11
+ LangChainTracer: () => LangChainTracer,
12
+ OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS: () => OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS
13
+ });
14
+ /**
15
+ * Keys that should be inherited from `tracerInheritableMetadata` even when
16
+ * the run already has a value for them. This lets nested contexts
17
+ * (e.g. a subagent invoked from inside a parent agent) override a
18
+ * LangSmith-only tracing metadata value that was set by an ancestor.
19
+ *
20
+ * Keep this list very small: every key here loses the default
21
+ * "first wins" protection and is always clobbered by the nearest
22
+ * enclosing tracer config. Only keys that are strictly for LangSmith
23
+ * tracing bookkeeping should be added.
24
+ */
25
+ const OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS = new Set(["ls_agent_type"]);
11
26
  /**
12
27
  * Extract usage_metadata from chat generations.
13
28
  *
@@ -70,7 +85,7 @@ var LangChainTracer = class LangChainTracer extends BaseTracer {
70
85
  else if (this.tracingMetadata === void 0) mergedMetadata = { ...metadata };
71
86
  else {
72
87
  mergedMetadata = { ...this.tracingMetadata };
73
- for (const [key, value] of Object.entries(metadata)) if (!Object.prototype.hasOwnProperty.call(mergedMetadata, key)) mergedMetadata[key] = value;
88
+ for (const [key, value] of Object.entries(metadata)) if (!Object.prototype.hasOwnProperty.call(mergedMetadata, key) || OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)) mergedMetadata[key] = value;
74
89
  }
75
90
  const mergedTags = tags ? Array.from(new Set([...this.tracingTags, ...tags])) : [...this.tracingTags];
76
91
  const copied = new LangChainTracer({
@@ -146,15 +161,17 @@ function _patchMissingTracingDefaults(tracer, run) {
146
161
  run.extra ??= {};
147
162
  const metadata = run.extra.metadata ?? {};
148
163
  let didPatchMetadata = false;
149
- for (const [key, value] of Object.entries(tracer.tracingMetadata)) if (!Object.prototype.hasOwnProperty.call(metadata, key)) {
150
- metadata[key] = value;
151
- didPatchMetadata = true;
164
+ for (const [key, value] of Object.entries(tracer.tracingMetadata)) if (!Object.prototype.hasOwnProperty.call(metadata, key) || OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)) {
165
+ if (metadata[key] !== value) {
166
+ metadata[key] = value;
167
+ didPatchMetadata = true;
168
+ }
152
169
  }
153
170
  if (didPatchMetadata) run.extra.metadata = metadata;
154
171
  }
155
172
  if (tracer.tracingTags.length > 0) run.tags = Array.from(new Set([...run.tags ?? [], ...tracer.tracingTags]));
156
173
  }
157
174
  //#endregion
158
- export { LangChainTracer, tracer_langchain_exports };
175
+ export { LangChainTracer, OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS, tracer_langchain_exports };
159
176
 
160
177
  //# sourceMappingURL=tracer_langchain.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracer_langchain.js","names":[],"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 metadata?: Record<string, unknown>;\n tags?: string[];\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 tracingMetadata?: Record<string, unknown>;\n\n tracingTags: string[] = [];\n\n constructor(protected fields: LangChainTracerFields = {}) {\n super(fields);\n const { exampleId, projectName, client, replicas, metadata, tags } = fields;\n\n this.projectName = projectName ?? getDefaultProjectName();\n this.replicas = replicas;\n this.exampleId = exampleId;\n this.client = client ?? getDefaultLangChainClientSingleton();\n this.tracingMetadata = metadata ? { ...metadata } : undefined;\n this.tracingTags = tags ?? [];\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 _patchMissingTracingDefaults(this, run);\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 _patchMissingTracingDefaults(this, run);\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 copyWithTracingConfig({\n metadata,\n tags,\n }: {\n metadata?: Record<string, unknown>;\n tags?: string[];\n }): LangChainTracer {\n let mergedMetadata: Record<string, unknown> | undefined;\n if (metadata === undefined) {\n mergedMetadata = this.tracingMetadata\n ? { ...this.tracingMetadata }\n : undefined;\n } else if (this.tracingMetadata === undefined) {\n mergedMetadata = { ...metadata };\n } else {\n mergedMetadata = { ...this.tracingMetadata };\n for (const [key, value] of Object.entries(metadata)) {\n if (!Object.prototype.hasOwnProperty.call(mergedMetadata, key)) {\n mergedMetadata[key] = value;\n }\n }\n }\n\n const mergedTags = tags\n ? Array.from(new Set([...this.tracingTags, ...tags]))\n : [...this.tracingTags];\n\n const copied = new LangChainTracer({\n ...this.fields,\n metadata: mergedMetadata,\n tags: mergedTags,\n });\n copied.runMap = this.runMap;\n copied.runTreeMap = this.runTreeMap;\n return copied;\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 this.fields = {\n ...this.fields,\n client: this.client,\n replicas: this.replicas,\n projectName: this.projectName,\n exampleId: this.exampleId,\n };\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 static [Symbol.hasInstance](instance: unknown): boolean {\n if (typeof instance !== \"object\" || instance === null) {\n return false;\n }\n const candidate = instance as Record<string, unknown>;\n return (\n \"name\" in candidate &&\n candidate.name === \"langchain_tracer\" &&\n \"copyWithTracingConfig\" in candidate &&\n typeof candidate.copyWithTracingConfig === \"function\" &&\n \"getRunTreeWithTracingConfig\" in candidate &&\n typeof candidate.getRunTreeWithTracingConfig === \"function\"\n );\n }\n}\n\nfunction _patchMissingTracingDefaults(tracer: LangChainTracer, run: Run): void {\n if (tracer.tracingMetadata) {\n run.extra ??= {};\n const metadata: Record<string, unknown> =\n (run.extra.metadata as Record<string, unknown> | undefined) ?? {};\n let didPatchMetadata = false;\n for (const [key, value] of Object.entries(tracer.tracingMetadata)) {\n if (!Object.prototype.hasOwnProperty.call(metadata, key)) {\n metadata[key] = value;\n didPatchMetadata = true;\n }\n }\n if (didPatchMetadata) {\n run.extra.metadata = metadata;\n }\n }\n\n if (tracer.tracingTags.length > 0) {\n run.tags = Array.from(\n new Set([...(run.tags ?? []), ...tracer.tracingTags])\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tracer_langchain.js","names":[],"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 metadata?: Record<string, unknown>;\n tags?: string[];\n}\n\n/**\n * Keys that should be inherited from `tracerInheritableMetadata` even when\n * the run already has a value for them. This lets nested contexts\n * (e.g. a subagent invoked from inside a parent agent) override a\n * LangSmith-only tracing metadata value that was set by an ancestor.\n *\n * Keep this list very small: every key here loses the default\n * \"first wins\" protection and is always clobbered by the nearest\n * enclosing tracer config. Only keys that are strictly for LangSmith\n * tracing bookkeeping should be added.\n */\nexport const OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS = new Set<string>([\n \"ls_agent_type\",\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 tracingMetadata?: Record<string, unknown>;\n\n tracingTags: string[] = [];\n\n constructor(protected fields: LangChainTracerFields = {}) {\n super(fields);\n const { exampleId, projectName, client, replicas, metadata, tags } = fields;\n\n this.projectName = projectName ?? getDefaultProjectName();\n this.replicas = replicas;\n this.exampleId = exampleId;\n this.client = client ?? getDefaultLangChainClientSingleton();\n this.tracingMetadata = metadata ? { ...metadata } : undefined;\n this.tracingTags = tags ?? [];\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 _patchMissingTracingDefaults(this, run);\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 _patchMissingTracingDefaults(this, run);\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 copyWithTracingConfig({\n metadata,\n tags,\n }: {\n metadata?: Record<string, unknown>;\n tags?: string[];\n }): LangChainTracer {\n let mergedMetadata: Record<string, unknown> | undefined;\n if (metadata === undefined) {\n mergedMetadata = this.tracingMetadata\n ? { ...this.tracingMetadata }\n : undefined;\n } else if (this.tracingMetadata === undefined) {\n mergedMetadata = { ...metadata };\n } else {\n mergedMetadata = { ...this.tracingMetadata };\n for (const [key, value] of Object.entries(metadata)) {\n // For allowlisted LangSmith-only inheritable metadata keys (e.g.\n // `ls_agent_type`), nested callers are allowed to OVERRIDE the\n // value inherited from an ancestor. For all other keys we keep\n // the existing \"first wins\" behavior so that ancestor-provided\n // tracing metadata is not accidentally clobbered by child runs.\n if (\n !Object.prototype.hasOwnProperty.call(mergedMetadata, key) ||\n OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)\n ) {\n mergedMetadata[key] = value;\n }\n }\n }\n\n const mergedTags = tags\n ? Array.from(new Set([...this.tracingTags, ...tags]))\n : [...this.tracingTags];\n\n const copied = new LangChainTracer({\n ...this.fields,\n metadata: mergedMetadata,\n tags: mergedTags,\n });\n copied.runMap = this.runMap;\n copied.runTreeMap = this.runTreeMap;\n return copied;\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 this.fields = {\n ...this.fields,\n client: this.client,\n replicas: this.replicas,\n projectName: this.projectName,\n exampleId: this.exampleId,\n };\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 static [Symbol.hasInstance](instance: unknown): boolean {\n if (typeof instance !== \"object\" || instance === null) {\n return false;\n }\n const candidate = instance as Record<string, unknown>;\n return (\n \"name\" in candidate &&\n candidate.name === \"langchain_tracer\" &&\n \"copyWithTracingConfig\" in candidate &&\n typeof candidate.copyWithTracingConfig === \"function\" &&\n \"getRunTreeWithTracingConfig\" in candidate &&\n typeof candidate.getRunTreeWithTracingConfig === \"function\"\n );\n }\n}\n\nfunction _patchMissingTracingDefaults(tracer: LangChainTracer, run: Run): void {\n if (tracer.tracingMetadata) {\n run.extra ??= {};\n const metadata: Record<string, unknown> =\n (run.extra.metadata as Record<string, unknown> | undefined) ?? {};\n let didPatchMetadata = false;\n for (const [key, value] of Object.entries(tracer.tracingMetadata)) {\n // `OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS` are a small, LangSmith-only\n // allowlist that bypasses the \"first wins\" merge so a nested caller\n // (e.g. a subagent) can override a parent-set value.\n if (\n !Object.prototype.hasOwnProperty.call(metadata, key) ||\n OVERRIDABLE_LANGSMITH_INHERITABLE_METADATA_KEYS.has(key)\n ) {\n if (metadata[key] !== value) {\n metadata[key] = value;\n didPatchMetadata = true;\n }\n }\n }\n if (didPatchMetadata) {\n run.extra.metadata = metadata;\n }\n }\n\n if (tracer.tracingTags.length > 0) {\n run.tags = Array.from(\n new Set([...(run.tags ?? []), ...tracer.tracingTags])\n );\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
3
+ const require_max = require("./max.cjs");
4
+ const require_nil = require("./nil.cjs");
5
+ const require_validate = require("./validate.cjs");
6
+ const require_parse = require("./parse.cjs");
7
+ const require_stringify = require("./stringify.cjs");
8
+ const require_v1 = require("./v1.cjs");
9
+ const require_v4 = require("./v4.cjs");
10
+ const require_v5 = require("./v5.cjs");
11
+ const require_v7 = require("./v7.cjs");
12
+ const require_version = require("./version.cjs");
13
+ //#region src/utils/uuid/index.ts
14
+ var uuid_exports = /* @__PURE__ */ require_runtime.__exportAll({
15
+ MAX: () => require_max.default,
16
+ NIL: () => require_nil.default,
17
+ parse: () => require_parse.default,
18
+ stringify: () => require_stringify.default,
19
+ v1: () => require_v1.default,
20
+ v4: () => require_v4.default,
21
+ v5: () => require_v5.default,
22
+ v7: () => require_v7.default,
23
+ validate: () => require_validate.default,
24
+ version: () => require_version.default
25
+ });
26
+ //#endregion
27
+ exports.MAX = require_max;
28
+ exports.NIL = require_nil;
29
+ exports.parse = require_parse;
30
+ exports.stringify = require_stringify;
31
+ Object.defineProperty(exports, "uuid_exports", {
32
+ enumerable: true,
33
+ get: function() {
34
+ return uuid_exports;
35
+ }
36
+ });
37
+ exports.v1 = require_v1;
38
+ exports.v4 = require_v4;
39
+ exports.v5 = require_v5;
40
+ exports.v7 = require_v7;
41
+ exports.validate = require_validate;
42
+ exports.version = require_version;
43
+
44
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/utils/uuid/index.ts"],"sourcesContent":["export { default as MAX } from \"./max.js\";\nexport { default as NIL } from \"./nil.js\";\nexport { default as parse } from \"./parse.js\";\nexport { default as stringify } from \"./stringify.js\";\nexport type * from \"./types.js\";\nexport { default as v1 } from \"./v1.js\";\nexport { default as v4 } from \"./v4.js\";\nexport { default as v5 } from \"./v5.js\";\nexport { default as v7 } from \"./v7.js\";\nexport { default as validate } from \"./validate.js\";\nexport { default as version } from \"./version.js\";\n"],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { _default } from "./max.cjs";
2
+ import { _default as _default$1 } from "./nil.cjs";
3
+ import { NonSharedArrayBuffer, UUIDTypes, Version1Options, Version4Options, Version6Options, Version7Options } from "./types.cjs";
4
+ import { parse } from "./parse.cjs";
5
+ import { stringify } from "./stringify.cjs";
6
+ import { v1 } from "./v1.cjs";
7
+ import { v4 } from "./v4.cjs";
8
+ import { v5 } from "./v5.cjs";
9
+ import { v7 } from "./v7.cjs";
10
+ import { validate } from "./validate.cjs";
11
+ import { version } from "./version.cjs";
12
+ export { _default as MAX, _default$1 as NIL, NonSharedArrayBuffer, UUIDTypes, Version1Options, Version4Options, Version6Options, Version7Options, parse, stringify, v1, v4, v5, v7, validate, version };
@@ -0,0 +1,12 @@
1
+ import { _default } from "./max.js";
2
+ import { _default as _default$1 } from "./nil.js";
3
+ import { NonSharedArrayBuffer, UUIDTypes, Version1Options, Version4Options, Version6Options, Version7Options } from "./types.js";
4
+ import { parse } from "./parse.js";
5
+ import { stringify } from "./stringify.js";
6
+ import { v1 } from "./v1.js";
7
+ import { v4 } from "./v4.js";
8
+ import { v5 } from "./v5.js";
9
+ import { v7 } from "./v7.js";
10
+ import { validate } from "./validate.js";
11
+ import { version } from "./version.js";
12
+ export { _default as MAX, _default$1 as NIL, NonSharedArrayBuffer, UUIDTypes, Version1Options, Version4Options, Version6Options, Version7Options, parse, stringify, v1, v4, v5, v7, validate, version };