@langchain/core 1.1.46 → 1.1.48

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 (84) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/callbacks/base.cjs +2 -3
  3. package/dist/callbacks/base.cjs.map +1 -1
  4. package/dist/callbacks/base.js +1 -2
  5. package/dist/callbacks/base.js.map +1 -1
  6. package/dist/callbacks/manager.cjs +7 -8
  7. package/dist/callbacks/manager.cjs.map +1 -1
  8. package/dist/callbacks/manager.js +1 -2
  9. package/dist/callbacks/manager.js.map +1 -1
  10. package/dist/indexing/base.cjs +3 -4
  11. package/dist/indexing/base.cjs.map +1 -1
  12. package/dist/indexing/base.js +1 -2
  13. package/dist/indexing/base.js.map +1 -1
  14. package/dist/language_models/base.cjs +1 -1
  15. package/dist/language_models/base.js +1 -1
  16. package/dist/language_models/chat_models.cjs +1 -0
  17. package/dist/language_models/chat_models.cjs.map +1 -1
  18. package/dist/language_models/chat_models.d.cts.map +1 -1
  19. package/dist/language_models/chat_models.d.ts.map +1 -1
  20. package/dist/language_models/chat_models.js +1 -0
  21. package/dist/language_models/chat_models.js.map +1 -1
  22. package/dist/messages/block_translators/index.cjs +2 -0
  23. package/dist/messages/block_translators/index.cjs.map +1 -1
  24. package/dist/messages/block_translators/index.js +2 -0
  25. package/dist/messages/block_translators/index.js.map +1 -1
  26. package/dist/messages/block_translators/openrouter.cjs +101 -0
  27. package/dist/messages/block_translators/openrouter.cjs.map +1 -0
  28. package/dist/messages/block_translators/openrouter.js +101 -0
  29. package/dist/messages/block_translators/openrouter.js.map +1 -0
  30. package/dist/messages/index.d.cts +2 -2
  31. package/dist/messages/index.d.ts +2 -2
  32. package/dist/messages/utils.cjs +16 -2
  33. package/dist/messages/utils.cjs.map +1 -1
  34. package/dist/messages/utils.d.cts +9 -1
  35. package/dist/messages/utils.d.cts.map +1 -1
  36. package/dist/messages/utils.d.ts +9 -1
  37. package/dist/messages/utils.d.ts.map +1 -1
  38. package/dist/messages/utils.js +16 -2
  39. package/dist/messages/utils.js.map +1 -1
  40. package/dist/runnables/base.cjs +2 -3
  41. package/dist/runnables/base.cjs.map +1 -1
  42. package/dist/runnables/base.js +1 -2
  43. package/dist/runnables/base.js.map +1 -1
  44. package/dist/runnables/graph.cjs +6 -8
  45. package/dist/runnables/graph.cjs.map +1 -1
  46. package/dist/runnables/graph.js +1 -3
  47. package/dist/runnables/graph.js.map +1 -1
  48. package/dist/testing/fake_model_builder.cjs +10 -9
  49. package/dist/testing/fake_model_builder.cjs.map +1 -1
  50. package/dist/testing/fake_model_builder.d.cts +1 -2
  51. package/dist/testing/fake_model_builder.d.cts.map +1 -1
  52. package/dist/testing/fake_model_builder.d.ts +1 -2
  53. package/dist/testing/fake_model_builder.d.ts.map +1 -1
  54. package/dist/testing/fake_model_builder.js +10 -9
  55. package/dist/testing/fake_model_builder.js.map +1 -1
  56. package/dist/utils/uuid/index.cjs +34 -20
  57. package/dist/utils/uuid/index.cjs.map +1 -1
  58. package/dist/utils/uuid/index.d.cts +25 -11
  59. package/dist/utils/uuid/index.d.cts.map +1 -0
  60. package/dist/utils/uuid/index.d.ts +25 -11
  61. package/dist/utils/uuid/index.d.ts.map +1 -0
  62. package/dist/utils/uuid/index.js +24 -11
  63. package/dist/utils/uuid/index.js.map +1 -1
  64. package/dist/utils/uuid/v1ToV6.cjs +14 -0
  65. package/dist/utils/uuid/v1ToV6.cjs.map +1 -0
  66. package/dist/utils/uuid/v1ToV6.js +14 -0
  67. package/dist/utils/uuid/v1ToV6.js.map +1 -0
  68. package/dist/utils/uuid/v6.cjs +23 -0
  69. package/dist/utils/uuid/v6.cjs.map +1 -0
  70. package/dist/utils/uuid/v6.d.cts +8 -0
  71. package/dist/utils/uuid/v6.d.cts.map +1 -0
  72. package/dist/utils/uuid/v6.d.ts +8 -0
  73. package/dist/utils/uuid/v6.d.ts.map +1 -0
  74. package/dist/utils/uuid/v6.js +23 -0
  75. package/dist/utils/uuid/v6.js.map +1 -0
  76. package/package.json +1 -2
  77. package/dist/utils/uuid/max.d.cts +0 -5
  78. package/dist/utils/uuid/max.d.cts.map +0 -1
  79. package/dist/utils/uuid/max.d.ts +0 -5
  80. package/dist/utils/uuid/max.d.ts.map +0 -1
  81. package/dist/utils/uuid/nil.d.cts +0 -5
  82. package/dist/utils/uuid/nil.d.cts.map +0 -1
  83. package/dist/utils/uuid/nil.d.ts +0 -5
  84. package/dist/utils/uuid/nil.d.ts.map +0 -1
@@ -1,15 +1,13 @@
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
+ const require_utils_uuid_index = require("../utils/uuid/index.cjs");
6
4
  const require_utils = require("./utils.cjs");
7
5
  const require_graph_mermaid = require("./graph_mermaid.cjs");
8
6
  const require_utils_json_schema = require("../utils/json_schema.cjs");
9
7
  //#region src/runnables/graph.ts
10
8
  var graph_exports = /* @__PURE__ */ require_runtime.__exportAll({ Graph: () => Graph });
