@langchain/core 0.1.21 → 0.1.23

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.
@@ -20,3 +20,4 @@ __exportStar(require("./list.cjs"), exports);
20
20
  __exportStar(require("./string.cjs"), exports);
21
21
  __exportStar(require("./transform.cjs"), exports);
22
22
  __exportStar(require("./json.cjs"), exports);
23
+ __exportStar(require("./xml.cjs"), exports);
@@ -4,3 +4,4 @@ export * from "./list.js";
4
4
  export * from "./string.js";
5
5
  export * from "./transform.js";
6
6
  export * from "./json.js";
7
+ export * from "./xml.js";
@@ -4,3 +4,4 @@ export * from "./list.js";
4
4
  export * from "./string.js";
5
5
  export * from "./transform.js";
6
6
  export * from "./json.js";
7
+ export * from "./xml.js";
@@ -57,7 +57,7 @@ function parseJsonMarkdown(s, parser = parsePartialJson) {
57
57
  }
58
58
  }
59
59
  exports.parseJsonMarkdown = parseJsonMarkdown;
60
- // Adapted from https://github.com/KillianLucas/open-interpreter/blob/main/interpreter/utils/parse_partial_json.py
60
+ // Adapted from https://github.com/KillianLucas/open-interpreter/blob/main/interpreter/core/llm/utils/parse_partial_json.py
61
61
  // MIT License
62
62
  function parsePartialJson(s) {
63
63
  // If the input is undefined, return null to indicate failure.
@@ -52,7 +52,7 @@ export function parseJsonMarkdown(s, parser = parsePartialJson) {
52
52
  return parser(match[2]);
53
53
  }
54
54
  }
55
- // Adapted from https://github.com/KillianLucas/open-interpreter/blob/main/interpreter/utils/parse_partial_json.py
55
+ // Adapted from https://github.com/KillianLucas/open-interpreter/blob/main/interpreter/core/llm/utils/parse_partial_json.py
56
56
  // MIT License
