langchain 0.2.18 → 0.2.20

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.
@@ -133,7 +133,9 @@ function convertOpenAPISchemaToJSONSchema(schema, spec) {
133
133
  }
134
134
  // eslint-disable-next-line no-param-reassign
135
135
  jsonSchema.properties[propertyName] = convertOpenAPISchemaToJSONSchema(openAPIProperty, spec);
136
- if (openAPIProperty.required && jsonSchema.required !== undefined) {
136
+ if ((openAPIProperty.required ||
137
+ schema.required?.includes(propertyName)) &&
138
+ jsonSchema.required !== undefined) {
137
139
  jsonSchema.required.push(propertyName);
138
140
  }
139
141
  return jsonSchema;
@@ -130,7 +130,9 @@ export function convertOpenAPISchemaToJSONSchema(schema, spec) {
130
130
  }
131
131
  // eslint-disable-next-line no-param-reassign
132
132
  jsonSchema.properties[propertyName] = convertOpenAPISchemaToJSONSchema(openAPIProperty, spec);
133
- if (openAPIProperty.required && jsonSchema.required !== undefined) {
133
+ if ((openAPIProperty.required ||
134
+ schema.required?.includes(propertyName)) &&
135
+ jsonSchema.required !== undefined) {
134
136
  jsonSchema.required.push(propertyName);
135
137
  }
136
138
  return jsonSchema;
@@ -102,7 +102,7 @@ class PlanAndExecuteAgentExecutor extends base_js_1.BaseChain {
102
102
  */
103
103
  static getDefaultStepExecutor({ llm, tools, humanMessageTemplate = prompt_js_1.DEFAULT_STEP_EXECUTOR_HUMAN_CHAT_MESSAGE_TEMPLATE, }) {
104
104
  let agent;
105
- if (isDynamicStructuredTool(tools[0])) {
105
+ if (tools.length > 0 && isDynamicStructuredTool(tools[0])) {
106
106
  agent = index_js_2.StructuredChatAgent.fromLLMAndTools(llm, tools, {
107
107
  humanMessageTemplate,
108
108
  inputVariables: ["previous_steps", "current_step", "agent_scratchpad"],
@@ -98,7 +98,7 @@ export class PlanAndExecuteAgentExecutor extends BaseChain {
98
98
  */
99
99
  static getDefaultStepExecutor({ llm, tools, humanMessageTemplate = DEFAULT_STEP_EXECUTOR_HUMAN_CHAT_MESSAGE_TEMPLATE, }) {
100
100
  let agent;
101
- if (isDynamicStructuredTool(tools[0])) {
101
+ if (tools.length > 0 && isDynamicStructuredTool(tools[0])) {
102
102
  agent = StructuredChatAgent.fromLLMAndTools(llm, tools, {
103
103
  humanMessageTemplate,
104
104
  inputVariables: ["previous_steps", "current_step", "agent_scratchpad"],
@@ -51,6 +51,11 @@ const stores_1 = require("@langchain/core/stores");
51
51
  * await store.mdelete([key]);
52
52
  * }
53
53
  * ```
54
+ *
55
+ * @security **Security Notice** This file store
56
+ * can alter any text file in the provided directory and any subfolders.
57
+ * Make sure that the path you specify when initializing the store is free
58
+ * of other files.
54
59
  */
55
60
  class LocalFileStore extends stores_1.BaseStore {
56
61
  constructor(fields) {
@@ -75,6 +80,10 @@ class LocalFileStore extends stores_1.BaseStore {
75
80
  * @returns Promise that resolves to the parsed file content.
76
81
  */
77
82
  async getParsedFile(key) {
83
+ // Validate the key to prevent path traversal
84
+ if (!/^[a-zA-Z0-9_\-:.]+$/.test(key)) {
85
+ throw new Error("Invalid key. Only alphanumeric characters, underscores, hyphens, colons, and periods are allowed.");
86
+ }
78
87
  try {
79
88
  const fileContent = await fs.readFile(this.getFullPath(key));
80
89
  if (!fileContent) {
@@ -111,11 +120,20 @@ class LocalFileStore extends stores_1.BaseStore {
111
120
  getFullPath(key) {
112
121
  try {
113
122
  const keyAsTxtFile = `${key}.txt`;
114
- const fullPath = path.join(this.rootPath, keyAsTxtFile);
123
+ // Validate the key to prevent path traversal
124
+ if (!/^[a-zA-Z0-9_.\-/]+$/.test(key)) {
125
+ throw new Error(`Invalid characters in key: ${key}`);
126
+ }
127
+ const fullPath = path.resolve(this.rootPath, keyAsTxtFile);
128
+ const commonPath = path.resolve(this.rootPath);
129
+ if (!fullPath.startsWith(commonPath)) {
130
+ throw new Error(`Invalid key: ${key}. Key should be relative to the root path. ` +
131
+ `Root path: ${this.rootPath}, Full path: ${fullPath}`);
132
+ }
115
133
  return fullPath;
116
134
  }
117
135
  catch (e) {
118
- throw new Error(`Error getting full path for key: ${key}.\nError: ${JSON.stringify(e)}`);
136
+ throw new Error(`Error getting full path for key: ${key}.\nError: ${String(e)}`);
119
137
  }
120
138
  }
121
139
  /**
@@ -23,6 +23,11 @@ import { BaseStore } from "@langchain/core/stores";
23
23
  * await store.mdelete([key]);
24
24
  * }
25
25
  * ```
26
+ *
27
+ * @security **Security Notice** This file store
28
+ * can alter any text file in the provided directory and any subfolders.
29
+ * Make sure that the path you specify when initializing the store is free
30
+ * of other files.
26
31
  */
27
32
  export declare class LocalFileStore extends BaseStore<string, Uint8Array> {
28
33
  lc_namespace: string[];
@@ -25,6 +25,11 @@ import { BaseStore } from "@langchain/core/stores";
25
25
  * await store.mdelete([key]);
26
26
  * }
27
27
  * ```
28
+ *
29
+ * @security **Security Notice** This file store
30
+ * can alter any text file in the provided directory and any subfolders.
31
+ * Make sure that the path you specify when initializing the store is free
32
+ * of other files.
28
33
  */
29
34
  export class LocalFileStore extends BaseStore {
30
35
  constructor(fields) {
@@ -49,6 +54,10 @@ export class LocalFileStore extends BaseStore {
49
54
  * @returns Promise that resolves to the parsed file content.
50
55
  */
51
56
  async getParsedFile(key) {
57
+ // Validate the key to prevent path traversal
58
+ if (!/^[a-zA-Z0-9_\-:.]+$/.test(key)) {
59
+ throw new Error("Invalid key. Only alphanumeric characters, underscores, hyphens, colons, and periods are allowed.");
60
+ }
52
61
  try {
53
62
  const fileContent = await fs.readFile(this.getFullPath(key));
54
63
  if (!fileContent) {
@@ -85,11 +94,20 @@ export class LocalFileStore extends BaseStore {
85
94
  getFullPath(key) {
86
95
  try {
87
96
  const keyAsTxtFile = `${key}.txt`;
88
- const fullPath = path.join(this.rootPath, keyAsTxtFile);
97
+ // Validate the key to prevent path traversal
98
+ if (!/^[a-zA-Z0-9_.\-/]+$/.test(key)) {
99
+ throw new Error(`Invalid characters in key: ${key}`);
100
+ }
101
+ const fullPath = path.resolve(this.rootPath, keyAsTxtFile);
102
+ const commonPath = path.resolve(this.rootPath);
103
+ if (!fullPath.startsWith(commonPath)) {
104
+ throw new Error(`Invalid key: ${key}. Key should be relative to the root path. ` +
105
+ `Root path: ${this.rootPath}, Full path: ${fullPath}`);
106
+ }
89
107
  return fullPath;
90
108
  }
91
109
  catch (e) {
92
- throw new Error(`Error getting full path for key: ${key}.\nError: ${JSON.stringify(e)}`);
110
+ throw new Error(`Error getting full path for key: ${key}.\nError: ${String(e)}`);
93
111
  }
94
112
  }
95
113
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "langchain",
3
- "version": "0.2.18",
3
+ "version": "0.2.20",
4
4
  "description": "Typescript bindings for langchain",
5
5
  "type": "module",
6
6
  "engines": {
@@ -600,7 +600,7 @@
600
600
  "@aws-sdk/types": "^3.357.0",
601
601
  "@azure/storage-blob": "^12.15.0",
602
602
  "@browserbasehq/sdk": "^1.1.5",
603
- "@cloudflare/workers-types": "^4.20230922.0",
603
+ "@cloudflare/workers-types": "^4.20240909.0",
604
604
  "@faker-js/faker": "^7.6.0",
605
605
  "@gomomento/sdk": "^1.51.1",
606
606
  "@gomomento/sdk-core": "^1.51.1",
@@ -699,7 +699,6 @@
699
699
  "@langchain/anthropic": "*",
700
700
  "@langchain/aws": "*",
701
701
  "@langchain/cohere": "*",
702
- "@langchain/community": "*",
703
702
  "@langchain/google-genai": "*",
704
703
  "@langchain/google-vertexai": "*",
705
704
  "@langchain/groq": "*",
@@ -783,9 +782,6 @@
783
782
  "@langchain/cohere": {
784
783
  "optional": true
785
784
  },
786
- "@langchain/community": {
787
- "optional": true
788
- },
789
785
  "@langchain/google-genai": {
790
786
  "optional": true
791
787
  },
@@ -933,7 +929,7 @@
933
929
  "js-tiktoken": "^1.0.12",
934
930
  "js-yaml": "^4.1.0",
935
931
  "jsonpointer": "^5.0.1",
936
- "langsmith": "~0.1.40",
932
+ "langsmith": "^0.1.56-rc.1",
937
933
  "openapi-types": "^12.1.3",
938
934
  "p-retry": "4",
939
935
  "uuid": "^10.0.0",