Skip to content

Commit 7d7e79c

Browse files
authored
Merge pull request #630 from hwchase17/nc/process-env-guard
Add a guard on usage of process.env
2 parents 5e6f8dc + 625475f commit 7d7e79c

23 files changed

+123
-40
lines changed

langchain/.eslintrc.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ module.exports = {
3939
],
4040
},
4141
],
42+
"no-process-env": 2,
4243
"@typescript-eslint/explicit-module-boundary-types": 0,
4344
"@typescript-eslint/no-empty-function": 0,
4445
"@typescript-eslint/no-shadow": 0,

langchain/src/agents/tests/sql.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-process-env */
12
import { test, expect, beforeEach, afterEach } from "@jest/globals";
23
import { DataSource } from "typeorm";
34
import {

langchain/src/agents/tools/bingserpapi.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ class BingSerpAPI extends Tool {
1111
params: Record<string, string>;
1212

1313
constructor(
14-
apiKey: string | undefined = process.env.BingApiKey,
14+
apiKey: string | undefined = typeof process !== "undefined"
15+
? // eslint-disable-next-line no-process-env
16+
process.env.BingApiKey
17+
: undefined,
1518
params: Record<string, string> = {}
1619
) {
1720
super();

langchain/src/agents/tools/serpapi.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,10 @@ export class SerpAPI extends Tool {
302302
protected params: Partial<GoogleParameters>;
303303

304304
constructor(
305-
apiKey: string | undefined = process.env.SERPAPI_API_KEY,
305+
apiKey: string | undefined = typeof process !== "undefined"
306+
? // eslint-disable-next-line no-process-env
307+
process.env.SERPAPI_API_KEY
308+
: undefined,
306309
params: Partial<GoogleParameters> = {}
307310
) {
308311
super();

langchain/src/agents/tools/serper.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ export class Serper extends Tool {
1818
protected params: Partial<GoogleParameters>;
1919

2020
constructor(
21-
apiKey: string | undefined = process.env.SERPER_API_KEY,
21+
apiKey: string | undefined = typeof process !== "undefined"
22+
? // eslint-disable-next-line no-process-env
23+
process.env.SERPER_API_KEY
24+
: undefined,
2225
params: Partial<GoogleParameters> = {}
2326
) {
2427
super();

langchain/src/agents/tools/zapier.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ export class ZapierNLAWrapper {
3333
constructor(params?: string | ZapiterNLAWrapperParams) {
3434
const zapierNlaApiKey =
3535
typeof params === "string" ? params : params?.apiKey;
36-
const apiKey = zapierNlaApiKey ?? process.env.ZAPIER_NLA_API_KEY;
36+
const apiKey =
37+
zapierNlaApiKey ??
38+
(typeof process !== "undefined"
39+
? // eslint-disable-next-line no-process-env
40+
process.env.ZAPIER_NLA_API_KEY
41+
: undefined);
3742
if (!apiKey) {
3843
throw new Error("ZAPIER_NLA_API_KEY not set");
3944
}

langchain/src/callbacks/tests/langchain_tracer.int.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-process-env */
12
import { test, expect } from "@jest/globals";
23

34
import { LangChainTracer } from "../tracers.js";

langchain/src/callbacks/tracers.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,15 +258,20 @@ export abstract class BaseTracer extends BaseCallbackHandler {
258258

259259
export class LangChainTracer extends BaseTracer {
260260
protected endpoint =
261-
process.env.LANGCHAIN_ENDPOINT || "http://localhost:8000";
261+
(typeof process !== "undefined"
262+
? // eslint-disable-next-line no-process-env
263+
process.env.LANGCHAIN_ENDPOINT
264+
: undefined) || "http://localhost:8000";
262265

263266
protected headers: Record<string, string> = {
264267
"Content-Type": "application/json",
265268
};
266269

267270
constructor() {
268271
super();
269-
if (process.env.LANGCHAIN_API_KEY) {
272+
// eslint-disable-next-line no-process-env
273+
if (typeof process !== "undefined" && process.env.LANGCHAIN_API_KEY) {
274+
// eslint-disable-next-line no-process-env
270275
this.headers["x-api-key"] = process.env.LANGCHAIN_API_KEY;
271276
}
272277
}

langchain/src/callbacks/utils.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ export class SingletonCallbackManager extends CallbackManager {
1414
SingletonCallbackManager.instance.addHandler(
1515
new ConsoleCallbackHandler()
1616
);
17-
if (process.env.LANGCHAIN_HANDLER === "langchain") {
17+
if (
18+
typeof process !== "undefined" &&
19+
// eslint-disable-next-line no-process-env
20+
process.env.LANGCHAIN_HANDLER === "langchain"
21+
) {
1822
SingletonCallbackManager.instance.addHandler(new LangChainTracer());
1923
}
2024
}

langchain/src/chat_models/anthropic.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,12 @@ export class ChatAnthropic extends BaseChatModel implements AnthropicInput {
135135
) {
136136
super(fields ?? {});
137137

138-
this.apiKey = fields?.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY;
138+
this.apiKey =
139+
fields?.anthropicApiKey ??
140+
(typeof process !== "undefined"
141+
? // eslint-disable-next-line no-process-env
142+
process.env.ANTHROPIC_API_KEY
143+
: undefined);
139144
if (!this.apiKey) {
140145
throw new Error("Anthropic API key not found");
141146
}

langchain/src/chat_models/openai.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,10 @@ export class ChatOpenAI extends BaseChatModel implements OpenAIInput {
173173
) {
174174
super(fields ?? {});
175175

176-
const apiKey = fields?.openAIApiKey ?? process.env.OPENAI_API_KEY;
176+
const apiKey =
177+
fields?.openAIApiKey ??
178+
// eslint-disable-next-line no-process-env
179+
(typeof process !== "undefined" ? process.env.OPENAI_API_KEY : undefined);
177180
if (!apiKey) {
178181
throw new Error("OpenAI API key not found");
179182
}
@@ -198,7 +201,7 @@ export class ChatOpenAI extends BaseChatModel implements OpenAIInput {
198201
}
199202

200203
this.clientConfig = {
201-
apiKey: fields?.openAIApiKey ?? process.env.OPENAI_API_KEY,
204+
apiKey,
202205
...configuration,
203206
};
204207
}

langchain/src/document_loaders/github.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ export class GithubRepoLoader
5050
constructor(
5151
githubUrl: string,
5252
{
53-
accessToken = process.env.GITHUB_ACCESS_TOKEN,
53+
accessToken = typeof process !== "undefined"
54+
? // eslint-disable-next-line no-process-env
55+
process.env.GITHUB_ACCESS_TOKEN
56+
: undefined,
5457
branch = "main",
5558
recursive = true,
5659
unknown = UnknownHandling.Warn,

langchain/src/embeddings/cohere.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ export class CohereEmbeddings extends Embeddings implements ModelParams {
3535
) {
3636
super(fields ?? {});
3737

38-
const apiKey = fields?.apiKey || process.env.COHERE_API_KEY;
38+
const apiKey =
39+
fields?.apiKey ||
40+
// eslint-disable-next-line no-process-env
41+
(typeof process !== "undefined" ? process.env.COHERE_API_KEY : undefined);
3942

4043
if (!apiKey) {
4144
throw new Error("Cohere API key not found");

langchain/src/embeddings/openai.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ export class OpenAIEmbeddings extends Embeddings implements ModelParams {
5151
) {
5252
super(fields ?? {});
5353

54-
const apiKey = fields?.openAIApiKey ?? process.env.OPENAI_API_KEY;
54+
const apiKey =
55+
fields?.openAIApiKey ??
56+
// eslint-disable-next-line no-process-env
57+
(typeof process !== "undefined" ? process.env.OPENAI_API_KEY : undefined);
5558
if (!apiKey) {
5659
throw new Error("OpenAI API key not found");
5760
}

langchain/src/llms/cohere.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import { LLM, BaseLLMParams } from "./base.js";
22

3-
interface CohereInput {
3+
interface CohereInput extends BaseLLMParams {
44
/** Sampling temperature to use */
5-
temperature: number;
5+
temperature?: number;
66

77
/**
88
* Maximum number of tokens to generate in the completion.
99
*/
10-
maxTokens: number;
10+
maxTokens?: number;
1111

1212
/** Model to use */
13-
model: string;
13+
model?: string;
14+
15+
apiKey?: string;
1416
}
1517

1618
export class Cohere extends LLM implements CohereInput {
@@ -22,13 +24,19 @@ export class Cohere extends LLM implements CohereInput {
2224

2325
apiKey: string;
2426

25-
constructor(fields?: Partial<CohereInput> & BaseLLMParams) {
27+
constructor(fields?: CohereInput) {
2628
super(fields ?? {});
2729

28-
const apiKey = process.env.COHERE_API_KEY;
30+
const apiKey =
31+
fields?.apiKey ?? typeof process !== "undefined"
32+
? // eslint-disable-next-line no-process-env
33+
process.env.COHERE_API_KEY
34+
: undefined;
2935

3036
if (!apiKey) {
31-
throw new Error("Please set the COHERE_API_KEY environment variable");
37+
throw new Error(
38+
"Please set the COHERE_API_KEY environment variable or pass it to the constructor as the apiKey field."
39+
);
3240
}
3341

3442
this.apiKey = apiKey;

langchain/src/llms/hf.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ interface HFInput {
2020

2121
/** Penalizes repeated tokens according to frequency */
2222
frequencyPenalty?: number;
23+
24+
/** API key to use. */
25+
apiKey?: string;
2326
}
2427

2528
export class HuggingFaceInference extends LLM implements HFInput {
@@ -35,6 +38,8 @@ export class HuggingFaceInference extends LLM implements HFInput {
3538

3639
frequencyPenalty: number | undefined = undefined;
3740

41+
apiKey: string | undefined = undefined;
42+
3843
constructor(fields?: Partial<HFInput> & BaseLLMParams) {
3944
super(fields ?? {});
4045

@@ -44,20 +49,26 @@ export class HuggingFaceInference extends LLM implements HFInput {
4449
this.topP = fields?.topP ?? this.topP;
4550
this.topK = fields?.topK ?? this.topK;
4651
this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;
52+
this.apiKey =
53+
fields?.apiKey ??
54+
(typeof process !== "undefined"
55+
? // eslint-disable-next-line no-process-env
56+
process.env.HUGGINGFACEHUB_API_KEY
57+
: undefined);
58+
if (!this.apiKey) {
59+
throw new Error(
60+
"Please set an API key for HuggingFace Hub in the environment variable HUGGINGFACEHUB_API_KEY or in the apiKey field of the HuggingFaceInference constructor."
61+
);
62+
}
4763
}
4864

4965
_llmType() {
5066
return "huggingface_hub";
5167
}
5268

5369
async _call(prompt: string, _stop?: string[]): Promise<string> {
54-
if (process.env.HUGGINGFACEHUB_API_KEY === "") {
55-
throw new Error(
56-
"Please set the HUGGINGFACEHUB_API_KEY environment variable"
57-
);
58-
}
5970
const { HfInference } = await HuggingFaceInference.imports();
60-
const hf = new HfInference(process.env.HUGGINGFACEHUB_API_KEY ?? "");
71+
const hf = new HfInference(this.apiKey);
6172
const res = await this.caller.call(hf.textGeneration.bind(hf), {
6273
model: this.model,
6374
parameters: {

langchain/src/llms/openai-chat.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ export class OpenAIChat extends LLM implements OpenAIInput {
124124
) {
125125
super(fields ?? {});
126126

127-
const apiKey = fields?.openAIApiKey ?? process.env.OPENAI_API_KEY;
127+
const apiKey =
128+
fields?.openAIApiKey ??
129+
// eslint-disable-next-line no-process-env
130+
(typeof process !== "undefined" ? process.env.OPENAI_API_KEY : undefined);
128131
if (!apiKey) {
129132
throw new Error("OpenAI API key not found");
130133
}

langchain/src/llms/openai.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ export class OpenAI extends BaseLLM implements OpenAIInput {
146146
}
147147
super(fields ?? {});
148148

149-
const apiKey = fields?.openAIApiKey ?? process.env.OPENAI_API_KEY;
149+
const apiKey =
150+
fields?.openAIApiKey ??
151+
// eslint-disable-next-line no-process-env
152+
(typeof process !== "undefined" ? process.env.OPENAI_API_KEY : undefined);
150153
if (!apiKey) {
151154
throw new Error("OpenAI API key not found");
152155
}
@@ -403,7 +406,11 @@ export class PromptLayerOpenAI extends OpenAI {
403406

404407
this.plTags = fields?.plTags ?? [];
405408
this.promptLayerApiKey =
406-
fields?.promptLayerApiKey ?? process.env.PROMPTLAYER_API_KEY;
409+
fields?.promptLayerApiKey ??
410+
(typeof process !== "undefined"
411+
? // eslint-disable-next-line no-process-env
412+
process.env.PROMPTLAYER_API_KEY
413+
: undefined);
407414

408415
if (!this.promptLayerApiKey) {
409416
throw new Error("Missing PromptLayer API key");
@@ -437,7 +444,7 @@ export class PromptLayerOpenAI extends OpenAI {
437444
request_response: response.data,
438445
request_start_time: Math.floor(requestStartTime / 1000),
439446
request_end_time: Math.floor(requestEndTime / 1000),
440-
api_key: process.env.PROMPTLAYER_API_KEY,
447+
api_key: this.promptLayerApiKey,
441448
}),
442449
});
443450

langchain/src/llms/replicate.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ export class Replicate extends LLM implements ReplicateInput {
2222
constructor(fields: ReplicateInput & BaseLLMParams) {
2323
super(fields);
2424

25-
const apiKey = fields?.apiKey ?? process.env.REPLICATE_API_KEY;
25+
const apiKey =
26+
fields?.apiKey ??
27+
// eslint-disable-next-line no-process-env
28+
(typeof process !== "undefined" && process.env.REPLICATE_API_KEY);
2629

2730
if (!apiKey) {
2831
throw new Error("Please set the REPLICATE_API_KEY environment variable");

langchain/src/retrievers/tests/supabase-hybrid-search.int.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-process-env */
12
/* eslint-disable @typescript-eslint/no-non-null-assertion */
23
import { test, expect } from "@jest/globals";
34
import { createClient } from "@supabase/supabase-js";

langchain/src/util/hub.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,24 @@ export const loadFromHub = async <T>(
1313
validSuffixes: Set<string>,
1414
values: LoadValues = {}
1515
): Promise<T | undefined> => {
16+
const LANGCHAIN_HUB_DEFAULT_REF =
17+
(typeof process !== "undefined"
18+
? // eslint-disable-next-line no-process-env
19+
process.env.LANGCHAIN_HUB_DEFAULT_REF
20+
: undefined) ?? "master";
21+
const LANGCHAIN_HUB_URL_BASE =
22+
(typeof process !== "undefined"
23+
? // eslint-disable-next-line no-process-env
24+
process.env.LANGCHAIN_HUB_URL_BASE
25+
: undefined) ??
26+
"https://raw.githubusercontent.com/hwchase17/langchain-hub/";
27+
1628
const match = uri.match(HUB_PATH_REGEX);
1729
if (!match) {
1830
return undefined;
1931
}
2032
const [rawRef, remotePath] = match.slice(1);
21-
const ref = rawRef
22-
? rawRef.slice(1)
23-
: process.env.LANGCHAIN_HUB_DEFAULT_REF ?? "master";
33+
const ref = rawRef ? rawRef.slice(1) : LANGCHAIN_HUB_DEFAULT_REF;
2434
const parts = remotePath.split(URL_PATH_SEPARATOR);
2535
if (parts[0] !== validPrefix) {
2636
return undefined;
@@ -30,12 +40,7 @@ export const loadFromHub = async <T>(
3040
throw new Error("Unsupported file type.");
3141
}
3242

33-
const url = [
34-
process.env.LANGCHAIN_HUB_URL_BASE ??
35-
"https://raw.githubusercontent.com/hwchase17/langchain-hub/",
36-
ref,
37-
remotePath,
38-
].join("/");
43+
const url = [LANGCHAIN_HUB_URL_BASE, ref, remotePath].join("/");
3944
const res = await backOff(() => fetchWithTimeout(url, { timeout: 5000 }), {
4045
numOfAttempts: 6,
4146
});

langchain/src/vectorstores/tests/pinecone.int.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-process-env */
12
/* eslint-disable @typescript-eslint/no-non-null-assertion */
23
import { beforeEach, describe, expect, test } from "@jest/globals";
34
import { faker } from "@faker-js/faker";

langchain/src/vectorstores/tests/supabase.int.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-process-env */
12
/* eslint-disable @typescript-eslint/no-non-null-assertion */
23
import { test, expect } from "@jest/globals";
34
import { createClient } from "@supabase/supabase-js";

0 commit comments

Comments
 (0)