57
57
  export function parsePartialJson(s) {
58
58
  // If the input is undefined, return null to indicate failure.
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseXMLMarkdown = exports.XMLOutputParser = exports.XML_FORMAT_INSTRUCTIONS = void 0;
7
+ const sax_1 = __importDefault(require("sax"));
8
+ const transform_js_1 = require("./transform.cjs");
9
+ const json_patch_js_1 = require("../utils/json_patch.cjs");
10
+ exports.XML_FORMAT_INSTRUCTIONS = `The output should be formatted as a XML file.
11
+ 1. Output should conform to the tags below.
12
+ 2. If tags are not given, make them on your own.
13
+ 3. Remember to always open and close all the tags.
14
+
15
+ As an example, for the tags ["foo", "bar", "baz"]:
16
+ 1. String "<foo>\n <bar>\n <baz></baz>\n </bar>\n</foo>" is a well-formatted instance of the schema.
17
+ 2. String "<foo>\n <bar>\n </foo>" is a badly-formatted instance.
18
+ 3. String "<foo>\n <tag>\n </tag>\n</foo>" is a badly-formatted instance.
19
+
20
+ Here are the output tags:
21
+ \`\`\`
22
+ {tags}
23
+ \`\`\``;
24
+ class XMLOutputParser extends transform_js_1.BaseCumulativeTransformOutputParser {
25
+ constructor(fields) {
26
+ const f = fields ?? {};
27
+ const { tags, ...saxOptions } = f;
28
+ super(f);
29
+ Object.defineProperty(this, "tags", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: void 0
34
+ });
35
+ Object.defineProperty(this, "saxOptions", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: void 0
40
+ });
41
+ Object.defineProperty(this, "lc_namespace", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: ["langchain_core", "output_parsers"]
46
+ });
47
+ Object.defineProperty(this, "lc_serializable", {
48
+ enumerable: true,
49
+ configurable: true,
50
+ writable: true,
51
+ value: true
52
+ });
53
+ this.tags = tags;
54
+ this.saxOptions = saxOptions;
55
+ }
56
+ static lc_name() {
57
+ return "XMLOutputParser";
58
+ }
59
+ _diff(prev, next) {
60
+ if (!next) {
61
+ return undefined;
62
+ }
63
+ if (!prev) {
64
+ return [{ op: "replace", path: "", value: next }];
65
+ }
66
+ return (0, json_patch_js_1.compare)(prev, next);
67
+ }
68
+ async parsePartialResult(generations) {
69
+ return parseXMLMarkdown(generations[0].text, this.saxOptions);
70
+ }
71
+ async parse(text) {
72
+ return parseXMLMarkdown(text, this.saxOptions);
73
+ }
74
+ getFormatInstructions() {
75
+ const withTags = !!(this.tags && this.tags.length > 0);
76
+ return withTags
77
+ ? exports.XML_FORMAT_INSTRUCTIONS.replace("{tags}", this.tags?.join(", ") ?? "")
78
+ : exports.XML_FORMAT_INSTRUCTIONS;
79
+ }
80
+ }
81
+ exports.XMLOutputParser = XMLOutputParser;
82
+ const strip = (text) => text
83
+ .split("\n")
84
+ .map((line) => line.replace(/^\s+/, ""))
85
+ .join("\n")
86
+ .trim();
87
+ const parseParsedResult = (input) => {
88
+ if (Object.keys(input).length === 0) {
89
+ return {};
90
+ }
91
+ const result = {};
92
+ if (input.children.length > 0) {
93
+ result[input.name] = input.children.map(parseParsedResult);
94
+ return result;
95
+ }
96
+ else {
97
+ result[input.name] = input.text ?? undefined;
98
+ return result;
99
+ }
100
+ };
101
+ function parseXMLMarkdown(s, saxOptions) {
102
+ const cleanedString = strip(s);
103
+ const parser = sax_1.default.parser(true, saxOptions);
104
+ let parsedResult = {};
105
+ const elementStack = [];
106
+ parser.onopentag = (node) => {
107
+ const element = {
108
+ name: node.name,
109
+ attributes: node.attributes,
110
+ children: [],
111
+ text: "",
112
+ isSelfClosing: node.isSelfClosing,
113
+ };
114
+ if (elementStack.length > 0) {
115
+ const parentElement = elementStack[elementStack.length - 1];
116
+ parentElement.children.push(element);
117
+ }
118
+ else {
119
+ parsedResult = element;
120
+ }
121
+ if (!node.isSelfClosing) {
122
+ elementStack.push(element);
123
+ }
124
+ };
125
+ parser.onclosetag = () => {
126
+ if (elementStack.length > 0) {
127
+ const lastElement = elementStack.pop();
128
+ if (elementStack.length === 0 && lastElement) {
129
+ parsedResult = lastElement;
130
+ }
131
+ }
132
+ };
133
+ parser.ontext = (text) => {
134
+ if (elementStack.length > 0) {
135
+ const currentElement = elementStack[elementStack.length - 1];
136
+ currentElement.text += text;
137
+ }
138
+ };
139
+ parser.onattribute = (attr) => {
140
+ if (elementStack.length > 0) {
141
+ const currentElement = elementStack[elementStack.length - 1];
142
+ currentElement.attributes[attr.name] = attr.value;
143
+ }
144
+ };
145
+ // Try to find XML string within triple backticks.
146
+ const match = /```(xml)?(.*)```/s.exec(cleanedString);
147
+ const xmlString = match ? match[2] : cleanedString;
148
+ parser.write(xmlString).close();
149
+ // Remove the XML declaration if present
150
+ if (parsedResult && parsedResult.name === "?xml") {
151
+ parsedResult = parsedResult.children[0];
152
+ }
153
+ return parseParsedResult(parsedResult);
154
+ }
155
+ exports.parseXMLMarkdown = parseXMLMarkdown;
@@ -0,0 +1,31 @@
1
+ import { SAXOptions } from "sax";
2
+ import { BaseCumulativeTransformOutputParser, BaseCumulativeTransformOutputParserInput } from "./transform.js";
3
+ import { Operation } from "../utils/json_patch.js";
4
+ import { ChatGeneration, Generation } from "../outputs.js";
5
+ export declare const XML_FORMAT_INSTRUCTIONS = "The output should be formatted as a XML file.\n1. Output should conform to the tags below. \n2. If tags are not given, make them on your own.\n3. Remember to always open and close all the tags.\n\nAs an example, for the tags [\"foo\", \"bar\", \"baz\"]:\n1. String \"<foo>\n <bar>\n <baz></baz>\n </bar>\n</foo>\" is a well-formatted instance of the schema. \n2. String \"<foo>\n <bar>\n </foo>\" is a badly-formatted instance.\n3. String \"<foo>\n <tag>\n </tag>\n</foo>\" is a badly-formatted instance.\n\nHere are the output tags:\n```\n{tags}\n```";
6
+ export interface XMLOutputParserFields extends SAXOptions, BaseCumulativeTransformOutputParserInput {
7
+ /**
8
+ * Optional list of tags that the output should conform to.
9
+ * Only used in formatting of the prompt.
10
+ */
11
+ tags?: string[];
12
+ }
13
+ export type Content = string | undefined | Array<{
14
+ [key: string]: Content;
15
+ }>;
16
+ export type XMLResult = {
17
+ [key: string]: Content;
18
+ };
19
+ export declare class XMLOutputParser extends BaseCumulativeTransformOutputParser<XMLResult> {
20
+ tags?: string[];
21
+ saxOptions?: SAXOptions;
22
+ constructor(fields?: XMLOutputParserFields);
23
+ static lc_name(): string;
24
+ lc_namespace: string[];
25
+ lc_serializable: boolean;
26
+ protected _diff(prev: unknown | undefined, next: unknown): Operation[] | undefined;
27
+ parsePartialResult(generations: ChatGeneration[] | Generation[]): Promise<XMLResult | undefined>;
28
+ parse(text: string): Promise<XMLResult>;
29
+ getFormatInstructions(): string;
30
+ }
31
+ export declare function parseXMLMarkdown(s: string, saxOptions?: SAXOptions): XMLResult;
@@ -0,0 +1,147 @@
1
+ import sax from "sax";
2
+ import { BaseCumulativeTransformOutputParser, } from "./transform.js";
3
+ import { compare } from "../utils/json_patch.js";
4
+ export const XML_FORMAT_INSTRUCTIONS = `The output should be formatted as a XML file.
5
+ 1. Output should conform to the tags below.
6
+ 2. If tags are not given, make them on your own.
7
+ 3. Remember to always open and close all the tags.
8
+
9
+ As an example, for the tags ["foo", "bar", "baz"]:
10
+ 1. String "<foo>\n <bar>\n <baz></baz>\n </bar>\n</foo>" is a well-formatted instance of the schema.
11
+ 2. String "<foo>\n <bar>\n </foo>" is a badly-formatted instance.
12
+ 3. String "<foo>\n <tag>\n </tag>\n</foo>" is a badly-formatted instance.
13
+
14
+ Here are the output tags:
15
+ \`\`\`
16
+ {tags}
17
+ \`\`\``;
18
+ export class XMLOutputParser extends BaseCumulativeTransformOutputParser {
19
+ constructor(fields) {
20
+ const f = fields ?? {};
21
+ const { tags, ...saxOptions } = f;
22
+ super(f);
23
+ Object.defineProperty(this, "tags", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: void 0
28
+ });
29
+ Object.defineProperty(this, "saxOptions", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: void 0
34
+ });
35
+ Object.defineProperty(this, "lc_namespace", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: ["langchain_core", "output_parsers"]
40
+ });
41
+ Object.defineProperty(this, "lc_serializable", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: true
46
+ });
47
+ this.tags = tags;
48
+ this.saxOptions = saxOptions;
49
+ }
50
+ static lc_name() {
51
+ return "XMLOutputParser";
52
+ }
53
+ _diff(prev, next) {
54
+ if (!next) {
55
+ return undefined;
56
+ }
57
+ if (!prev) {
58
+ return [{ op: "replace", path: "", value: next }];
59
+ }
60
+ return compare(prev, next);
61
+ }
62
+ async parsePartialResult(generations) {
63
+ return parseXMLMarkdown(generations[0].text, this.saxOptions);
64
+ }
65
+ async parse(text) {
66
+ return parseXMLMarkdown(text, this.saxOptions);
67
+ }
68
+ getFormatInstructions() {
69
+ const withTags = !!(this.tags && this.tags.length > 0);
70
+ return withTags
71
+ ? XML_FORMAT_INSTRUCTIONS.replace("{tags}", this.tags?.join(", ") ?? "")
72
+ : XML_FORMAT_INSTRUCTIONS;
73
+ }
74
+ }
75
+ const strip = (text) => text
76
+ .split("\n")
77
+ .map((line) => line.replace(/^\s+/, ""))
78
+ .join("\n")
79
+ .trim();
80
+ const parseParsedResult = (input) => {
81
+ if (Object.keys(input).length === 0) {
82
+ return {};
83
+ }
84
+ const result = {};
85
+ if (input.children.length > 0) {
86
+ result[input.name] = input.children.map(parseParsedResult);
87
+ return result;
88
+ }
89
+ else {
90
+ result[input.name] = input.text ?? undefined;
91
+ return result;
92
+ }
93
+ };
94
+ export function parseXMLMarkdown(s, saxOptions) {
95
+ const cleanedString = strip(s);
96
+ const parser = sax.parser(true, saxOptions);
97
+ let parsedResult = {};
98
+ const elementStack = [];
99
+ parser.onopentag = (node) => {
100
+ const element = {
101
+ name: node.name,
102
+ attributes: node.attributes,
103
+ children: [],
104
+ text: "",
105
+ isSelfClosing: node.isSelfClosing,
106
+ };
107
+ if (elementStack.length > 0) {
108
+ const parentElement = elementStack[elementStack.length - 1];
109
+ parentElement.children.push(element);
110
+ }
111
+ else {
112
+ parsedResult = element;
113
+ }
114
+ if (!node.isSelfClosing) {
115
+ elementStack.push(element);
116
+ }
117
+ };
118
+ parser.onclosetag = () => {
119
+ if (elementStack.length > 0) {
120
+ const lastElement = elementStack.pop();
121
+ if (elementStack.length === 0 && lastElement) {
122
+ parsedResult = lastElement;
123
+ }
124
+ }
125
+ };
126
+ parser.ontext = (text) => {
127
+ if (elementStack.length > 0) {
128
+ const currentElement = elementStack[elementStack.length - 1];
129
+ currentElement.text += text;
130
+ }
131
+ };
132
+ parser.onattribute = (attr) => {
133
+ if (elementStack.length > 0) {
134
+ const currentElement = elementStack[elementStack.length - 1];
135
+ currentElement.attributes[attr.name] = attr.value;
136
+ }
137
+ };
138
+ // Try to find XML string within triple backticks.
139
+ const match = /```(xml)?(.*)```/s.exec(cleanedString);
140
+ const xmlString = match ? match[2] : cleanedString;
141
+ parser.write(xmlString).close();
142
+ // Remove the XML declaration if present
143
+ if (parsedResult && parsedResult.name === "?xml") {
144
+ parsedResult = parsedResult.children[0];
145
+ }
146
+ return parseParsedResult(parsedResult);
147
+ }
@@ -1084,7 +1084,7 @@ class RunnableLambda extends Runnable {
1084
1084
  });