11
9
  function nodeDataStr(id, data) {
12
- if (id !== void 0 && !require_validate.default(id)) return id;
10
+ if (id !== void 0 && !require_utils_uuid_index.validate(id)) return id;
13
11
  else if (require_utils.isRunnableInterface(data)) try {
14
12
  let dataStr = data.getName();
15
13
  dataStr = dataStr.startsWith("Runnable") ? dataStr.slice(8) : dataStr;
@@ -45,7 +43,7 @@ var Graph = class Graph {
45
43
  toJSON() {
46
44
  const stableNodeIds = {};
47
45
  Object.values(this.nodes).forEach((node, i) => {
48
- stableNodeIds[node.id] = require_validate.default(node.id) ? i : node.id;
46
+ stableNodeIds[node.id] = require_utils_uuid_index.validate(node.id) ? i : node.id;
49
47
  });
50
48
  return {
51
49
  nodes: Object.values(this.nodes).map((node) => ({
@@ -65,7 +63,7 @@ var Graph = class Graph {
65
63
  }
66
64
  addNode(data, id, metadata) {
67
65
  if (id !== void 0 && this.nodes[id] !== void 0) throw new Error(`Node with id ${id} already exists`);
68
- const nodeId = id ?? require_v4.default();
66
+ const nodeId = id ?? require_utils_uuid_index.v4();
69
67
  const node = {
70
68
  id: nodeId,
71
69
  data,
@@ -103,7 +101,7 @@ var Graph = class Graph {
103
101
  */
104
102
  extend(graph, prefix = "") {
105
103
  let finalPrefix = prefix;
106
- if (Object.values(graph.nodes).map((node) => node.id).every(require_validate.default)) finalPrefix = "";
104
+ if (Object.values(graph.nodes).map((node) => node.id).every(require_utils_uuid_index.validate)) finalPrefix = "";
107
105
  const prefixed = (id) => {
108
106
  return finalPrefix ? `${finalPrefix}:${id}` : id;
109
107
  };
@@ -151,7 +149,7 @@ var Graph = class Graph {
151
149
  });
152
150
  const getNodeId = (nodeId) => {
153
151
  const label = nodeLabels[nodeId];
154
- if (require_validate.default(nodeId) && nodeLabelCounts.get(label) === 1) return label;
152
+ if (require_utils_uuid_index.validate(nodeId) && nodeLabelCounts.get(label) === 1) return label;
155
153
  else return nodeId;
156
154
  };
157
155
  return new Graph({
@@ -1 +1 @@
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
+ {"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,7 +1,5 @@
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
+ import { v4, validate } from "../utils/uuid/index.js";
5
3
  import { isRunnableInterface } from "./utils.js";
6
4
  import { drawMermaid, drawMermaidImage } from "./graph_mermaid.js";
7
5
  import { toJsonSchema } from "../utils/json_schema.js";
@@ -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 \"../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":";;;;;;;;;AAaA,SAAS,YACP,IACA,MACQ;AACR,KAAI,OAAO,KAAA,KAAa,CAACA,SAAO,GAAG,CACjC,QAAO;UACE,oBAAoB,KAAK,CAClC,KAAI;EACF,IAAI,UAAU,KAAK,SAAS;AAC5B,YAAU,QAAQ,WAAW,WAAW,GACpC,QAAQ,MAAM,EAAkB,GAChC;AACJ,SAAO;SACD;AACN,SAAO,KAAK,SAAS;;KAGvB,QAAO,KAAK,QAAQ;;AAIxB,SAAS,aAAa,MAAY;AAEhC,KAAI,oBAAoB,KAAK,KAAK,CAChC,QAAO;EACL,MAAM;EACN,MAAM;GACJ,IAAI,KAAK,KAAK;GACd,MAAM,KAAK,KAAK,SAAS;GAC1B;EACF;KAED,QAAO;EACL,MAAM;EACN,MAAM;GAAE,GAAG,aAAa,KAAK,KAAK,OAAO;GAAE,OAAO,KAAK,KAAK;GAAM;EACnE;;AAIL,IAAa,QAAb,MAAa,MAAM;CACjB,QAA8B,EAAE;CAEhC,QAAgB,EAAE;CAElB,YAAY,QAAyD;AACnE,OAAK,QAAQ,QAAQ,SAAS,KAAK;AACnC,OAAK,QAAQ,QAAQ,SAAS,KAAK;;CAKrC,SAA8B;EAC5B,MAAM,gBAAiD,EAAE;AACzD,SAAO,OAAO,KAAK,MAAM,CAAC,SAAS,MAAM,MAAM;AAC7C,iBAAc,KAAK,MAAMA,SAAO,KAAK,GAAG,GAAG,IAAI,KAAK;IACpD;AAEF,SAAO;GACL,OAAO,OAAO,OAAO,KAAK,MAAM,CAAC,KAAK,UAAU;IAC9C,IAAI,cAAc,KAAK;IACvB,GAAG,aAAa,KAAK;IACtB,EAAE;GACH,OAAO,KAAK,MAAM,KAAK,SAAS;IAC9B,MAAM,OAAgC;KACpC,QAAQ,cAAc,KAAK;KAC3B,QAAQ,cAAc,KAAK;KAC5B;AAED,QAAI,OAAO,KAAK,SAAS,YACvB,MAAK,OAAO,KAAK;AAGnB,QAAI,OAAO,KAAK,gBAAgB,YAC9B,MAAK,cAAc,KAAK;AAE1B,WAAO;KACP;GACH;;CAGH,QACE,MACA,IAEA,UACM;AACN,MAAI,OAAO,KAAA,KAAa,KAAK,MAAM,QAAQ,KAAA,EACzC,OAAM,IAAI,MAAM,gBAAgB,GAAG,iBAAiB;EAEtD,MAAM,SAAS,MAAMC,IAAQ;EAC7B,MAAM,OAAa;GACjB,IAAI;GACJ;GACA,MAAM,YAAY,IAAI,KAAK;GAC3B;GACD;AACD,OAAK,MAAM,UAAU;AACrB,SAAO;;CAGT,WAAW,MAAkB;AAE3B,SAAO,KAAK,MAAM,KAAK;AAGvB,OAAK,QAAQ,KAAK,MAAM,QACrB,SAAS,KAAK,WAAW,KAAK,MAAM,KAAK,WAAW,KAAK,GAC3D;;CAGH,QACE,QACA,QACA,MACA,aACM;AACN,MAAI,KAAK,MAAM,OAAO,QAAQ,KAAA,EAC5B,OAAM,IAAI,MAAM,eAAe,OAAO,GAAG,eAAe;AAE1D,MAAI,KAAK,MAAM,OAAO,QAAQ,KAAA,EAC5B,OAAM,IAAI,MAAM,eAAe,OAAO,GAAG,eAAe;EAE1D,MAAM,OAAa;GACjB,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf;GACA;GACD;AACD,OAAK,MAAM,KAAK,KAAK;AACrB,SAAO;;CAGT,YAA8B;AAC5B,SAAO,WAAW,KAAK;;CAGzB,WAA6B;AAC3B,SAAO,UAAU,KAAK;;;;;;CAOxB,OAAO,OAAc,SAAS,IAAI;EAChC,IAAI,cAAc;AAElB,MADgB,OAAO,OAAO,MAAM,MAAM,CAAC,KAAK,SAAS,KAAK,GAAG,CACrD,MAAMD,SAAO,CACvB,eAAc;EAGhB,MAAM,YAAY,OAAe;AAC/B,UAAO,cAAc,GAAG,YAAY,GAAG,OAAO;;AAGhD,SAAO,QAAQ,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,WAAW;AACpD,QAAK,MAAM,SAAS,IAAI,IAAI;IAAE,GAAG;IAAO,IAAI,SAAS,IAAI;IAAE;IAC3D;EAEF,MAAM,WAAW,MAAM,MAAM,KAAK,SAAS;AACzC,UAAO;IACL,GAAG;IACH,QAAQ,SAAS,KAAK,OAAO;IAC7B,QAAQ,SAAS,KAAK,OAAO;IAC9B;IACD;AAEF,OAAK,QAAQ,CAAC,GAAG,KAAK,OAAO,GAAG,SAAS;EACzC,MAAM,QAAQ,MAAM,WAAW;EAC/B,MAAM,OAAO,MAAM,UAAU;AAC7B,SAAO,CACL,QAAQ;GAAE,IAAI,SAAS,MAAM,GAAG;GAAE,MAAM,MAAM;GAAM,GAAG,KAAA,GACvD,OAAO;GAAE,IAAI,SAAS,KAAK,GAAG;GAAE,MAAM,KAAK;GAAM,GAAG,KAAA,EACrD;;CAGH,gBAAsB;EACpB,MAAM,YAAY,KAAK,WAAW;AAClC,MAAI,aAAa,WAAW,MAAM,CAAC,UAAU,GAAG,CAAC,CAC/C,MAAK,WAAW,UAAU;;CAI9B,eAAqB;EACnB,MAAM,WAAW,KAAK,UAAU;AAChC,MAAI,YAAY,UAAU,MAAM,CAAC,SAAS,GAAG,CAAC,CAC5C,MAAK,WAAW,SAAS;;;;;;CAQ7B,OAAc;EACZ,MAAM,aAAqC,OAAO,YAChD,OAAO,OAAO,KAAK,MAAM,CAAC,KAAK,SAAS,CAAC,KAAK,IAAI,KAAK,KAAK,CAAC,CAC9D;EACD,MAAM,kCAAkB,IAAI,KAAqB;AACjD,SAAO,OAAO,WAAW,CAAC,SAAS,UAAU;AAC3C,mBAAgB,IAAI,QAAQ,gBAAgB,IAAI,MAAM,IAAI,KAAK,EAAE;IACjE;EAEF,MAAM,aAAa,WAA2B;GAC5C,MAAM,QAAQ,WAAW;AACzB,OAAIA,SAAO,OAAO,IAAI,gBAAgB,IAAI,MAAM,KAAK,EACnD,QAAO;OAEP,QAAO;;AAIX,SAAO,IAAI,MAAM;GACf,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,UAAU,CAC7C,UAAU,GAAG,EACb;IAAE,GAAG;IAAM,IAAI,UAAU,GAAG;IAAE,CAC/B,CAAC,CACH;GACD,OAAO,KAAK,MAAM,KAAK,UAAU;IAC/B,GAAG;IACH,QAAQ,UAAU,KAAK,OAAO;IAC9B,QAAQ,UAAU,KAAK,OAAO;IAC/B,EAAE;GACJ,CAAC;;CAGJ,YAAY,QAKD;EACT,MAAM,EACJ,YACA,YACA,aAAa;GACX,SAAS;GACT,OAAO;GACP,MAAM;GACP,EACD,oBACE,UAAU,EAAE;EAChB,MAAM,QAAQ,KAAK,MAAM;EACzB,MAAM,YAAY,MAAM,WAAW;EAEnC,MAAM,WAAW,MAAM,UAAU;AAEjC,SAAO,YAAY,MAAM,OAAO,MAAM,OAAO;GAC3C,WAAW,WAAW;GACtB,UAAU,UAAU;GACpB;GACA;GACA;GACA;GACD,CAAC;;CAGJ,MAAM,eAAe,QAMH;AAEhB,SAAO,iBADe,KAAK,YAAY,OAAO,EACP,EACrC,iBAAiB,QAAQ,iBAC1B,CAAC;;;;;;;;;AASN,SAAS,WAAW,OAAc,UAAoB,EAAE,EAAoB;CAC1E,MAAM,UAAU,IAAI,IAClB,MAAM,MACH,QAAQ,SAAS,CAAC,QAAQ,SAAS,KAAK,OAAO,CAAC,CAChD,KAAK,SAAS,KAAK,OAAO,CAC9B;CAED,MAAM,QAAgB,EAAE;AACxB,MAAK,MAAM,QAAQ,OAAO,OAAO,MAAM,MAAM,CAC3C,KAAI,CAAC,QAAQ,SAAS,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,GAAG,CACrD,OAAM,KAAK,KAAK;AAGpB,QAAO,MAAM,WAAW,IAAI,MAAM,KAAK,KAAA;;;;;;;;AASzC,SAAS,UAAU,OAAc,UAAoB,EAAE,EAAoB;CACzE,MAAM,UAAU,IAAI,IAClB,MAAM,MACH,QAAQ,SAAS,CAAC,QAAQ,SAAS,KAAK,OAAO,CAAC,CAChD,KAAK,SAAS,KAAK,OAAO,CAC9B;CAED,MAAM,QAAgB,EAAE;AACxB,MAAK,MAAM,QAAQ,OAAO,OAAO,MAAM,MAAM,CAC3C,KAAI,CAAC,QAAQ,SAAS,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,GAAG,CACrD,OAAM,KAAK,KAAK;AAGpB,QAAO,MAAM,WAAW,IAAI,MAAM,KAAK,KAAA"}
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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"}
@@ -25,21 +25,23 @@ var FakeBuiltModel = class FakeBuiltModel extends require_language_models_chat_m
25
25
  _alwaysThrowError;
26
26
  _structuredResponseValue;
27
27
  _tools = [];
28
- _callIndex = 0;
29
- _calls = [];
28
+ _state = {
29
+ callIndex: 0,
30
+ calls: []
31
+ };
30
32
  /**
31
33
  * All invocations recorded by this model, in order.
32
34
  * Each entry contains the `messages` array and `options` that were
33
35
  * passed to `invoke()`.
34
36
  */
35
37
  get calls() {
36
- return this._calls;
38
+ return this._state.calls;
37
39
  }
38
40
  /**
39
41
  * The number of times this model has been invoked.
40
42
  */
41
43
  get callCount() {
42
- return this._calls.length;
44
+ return this._state.calls.length;
43
45
  }
44
46
  constructor() {
45
47
  super({});
@@ -122,8 +124,7 @@ var FakeBuiltModel = class FakeBuiltModel extends require_language_models_chat_m
122
124
  next._alwaysThrowError = this._alwaysThrowError;
123
125
  next._structuredResponseValue = this._structuredResponseValue;
124
126
  next._tools = merged;
125
- next._calls = this._calls;
126
- next._callIndex = this._callIndex;
127
+ next._state = this._state;
127
128
  return next.withConfig({});
128
129
  }
129
130
  /**
@@ -140,12 +141,12 @@ var FakeBuiltModel = class FakeBuiltModel extends require_language_models_chat_m
140
141
  });
141
142
  }
142
143
  async _generate(messages, options, _runManager) {
143
- this._calls.push({
144
+ this._state.calls.push({
144
145
  messages: [...messages],
145
146
  options
146
147
  });
147
- const currentCallIndex = this._callIndex;
148
- this._callIndex += 1;
148
+ const currentCallIndex = this._state.callIndex;
149
+ this._state.callIndex += 1;
149
150
  if (this._alwaysThrowError) throw this._alwaysThrowError;
150
151
  const entry = this.queue[currentCallIndex];
151
152
  if (!entry) throw new Error(`FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`);
@@ -1 +1 @@
1
- {"version":3,"file":"fake_model_builder.cjs","names":["BaseChatModel","BaseMessage","RunnableLambda","AIMessage"],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _callIndex = 0;\n\n private _calls: FakeModelCall[] = [];\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._calls = this._calls;\n next._callIndex = this._callIndex;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._callIndex;\n this._callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fake_model_builder.cjs","names":["BaseChatModel","BaseMessage","RunnableLambda","AIMessage"],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\ninterface FakeModelState {\n callIndex: number;\n calls: FakeModelCall[];\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _state: FakeModelState = { callIndex: 0, calls: [] };\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._state.calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._state.calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._state = this._state;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._state.calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._state.callIndex;\n this._state.callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":"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"}
@@ -29,8 +29,7 @@ declare class FakeBuiltModel extends BaseChatModel {
29
29
  private _alwaysThrowError;
30
30
  private _structuredResponseValue;
31
31
  private _tools;
32
- private _callIndex;
33
- private _calls;
32
+ private _state;
34
33
  /**
35
34
  * All invocations recorded by this model, in order.
36
35
  * Each entry contains the `messages` array and `options` that were
@@ -1 +1 @@
1
- {"version":3,"file":"fake_model_builder.d.cts","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"mappings":";;;;;;;;;;;;;KAmBK,eAAA,IAAmB,QAAA,EAAU,WAAA,OAAkB,WAAA,GAAc,KAAA;AAAA,UAQxD,aAAA;EACR,QAAA,EAAU,WAAA;EACV,OAAA;AAAA;AAZ8D;;;;;;;;AAAA,cAoCnD,cAAA,SAAuB,aAAA;EAAA,QAC1B,KAAA;EAAA,QAEA,iBAAA;EAAA,QAEA,wBAAA;EAAA,QAEA,MAAA;EAAA,QAEA,UAAA;EAAA,QAEA,MAAA;EArCa;;;;;EAAA,IA4CjB,KAAA,CAAA,GAAS,aAAA;EA1CN;;AAwBT;EAxBS,IAiDH,SAAA,CAAA;EAIJ,WAAA,CAAA;EAIA,QAAA,CAAA;EAIA,iBAAA,CAAA;EAU6B;;;;;;EAA7B,OAAA,CAAQ,KAAA,EAAO,WAAA,GAAc,KAAA,GAAQ,eAAA;EA4DF;;;;;;;EA1CnC,gBAAA,CACE,SAAA,EAAW,KAAA;IAAQ,IAAA;IAAc,IAAA,EAAM,MAAA;IAAqB,EAAA;EAAA;EAkExD;;;;;EA/CN,WAAA,CAAY,KAAA,EAAO,KAAA;EAqDb;;;;;EA3CN,kBAAA,CAAmB,KAAA,EAAO,MAAA;EAwDf;;;;;;;EA5CX,SAAA,CAAU,KAAA,GAAQ,cAAA,GAAiB,QAAA,MAAW,QAAA,CAAA,sBAAA,EAAA,cAAA,CAAA,gBAAA,CAAA,cAAA,IAAA,wBAAA;EAtGtC;;;;;;;EA0HR,oBAAA,mBACoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,OAAA,EACI,4BAAA,CAA6B,SAAA,aAC7B,cAAA,CAAe,SAAA,IACf,MAAA,eACJ,OAAA,GAAU,6BAAA,YAER,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CACE,sBAAA;IACE,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAQ5B,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,8BACA,WAAA,GAAc,wBAAA,GACb,OAAA,CAAQ,UAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6FG,SAAA,CAAA,GAAa,cAAA"}
1
+ {"version":3,"file":"fake_model_builder.d.cts","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"mappings":";;;;;;;;;;;;;KAmBK,eAAA,IAAmB,QAAA,EAAU,WAAA,OAAkB,WAAA,GAAc,KAAA;AAAA,UAQxD,aAAA;EACR,QAAA,EAAU,WAAA;EACV,OAAA;AAAA;AAZ8D;;;;;;;;AAAA,cAyCnD,cAAA,SAAuB,aAAA;EAAA,QAC1B,KAAA;EAAA,QAEA,iBAAA;EAAA,QAEA,wBAAA;EAAA,QAEA,MAAA;EAAA,QAEA,MAAA;EAxCA;;;;;EAAA,IA+CJ,KAAA,CAAA,GAAS,aAAA;EA7Cb;;;EAAA,IAoDI,SAAA,CAAA;EAIJ,WAAA,CAAA;EAIA,QAAA,CAAA;EAIA,iBAAA,CAAA;EAUe;;;;;;EAAf,OAAA,CAAQ,KAAA,EAAO,WAAA,GAAc,KAAA,GAAQ,eAAA;EA4DnB;;;;;;;EA1ClB,gBAAA,CACE,SAAA,EAAW,KAAA;IAAQ,IAAA;IAAc,IAAA,EAAM,MAAA;IAAqB,EAAA;EAAA;EAiEzC;;;;;EA9CrB,WAAA,CAAY,KAAA,EAAO,KAAA;EAkDf;;;;;EAxCJ,kBAAA,CAAmB,KAAA,EAAO,MAAA;EAsDV;;;;;;;EA1ChB,SAAA,CAAU,KAAA,GAAQ,cAAA,GAAiB,QAAA,MAAW,QAAA,CAAA,sBAAA,EAAA,cAAA,CAAA,gBAAA,CAAA,cAAA,IAAA,wBAAA;EAtGtC;;;;;;;EAyHR,oBAAA,mBACoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,OAAA,EACI,4BAAA,CAA6B,SAAA,aAC7B,cAAA,CAAe,SAAA,IACf,MAAA,eACJ,OAAA,GAAU,6BAAA,YAER,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CACE,sBAAA;IACE,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAQ5B,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,8BACA,WAAA,GAAc,wBAAA,GACb,OAAA,CAAQ,UAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6FG,SAAA,CAAA,GAAa,cAAA"}
@@ -29,8 +29,7 @@ declare class FakeBuiltModel extends BaseChatModel {
29
29
  private _alwaysThrowError;
30
30
  private _structuredResponseValue;
31
31
  private _tools;
32
- private _callIndex;
33
- private _calls;
32
+ private _state;
34
33
  /**
35
34
  * All invocations recorded by this model, in order.
36
35
  * Each entry contains the `messages` array and `options` that were
@@ -1 +1 @@
1
- {"version":3,"file":"fake_model_builder.d.ts","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"mappings":";;;;;;;;;;;;;KAmBK,eAAA,IAAmB,QAAA,EAAU,WAAA,OAAkB,WAAA,GAAc,KAAA;AAAA,UAQxD,aAAA;EACR,QAAA,EAAU,WAAA;EACV,OAAA;AAAA;AAZ8D;;;;;;;;AAAA,cAoCnD,cAAA,SAAuB,aAAA;EAAA,QAC1B,KAAA;EAAA,QAEA,iBAAA;EAAA,QAEA,wBAAA;EAAA,QAEA,MAAA;EAAA,QAEA,UAAA;EAAA,QAEA,MAAA;EArCa;;;;;EAAA,IA4CjB,KAAA,CAAA,GAAS,aAAA;EA1CN;;AAwBT;EAxBS,IAiDH,SAAA,CAAA;EAIJ,WAAA,CAAA;EAIA,QAAA,CAAA;EAIA,iBAAA,CAAA;EAU6B;;;;;;EAA7B,OAAA,CAAQ,KAAA,EAAO,WAAA,GAAc,KAAA,GAAQ,eAAA;EA4DF;;;;;;;EA1CnC,gBAAA,CACE,SAAA,EAAW,KAAA;IAAQ,IAAA;IAAc,IAAA,EAAM,MAAA;IAAqB,EAAA;EAAA;EAkExD;;;;;EA/CN,WAAA,CAAY,KAAA,EAAO,KAAA;EAqDb;;;;;EA3CN,kBAAA,CAAmB,KAAA,EAAO,MAAA;EAwDf;;;;;;;EA5CX,SAAA,CAAU,KAAA,GAAQ,cAAA,GAAiB,QAAA,MAAW,QAAA,CAAA,sBAAA,EAAA,cAAA,CAAA,gBAAA,CAAA,cAAA,IAAA,wBAAA;EAtGtC;;;;;;;EA0HR,oBAAA,mBACoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,OAAA,EACI,4BAAA,CAA6B,SAAA,aAC7B,cAAA,CAAe,SAAA,IACf,MAAA,eACJ,OAAA,GAAU,6BAAA,YAER,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CACE,sBAAA;IACE,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAQ5B,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,8BACA,WAAA,GAAc,wBAAA,GACb,OAAA,CAAQ,UAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6FG,SAAA,CAAA,GAAa,cAAA"}
1
+ {"version":3,"file":"fake_model_builder.d.ts","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"mappings":";;;;;;;;;;;;;KAmBK,eAAA,IAAmB,QAAA,EAAU,WAAA,OAAkB,WAAA,GAAc,KAAA;AAAA,UAQxD,aAAA;EACR,QAAA,EAAU,WAAA;EACV,OAAA;AAAA;AAZ8D;;;;;;;;AAAA,cAyCnD,cAAA,SAAuB,aAAA;EAAA,QAC1B,KAAA;EAAA,QAEA,iBAAA;EAAA,QAEA,wBAAA;EAAA,QAEA,MAAA;EAAA,QAEA,MAAA;EAxCA;;;;;EAAA,IA+CJ,KAAA,CAAA,GAAS,aAAA;EA7Cb;;;EAAA,IAoDI,SAAA,CAAA;EAIJ,WAAA,CAAA;EAIA,QAAA,CAAA;EAIA,iBAAA,CAAA;EAUe;;;;;;EAAf,OAAA,CAAQ,KAAA,EAAO,WAAA,GAAc,KAAA,GAAQ,eAAA;EA4DnB;;;;;;;EA1ClB,gBAAA,CACE,SAAA,EAAW,KAAA;IAAQ,IAAA;IAAc,IAAA,EAAM,MAAA;IAAqB,EAAA;EAAA;EAiEzC;;;;;EA9CrB,WAAA,CAAY,KAAA,EAAO,KAAA;EAkDf;;;;;EAxCJ,kBAAA,CAAmB,KAAA,EAAO,MAAA;EAsDV;;;;;;;EA1ChB,SAAA,CAAU,KAAA,GAAQ,cAAA,GAAiB,QAAA,MAAW,QAAA,CAAA,sBAAA,EAAA,cAAA,CAAA,gBAAA,CAAA,cAAA,IAAA,wBAAA;EAtGtC;;;;;;;EAyHR,oBAAA,mBACoB,MAAA,gBAAsB,MAAA,cAAA,CAExC,OAAA,EACI,4BAAA,CAA6B,SAAA,aAC7B,cAAA,CAAe,SAAA,IACf,MAAA,eACJ,OAAA,GAAU,6BAAA,YAER,QAAA,CAAS,sBAAA,EAAwB,SAAA,IACjC,QAAA,CACE,sBAAA;IACE,GAAA,EAAK,WAAA;IAAa,MAAA,EAAQ,SAAA;EAAA;EAQ5B,SAAA,CACJ,QAAA,EAAU,WAAA,IACV,OAAA,8BACA,WAAA,GAAc,wBAAA,GACb,OAAA,CAAQ,UAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6FG,SAAA,CAAA,GAAa,cAAA"}
@@ -25,21 +25,23 @@ var FakeBuiltModel = class FakeBuiltModel extends BaseChatModel {
25
25
  _alwaysThrowError;
26
26
  _structuredResponseValue;
27
27
  _tools = [];
28
- _callIndex = 0;
29
- _calls = [];
28
+ _state = {
29
+ callIndex: 0,
30
+ calls: []
31
+ };
30
32
  /**
31
33
  * All invocations recorded by this model, in order.
32
34
  * Each entry contains the `messages` array and `options` that were
33
35
  * passed to `invoke()`.
34
36
  */
35
37
  get calls() {
36
- return this._calls;
38
+ return this._state.calls;
37
39
  }
38
40
  /**
39
41
  * The number of times this model has been invoked.
40
42
  */
41
43
  get callCount() {
42
- return this._calls.length;
44
+ return this._state.calls.length;
43
45
  }
44
46
  constructor() {
45
47
  super({});
@@ -122,8 +124,7 @@ var FakeBuiltModel = class FakeBuiltModel extends BaseChatModel {
122
124
  next._alwaysThrowError = this._alwaysThrowError;
123
125
  next._structuredResponseValue = this._structuredResponseValue;
124
126
  next._tools = merged;
125
- next._calls = this._calls;
126
- next._callIndex = this._callIndex;
127
+ next._state = this._state;
127
128
  return next.withConfig({});
128
129
  }
129
130
  /**
@@ -140,12 +141,12 @@ var FakeBuiltModel = class FakeBuiltModel extends BaseChatModel {
140
141
  });
141
142
  }
142
143
  async _generate(messages, options, _runManager) {
143
- this._calls.push({
144
+ this._state.calls.push({
144
145
  messages: [...messages],
145
146
  options
146
147
  });
147
- const currentCallIndex = this._callIndex;
148
- this._callIndex += 1;
148
+ const currentCallIndex = this._state.callIndex;
149
+ this._state.callIndex += 1;
149
150
  if (this._alwaysThrowError) throw this._alwaysThrowError;
150
151
  const entry = this.queue[currentCallIndex];
151
152
  if (!entry) throw new Error(`FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`);
@@ -1 +1 @@
1
- {"version":3,"file":"fake_model_builder.js","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _callIndex = 0;\n\n private _calls: FakeModelCall[] = [];\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._calls = this._calls;\n next._callIndex = this._callIndex;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._callIndex;\n this._callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fake_model_builder.js","names":[],"sources":["../../src/testing/fake_model_builder.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport { CallbackManagerForLLMRun } from \"../callbacks/manager.js\";\nimport {\n BaseChatModel,\n BaseChatModelCallOptions,\n} from \"../language_models/chat_models.js\";\nimport {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n StructuredOutputMethodParams,\n} from \"../language_models/base.js\";\nimport { BaseMessage, AIMessage } from \"../messages/index.js\";\nimport type { ToolCall } from \"../messages/tool.js\";\nimport type { ChatResult } from \"../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../runnables/base.js\";\nimport { StructuredTool } from \"../tools/index.js\";\nimport type { InteropZodType } from \"../utils/types/zod.js\";\nimport type { ToolSpec } from \"../utils/testing/chat_models.js\";\n\ntype ResponseFactory = (messages: BaseMessage[]) => BaseMessage | Error;\n\ntype QueueEntry =\n | { kind: \"message\"; message: BaseMessage }\n | { kind: \"toolCalls\"; toolCalls: ToolCall[] }\n | { kind: \"error\"; error: Error }\n | { kind: \"factory\"; factory: ResponseFactory };\n\ninterface FakeModelCall {\n messages: BaseMessage[];\n options: any;\n}\n\ninterface FakeModelState {\n callIndex: number;\n calls: FakeModelCall[];\n}\n\nfunction deriveContent(messages: BaseMessage[]): string {\n return messages\n .map((m) => m.text)\n .filter(Boolean)\n .join(\"-\");\n}\n\nlet idCounter = 0;\nfunction nextToolCallId(): string {\n idCounter += 1;\n return `fake_tc_${idCounter}`;\n}\n\n/**\n * A fake chat model for testing, created via {@link fakeModel}.\n *\n * Queue responses with `.respond()` and `.respondWithTools()`, then\n * pass the instance directly wherever a chat model is expected.\n * Responses are consumed in first-in-first-out order — one per `invoke()` call.\n * When all queued responses are consumed, further invocations throw.\n */\nexport class FakeBuiltModel extends BaseChatModel {\n private queue: QueueEntry[] = [];\n\n private _alwaysThrowError: Error | undefined;\n\n private _structuredResponseValue: any;\n\n private _tools: (StructuredTool | ToolSpec)[] = [];\n\n private _state: FakeModelState = { callIndex: 0, calls: [] };\n\n /**\n * All invocations recorded by this model, in order.\n * Each entry contains the `messages` array and `options` that were\n * passed to `invoke()`.\n */\n get calls(): FakeModelCall[] {\n return this._state.calls;\n }\n\n /**\n * The number of times this model has been invoked.\n */\n get callCount(): number {\n return this._state.calls.length;\n }\n\n constructor() {\n super({});\n }\n\n _llmType(): string {\n return \"fake-model-builder\";\n }\n\n _combineLLMOutput() {\n return [];\n }\n\n /**\n * Enqueue a response that the model will return on its next invocation.\n * @param entry A {@link BaseMessage} to return, an `Error` to throw, or\n * a factory `(messages) => BaseMessage | Error` for dynamic responses.\n * @returns `this`, for chaining.\n */\n respond(entry: BaseMessage | Error | ResponseFactory): this {\n if (typeof entry === \"function\") {\n this.queue.push({ kind: \"factory\", factory: entry });\n } else if (BaseMessage.isInstance(entry)) {\n this.queue.push({ kind: \"message\", message: entry });\n } else {\n this.queue.push({ kind: \"error\", error: entry });\n }\n return this;\n }\n\n /**\n * Enqueue an {@link AIMessage} that carries the given tool calls.\n * Content is derived from the input messages at invocation time.\n * @param toolCalls Array of tool calls. Each entry needs `name` and\n * `args`; `id` is optional and auto-generated when omitted.\n * @returns `this`, for chaining.\n */\n respondWithTools(\n toolCalls: Array<{ name: string; args: Record<string, any>; id?: string }>\n ): this {\n this.queue.push({\n kind: \"toolCalls\",\n toolCalls: toolCalls.map((tc) => ({\n name: tc.name,\n args: tc.args,\n id: tc.id ?? nextToolCallId(),\n type: \"tool_call\" as const,\n })),\n });\n return this;\n }\n\n /**\n * Make every invocation throw the given error, regardless of the queue.\n * @param error The error to throw.\n * @returns `this`, for chaining.\n */\n alwaysThrow(error: Error): this {\n this._alwaysThrowError = error;\n return this;\n }\n\n /**\n * Set the value that {@link withStructuredOutput} will resolve to.\n * @param value The structured object to return.\n * @returns `this`, for chaining.\n */\n structuredResponse(value: Record<string, any>): this {\n this._structuredResponseValue = value;\n return this;\n }\n\n /**\n * Bind tools to the model. Returns a new model that shares the same\n * response queue and call history.\n * @param tools The tools to bind, as {@link StructuredTool} instances or\n * plain {@link ToolSpec} objects.\n * @returns A new RunnableBinding with the tools bound.\n */\n bindTools(tools: (StructuredTool | ToolSpec)[]) {\n const merged = [...this._tools, ...tools];\n const next = new FakeBuiltModel();\n next.queue = this.queue;\n next._alwaysThrowError = this._alwaysThrowError;\n next._structuredResponseValue = this._structuredResponseValue;\n next._tools = merged;\n next._state = this._state;\n\n return next.withConfig({} as BaseChatModelCallOptions);\n }\n\n /**\n * Returns a {@link Runnable} that produces the {@link structuredResponse}\n * value. The schema argument is accepted for compatibility but ignored.\n * @param _params Schema or params (ignored).\n * @param _config Options (ignored).\n * @returns A Runnable that resolves to the structured response value.\n */\n withStructuredOutput<\n RunOutput extends Record<string, any> = Record<string, any>,\n >(\n _params:\n | StructuredOutputMethodParams<RunOutput, boolean>\n | InteropZodType<RunOutput>\n | Record<string, any>,\n _config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n const { _structuredResponseValue } = this;\n return RunnableLambda.from(async () => {\n return _structuredResponseValue as RunOutput;\n }) as Runnable;\n }\n\n async _generate(\n messages: BaseMessage[],\n options?: this[\"ParsedCallOptions\"],\n _runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n this._state.calls.push({ messages: [...messages], options });\n\n const currentCallIndex = this._state.callIndex;\n this._state.callIndex += 1;\n\n if (this._alwaysThrowError) {\n throw this._alwaysThrowError;\n }\n\n const entry = this.queue[currentCallIndex];\n if (!entry) {\n throw new Error(\n `FakeModel: no response queued for invocation ${currentCallIndex} (${this.queue.length} total queued).`\n );\n }\n\n if (entry.kind === \"error\") {\n throw entry.error;\n }\n\n if (entry.kind === \"factory\") {\n const result = entry.factory(messages);\n if (!BaseMessage.isInstance(result)) {\n throw result;\n }\n return {\n generations: [{ text: \"\", message: result }],\n };\n }\n\n if (entry.kind === \"message\") {\n return {\n generations: [{ text: \"\", message: entry.message }],\n };\n }\n\n const content = deriveContent(messages);\n const message = new AIMessage({\n content,\n id: currentCallIndex.toString(),\n tool_calls:\n entry.toolCalls.length > 0\n ? entry.toolCalls.map((tc) => ({\n ...tc,\n type: \"tool_call\" as const,\n }))\n : undefined,\n });\n\n return {\n generations: [{ text: content, message }],\n llmOutput: {},\n };\n }\n}\n\n/**\n * Creates a new {@link FakeBuiltModel} for testing.\n *\n * Returns a chainable builder — queue responses, then pass the model\n * anywhere a chat model is expected. Responses are consumed in FIFO\n * order, one per `invoke()` call.\n *\n * ## API summary\n *\n * | Method | Description |\n * | --- | --- |\n * | `fakeModel()` | Creates a new fake chat model. Returns a chainable builder. |\n * | `.respond(message)` | Queue an `AIMessage` (or any `BaseMessage`) to return on the next invocation. |\n * | `.respond(error)` | Queue an `Error` to throw on the next invocation. |\n * | `.respond(factory)` | Queue a function `(messages) => BaseMessage \\| Error` for dynamic responses. |\n * | `.respondWithTools(toolCalls)` | Shorthand for `.respond()` with tool calls. Each entry needs `name` and `args`; `id` is optional. |\n * | `.alwaysThrow(error)` | Make every invocation throw this error, regardless of the queue. |\n * | `.structuredResponse(value)` | Set the value returned by `.withStructuredOutput()`. |\n * | `.bindTools(tools)` | Bind tools to the model. Returns a `RunnableBinding` that shares the response queue and call recording. |\n * | `.withStructuredOutput(schema)` | Returns a runnable that produces the `.structuredResponse()` value. |\n * | `.calls` | Array of `{ messages, options }` for every invocation (read-only). |\n * | `.callCount` | Number of times the model has been invoked. |\n *\n * @example\n * ```typescript\n * const model = fakeModel()\n * .respondWithTools([{ name: \"search\", args: { query: \"weather\" } }])\n * .respond(new AIMessage(\"Sunny and warm.\"));\n *\n * const r1 = await model.invoke([new HumanMessage(\"What's the weather?\")]);\n * // r1.tool_calls[0].name === \"search\"\n *\n * const r2 = await model.invoke([new HumanMessage(\"Thanks\")]);\n * // r2.content === \"Sunny and warm.\"\n * ```\n */\nexport function fakeModel(): FakeBuiltModel {\n return new FakeBuiltModel();\n}\n"],"mappings":";;;;;;AAqCA,SAAS,cAAc,UAAiC;AACtD,QAAO,SACJ,KAAK,MAAM,EAAE,KAAK,CAClB,OAAO,QAAQ,CACf,KAAK,IAAI;;AAGd,IAAI,YAAY;AAChB,SAAS,iBAAyB;AAChC,cAAa;AACb,QAAO,WAAW;;;;;;;;;;AAWpB,IAAa,iBAAb,MAAa,uBAAuB,cAAc;CAChD,QAA8B,EAAE;CAEhC;CAEA;CAEA,SAAgD,EAAE;CAElD,SAAiC;EAAE,WAAW;EAAG,OAAO,EAAE;EAAE;;;;;;CAO5D,IAAI,QAAyB;AAC3B,SAAO,KAAK,OAAO;;;;;CAMrB,IAAI,YAAoB;AACtB,SAAO,KAAK,OAAO,MAAM;;CAG3B,cAAc;AACZ,QAAM,EAAE,CAAC;;CAGX,WAAmB;AACjB,SAAO;;CAGT,oBAAoB;AAClB,SAAO,EAAE;;;;;;;;CASX,QAAQ,OAAoD;AAC1D,MAAI,OAAO,UAAU,WACnB,MAAK,MAAM,KAAK;GAAE,MAAM;GAAW,SAAS;GAAO,CAAC;WAC3C,YAAY,WAAW,MAAM,CACtC,MAAK,MAAM,KAAK;GAAE,MAAM;GAAW,SAAS;GAAO,CAAC;MAEpD,MAAK,MAAM,KAAK;GAAE,MAAM;GAAS,OAAO;GAAO,CAAC;AAElD,SAAO;;;;;;;;;CAUT,iBACE,WACM;AACN,OAAK,MAAM,KAAK;GACd,MAAM;GACN,WAAW,UAAU,KAAK,QAAQ;IAChC,MAAM,GAAG;IACT,MAAM,GAAG;IACT,IAAI,GAAG,MAAM,gBAAgB;IAC7B,MAAM;IACP,EAAE;GACJ,CAAC;AACF,SAAO;;;;;;;CAQT,YAAY,OAAoB;AAC9B,OAAK,oBAAoB;AACzB,SAAO;;;;;;;CAQT,mBAAmB,OAAkC;AACnD,OAAK,2BAA2B;AAChC,SAAO;;;;;;;;;CAUT,UAAU,OAAsC;EAC9C,MAAM,SAAS,CAAC,GAAG,KAAK,QAAQ,GAAG,MAAM;EACzC,MAAM,OAAO,IAAI,gBAAgB;AACjC,OAAK,QAAQ,KAAK;AAClB,OAAK,oBAAoB,KAAK;AAC9B,OAAK,2BAA2B,KAAK;AACrC,OAAK,SAAS;AACd,OAAK,SAAS,KAAK;AAEnB,SAAO,KAAK,WAAW,EAAE,CAA6B;;;;;;;;;CAUxD,qBAGE,SAIA,SAMI;EACJ,MAAM,EAAE,6BAA6B;AACrC,SAAO,eAAe,KAAK,YAAY;AACrC,UAAO;IACP;;CAGJ,MAAM,UACJ,UACA,SACA,aACqB;AACrB,OAAK,OAAO,MAAM,KAAK;GAAE,UAAU,CAAC,GAAG,SAAS;GAAE;GAAS,CAAC;EAE5D,MAAM,mBAAmB,KAAK,OAAO;AACrC,OAAK,OAAO,aAAa;AAEzB,MAAI,KAAK,kBACP,OAAM,KAAK;EAGb,MAAM,QAAQ,KAAK,MAAM;AACzB,MAAI,CAAC,MACH,OAAM,IAAI,MACR,gDAAgD,iBAAiB,IAAI,KAAK,MAAM,OAAO,iBACxF;AAGH,MAAI,MAAM,SAAS,QACjB,OAAM,MAAM;AAGd,MAAI,MAAM,SAAS,WAAW;GAC5B,MAAM,SAAS,MAAM,QAAQ,SAAS;AACtC,OAAI,CAAC,YAAY,WAAW,OAAO,CACjC,OAAM;AAER,UAAO,EACL,aAAa,CAAC;IAAE,MAAM;IAAI,SAAS;IAAQ,CAAC,EAC7C;;AAGH,MAAI,MAAM,SAAS,UACjB,QAAO,EACL,aAAa,CAAC;GAAE,MAAM;GAAI,SAAS,MAAM;GAAS,CAAC,EACpD;EAGH,MAAM,UAAU,cAAc,SAAS;AAavC,SAAO;GACL,aAAa,CAAC;IAAE,MAAM;IAAS,SAbjB,IAAI,UAAU;KAC5B;KACA,IAAI,iBAAiB,UAAU;KAC/B,YACE,MAAM,UAAU,SAAS,IACrB,MAAM,UAAU,KAAK,QAAQ;MAC3B,GAAG;MACH,MAAM;MACP,EAAE,GACH,KAAA;KACP,CAAC;IAGwC,CAAC;GACzC,WAAW,EAAE;GACd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCL,SAAgB,YAA4B;AAC1C,QAAO,IAAI,gBAAgB"}
@@ -8,37 +8,51 @@ const require_stringify = require("./stringify.cjs");
8
8
  const require_v1 = require("./v1.cjs");
9
9
  const require_v4 = require("./v4.cjs");
10
10
  const require_v5 = require("./v5.cjs");
11
+ const require_v6 = require("./v6.cjs");
11
12
  const require_v7 = require("./v7.cjs");
12
13
  const require_version = require("./version.cjs");
13
14
  //#region src/utils/uuid/index.ts
14
15
  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
16
+ MAX: () => MAX,
17
+ NIL: () => NIL,
18
+ parse: () => parse,
19
+ stringify: () => stringify,
20
+ v1: () => v1,
21
+ v4: () => v4,
22
+ v5: () => v5,
23
+ v6: () => v6,
24
+ v7: () => v7,
25
+ validate: () => validate,
26
+ version: () => version
25
27
  });
28
+ const MAX = require_max.default;
29
+ const NIL = require_nil.default;
30
+ const parse = require_parse.default;
31
+ const stringify = require_stringify.default;
32
+ const v1 = require_v1.default;
33
+ const v4 = require_v4.default;
34
+ const v5 = require_v5.default;
35
+ const v6 = require_v6.default;
36
+ const v7 = require_v7.default;
37
+ const validate = require_validate.default;
38
+ const version = require_version.default;
26
39
  //#endregion
27
- exports.MAX = require_max;
28
- exports.NIL = require_nil;
29
- exports.parse = require_parse;
30
- exports.stringify = require_stringify;
40
+ exports.MAX = MAX;
41
+ exports.NIL = NIL;
42
+ exports.parse = parse;
43
+ exports.stringify = stringify;
31
44
  Object.defineProperty(exports, "uuid_exports", {
32
45
  enumerable: true,
33
46
  get: function() {
34
47
  return uuid_exports;
35
48
  }
36
49
  });
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;
50
+ exports.v1 = v1;
51
+ exports.v4 = v4;
52
+ exports.v5 = v5;
53
+ exports.v6 = v6;
54
+ exports.v7 = v7;
55
+ exports.validate = validate;
56
+ exports.version = version;
43
57
 
44
58
  //# sourceMappingURL=index.cjs.map
@@ -1 +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":""}
1
+ {"version":3,"file":"index.cjs","names":["_MAX","_NIL","_parse","_stringify","_v1","_v4","_v5","_v6","_v7","_validate","_version"],"sources":["../../../src/utils/uuid/index.ts"],"sourcesContent":["import _MAX from \"./max.js\";\nimport _NIL from \"./nil.js\";\nimport _parse from \"./parse.js\";\nimport _stringify from \"./stringify.js\";\nimport _v1 from \"./v1.js\";\nimport _v4 from \"./v4.js\";\nimport _v5 from \"./v5.js\";\nimport _v6 from \"./v6.js\";\nimport _v7 from \"./v7.js\";\nimport _validate from \"./validate.js\";\nimport _version from \"./version.js\";\n\nexport type * from \"./types.js\";\n\nexport const MAX = _MAX;\nexport const NIL = _NIL;\nexport const parse = _parse;\nexport const stringify = _stringify;\nexport const v1 = _v1;\nexport const v4 = _v4;\nexport const v5 = _v5;\nexport const v6 = _v6;\nexport const v7 = _v7;\nexport const validate = _validate;\nexport const version = _version;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAa,MAAMA,YAAAA;AACnB,MAAa,MAAMC,YAAAA;AACnB,MAAa,QAAQC,cAAAA;AACrB,MAAa,YAAYC,kBAAAA;AACzB,MAAa,KAAKC,WAAAA;AAClB,MAAa,KAAKC,WAAAA;AAClB,MAAa,KAAKC,WAAAA;AAClB,MAAa,KAAKC,WAAAA;AAClB,MAAa,KAAKC,WAAAA;AAClB,MAAa,WAAWC,iBAAAA;AACxB,MAAa,UAAUC,gBAAAA"}
@@ -1,12 +1,26 @@
1
- import { _default } from "./max.cjs";
2
- import { _default as _default$1 } from "./nil.cjs";
3
1
  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 };
2
+ import { parse as parse$1 } from "./parse.cjs";
3
+ import { stringify as stringify$1 } from "./stringify.cjs";
4
+ import { v1 as v1$1 } from "./v1.cjs";
5
+ import { v4 as v4$1 } from "./v4.cjs";
6
+ import { v5 as v5$1 } from "./v5.cjs";
7
+ import { v6 as v6$1 } from "./v6.cjs";
8
+ import { v7 as v7$1 } from "./v7.cjs";
9
+ import { validate as validate$1 } from "./validate.cjs";
10
+ import { version as version$1 } from "./version.cjs";
11
+
12
+ //#region src/utils/uuid/index.d.ts
13
+ declare const MAX = "ffffffff-ffff-ffff-ffff-ffffffffffff";
14
+ declare const NIL = "00000000-0000-0000-0000-000000000000";
15
+ declare const parse: typeof parse$1;
16
+ declare const stringify: typeof stringify$1;
17
+ declare const v1: typeof v1$1;
18
+ declare const v4: typeof v4$1;
19
+ declare const v5: typeof v5$1;
20
+ declare const v6: typeof v6$1;
21
+ declare const v7: typeof v7$1;
22
+ declare const validate: typeof validate$1;
23
+ declare const version: typeof version$1;
24
+ //#endregion
25
+ export { MAX, NIL, NonSharedArrayBuffer, UUIDTypes, Version1Options, Version4Options, Version6Options, Version7Options, parse, stringify, v1, v4, v5, v6, v7, validate, version };
26
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/utils/uuid/index.ts"],"mappings":";;;;;;;;;;;;cAca,GAAA;AAAA,cACA,GAAA;AAAA,cACA,KAAA,SAAK,OAAA;AAAA,cACL,SAAA,SAAS,WAAA;AAAA,cACT,EAAA,SAAE,IAAA;AAAA,cACF,EAAA,SAAE,IAAA;AAAA,cACF,EAAA,SAAE,IAAA;AAAA,cACF,EAAA,SAAE,IAAA;AAAA,cACF,EAAA,SAAE,IAAA;AAAA,cACF,QAAA,SAAQ,UAAA;AAAA,cACR,OAAA,SAAO,SAAA"}