1085
1085
  }
1086
1086
  async _invoke(input, config, runManager) {
1087
- let output = await this.func(input, { config });
1087
+ let output = await this.func(input, { ...config, config });
1088
1088
  if (output && Runnable.isRunnable(output)) {
1089
1089
  if (config?.recursionLimit === 0) {
1090
1090
  throw new Error("Recursion limit reached.");
@@ -1116,7 +1116,7 @@ class RunnableLambda extends Runnable {
1116
1116
  }
1117
1117
  }
1118
1118
  }
1119
- const output = await this.func(finalChunk, { config });
1119
+ const output = await this.func(finalChunk, { ...config, config });
1120
1120
  if (output && Runnable.isRunnable(output)) {
1121
1121
  if (config?.recursionLimit === 0) {
1122
1122
  throw new Error("Recursion limit reached.");
@@ -23,11 +23,11 @@ export interface RunnableInterface<RunInput = any, RunOutput = any, CallOptions
23
23
  stream(input: RunInput, options?: Partial<CallOptions>): Promise<IterableReadableStreamInterface<RunOutput>>;
24
24
  transform(generator: AsyncGenerator<RunInput>, options: Partial<CallOptions>): AsyncGenerator<RunOutput>;
25
25
  }
26
- export type RunnableFunc<RunInput, RunOutput> = (input: RunInput, options?: {
26
+ export type RunnableFunc<RunInput, RunOutput> = (input: RunInput, options?: ({
27
27
  config?: RunnableConfig;
28
- } | Record<string, any> | (Record<string, any> & {
28
+ } & RunnableConfig) | Record<string, any> | (Record<string, any> & {
29
29
  config: RunnableConfig;
30
- })) => RunOutput | Promise<RunOutput>;
30
+ } & RunnableConfig)) => RunOutput | Promise<RunOutput>;
31
31
  export type RunnableMapLike<RunInput, RunOutput> = {
32
32
  [K in keyof RunOutput]: RunnableLike<RunInput, RunOutput[K]>;
33
33
  };
@@ -1071,7 +1071,7 @@ export class RunnableLambda extends Runnable {
1071
1071
  });
1072
1072
  }
1073
1073
  async _invoke(input, config, runManager) {
1074
- let output = await this.func(input, { config });
1074
+ let output = await this.func(input, { ...config, config });
1075
1075
  if (output && Runnable.isRunnable(output)) {
1076
1076
  if (config?.recursionLimit === 0) {
1077
1077
  throw new Error("Recursion limit reached.");
@@ -1103,7 +1103,7 @@ export class RunnableLambda extends Runnable {
1103
1103
  }
1104
1104
  }
1105
1105
  }
1106
- const output = await this.func(finalChunk, { config });
1106
+ const output = await this.func(finalChunk, { ...config, config });
1107
1107
  if (output && Runnable.isRunnable(output)) {
1108
1108
  if (config?.recursionLimit === 0) {
1109
1109
  throw new Error("Recursion limit reached.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/core",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "Core LangChain.js abstractions and schemas",
5
5
  "type": "module",
6
6
  "engines": {
@@ -12,6 +12,7 @@
12
12
  "type": "git",
13
13
  "url": "git@github.com:langchain-ai/langchainjs.git"
14
14
  },
15
+ "homepage": "https://github.com/langchain-ai/langchainjs/tree/main/langchain-core/",
15
16
  "scripts": {
16
17
  "build": "yarn clean && yarn build:esm && yarn build:cjs && yarn run build:scripts",
17
18
  "build:esm": "NODE_OPTIONS=--max-old-space-size=4096 tsc --outDir dist/ && rimraf dist/tests dist/**/tests",
@@ -22,7 +23,7 @@
22
23
  "lint:dpdm": "dpdm --exit-code circular:1 --no-warning --no-tree src/*.ts src/**/*.ts",
23
24
  "lint": "yarn lint:eslint && yarn lint:dpdm",
24
25
  "lint:fix": "yarn lint:eslint --fix && yarn lint:dpdm",
25
- "clean": "rimraf .turbo/ dist/ && NODE_OPTIONS=--max-old-space-size=4096 yarn create-entrypoints -- --pre",
26
+ "clean": "rimraf .turbo/ dist/ && NODE_OPTIONS=--max-old-space-size=4096 yarn lc-build --config ./langchain.config.js --create-entrypoints --pre",
26
27
  "prepack": "yarn build",
27
28
  "release": "release-it --only-version --config .release-it.json",
28
29
  "test": "NODE_OPTIONS=--experimental-vm-modules jest --testPathIgnorePatterns=\\.int\\.test.ts --testTimeout 30000 --maxWorkers=50%",
@@ -45,6 +46,7 @@
45
46
  "ml-distance": "^4.0.0",
46
47
  "p-queue": "^6.6.2",
47
48
  "p-retry": "4",
49
+ "sax": "^1.3.0",
48
50
  "uuid": "^9.0.0",
49
51
  "zod": "^3.22.4",
50
52
  "zod-to-json-schema": "^3.22.3"
@@ -54,6 +56,7 @@
54
56
  "@langchain/scripts": "~0.0",
55
57
  "@swc/core": "^1.3.90",
56
58
  "@swc/jest": "^0.2.29",
59
+ "@types/sax": "^1",
57
60
  "dpdm": "^3.12.0",
58
61
  "eslint": "^8.33.0",
59
62
  "eslint-config-airbnb-base": "^15.0.0",