fix(core): Fix HTTP proxy support in all nodes and other axios requests (#16092)

This commit is contained in:
Elias Meire
2025-06-10 14:42:51 +02:00
committed by GitHub
parent cd6e510596
commit e3675bdfb4
6 changed files with 325 additions and 140 deletions

View File

@@ -195,7 +195,7 @@
"form-data": "catalog:", "form-data": "catalog:",
"generate-schema": "2.6.0", "generate-schema": "2.6.0",
"html-to-text": "9.0.5", "html-to-text": "9.0.5",
"https-proxy-agent": "^7.0.6", "https-proxy-agent": "catalog:",
"jsdom": "23.0.1", "jsdom": "23.0.1",
"langchain": "0.3.11", "langchain": "0.3.11",
"lodash": "catalog:", "lodash": "catalog:",

View File

@@ -32,6 +32,7 @@
"@types/jsonwebtoken": "catalog:", "@types/jsonwebtoken": "catalog:",
"@types/lodash": "catalog:", "@types/lodash": "catalog:",
"@types/mime-types": "^2.1.0", "@types/mime-types": "^2.1.0",
"@types/proxy-from-env": "^1.0.4",
"@types/uuid": "catalog:", "@types/uuid": "catalog:",
"@types/xml2js": "catalog:" "@types/xml2js": "catalog:"
}, },
@@ -52,6 +53,8 @@
"fast-glob": "catalog:", "fast-glob": "catalog:",
"file-type": "16.5.4", "file-type": "16.5.4",
"form-data": "catalog:", "form-data": "catalog:",
"http-proxy-agent": "catalog:",
"https-proxy-agent": "catalog:",
"iconv-lite": "catalog:", "iconv-lite": "catalog:",
"jsonwebtoken": "catalog:", "jsonwebtoken": "catalog:",
"lodash": "catalog:", "lodash": "catalog:",
@@ -63,6 +66,7 @@
"p-cancelable": "2.1.1", "p-cancelable": "2.1.1",
"picocolors": "catalog:", "picocolors": "catalog:",
"pretty-bytes": "5.6.0", "pretty-bytes": "5.6.0",
"proxy-from-env": "^1.1.0",
"qs": "6.11.0", "qs": "6.11.0",
"ssh2": "1.15.0", "ssh2": "1.15.0",
"uuid": "catalog:", "uuid": "catalog:",

View File

@@ -1,5 +1,7 @@
import FormData from 'form-data'; import FormData from 'form-data';
import type { Agent } from 'https'; import { HttpProxyAgent } from 'http-proxy-agent';
import { Agent } from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { mock } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended';
import type { import type {
IHttpRequestMethods, IHttpRequestMethods,
@@ -19,6 +21,7 @@ import {
applyPaginationRequestData, applyPaginationRequestData,
convertN8nRequestToAxios, convertN8nRequestToAxios,
createFormDataObject, createFormDataObject,
getAgentWithProxy,
httpRequest, httpRequest,
invokeAxios, invokeAxios,
parseRequestObject, parseRequestObject,
@@ -28,7 +31,7 @@ import {
describe('Request Helper Functions', () => { describe('Request Helper Functions', () => {
describe('proxyRequestToAxios', () => { describe('proxyRequestToAxios', () => {
const baseUrl = 'http://example.de'; const baseUrl = 'https://example.de';
const workflow = mock<Workflow>(); const workflow = mock<Workflow>();
const hooks = mock<ExecutionLifecycleHooks>(); const hooks = mock<ExecutionLifecycleHooks>();
const additionalData = mock<IWorkflowExecuteAdditionalData>({ hooks }); const additionalData = mock<IWorkflowExecuteAdditionalData>({ hooks });
@@ -66,7 +69,7 @@ describe('Request Helper Functions', () => {
expect(error.options).toMatchObject({ expect(error.options).toMatchObject({
headers: { Accept: '*/*' }, headers: { Accept: '*/*' },
method: 'get', method: 'get',
url: 'http://example.de/test', url: 'https://example.de/test',
}); });
expect(error.config).toBeUndefined(); expect(error.config).toBeUndefined();
expect(error.message).toEqual('403 - "Forbidden"'); expect(error.message).toEqual('403 - "Forbidden"');
@@ -165,7 +168,7 @@ describe('Request Helper Functions', () => {
}); });
describe('invokeAxios', () => { describe('invokeAxios', () => {
const baseUrl = 'http://example.de'; const baseUrl = 'https://example.de';
beforeEach(() => { beforeEach(() => {
nock.cleanAll(); nock.cleanAll();
@@ -346,7 +349,11 @@ describe('Request Helper Functions', () => {
const axiosOptions = await parseRequestObject(requestObject); const axiosOptions = await parseRequestObject(requestObject);
expect(axiosOptions.beforeRedirect).toBeDefined; expect(axiosOptions.beforeRedirect).toBeDefined;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const redirectOptions: Record<string, any> = { agents: {}, hostname: 'example.de' }; const redirectOptions: Record<string, any> = {
agents: {},
hostname: 'example.de',
href: requestObject.uri,
};
axiosOptions.beforeRedirect!(redirectOptions, mock()); axiosOptions.beforeRedirect!(redirectOptions, mock());
expect(redirectOptions.agent).toEqual(redirectOptions.agents.https); expect(redirectOptions.agent).toEqual(redirectOptions.agents.https);
expect((redirectOptions.agent as Agent).options).toEqual({ expect((redirectOptions.agent as Agent).options).toEqual({
@@ -862,4 +869,82 @@ describe('Request Helper Functions', () => {
scope.done(); scope.done();
}); });
}); });
describe('getAgentWithProxy', () => {
const baseUrlHttps = 'https://example.com';
const baseUrlHttp = 'http://example.com';
const proxyUrlHttps = 'http://proxy-for-https.com:8080/';
const proxyUrlHttp = 'http://proxy-for-http.com:8080/';
test('should return a regular agent when no proxy is set', async () => {
const { agent, protocol } = getAgentWithProxy({
targetUrl: baseUrlHttps,
});
expect(protocol).toEqual('https');
expect(agent).toBeInstanceOf(Agent);
});
test('should use a proxyConfig object', async () => {
const { agent, protocol } = getAgentWithProxy({
targetUrl: baseUrlHttps,
proxyConfig: {
host: 'proxy-for-https.com',
port: 8080,
},
});
expect(protocol).toEqual('https');
expect((agent as HttpsProxyAgent<string>).proxy.href).toEqual(proxyUrlHttps);
});
test('should use a proxyConfig string', async () => {
const { agent, protocol } = getAgentWithProxy({
targetUrl: baseUrlHttps,
proxyConfig: proxyUrlHttps,
});
expect(agent).toBeInstanceOf(HttpsProxyAgent);
expect(protocol).toEqual('https');
expect((agent as HttpsProxyAgent<string>).proxy.href).toEqual(proxyUrlHttps);
});
describe('environment variables', () => {
let originalEnv: NodeJS.ProcessEnv;
beforeAll(() => {
originalEnv = { ...process.env };
process.env.HTTP_PROXY = proxyUrlHttp;
process.env.HTTPS_PROXY = proxyUrlHttps;
process.env.NO_PROXY = 'should-not-proxy.com';
});
afterAll(() => {
process.env = originalEnv;
});
test('should proxy http requests (HTTP_PROXY)', async () => {
const { agent, protocol } = getAgentWithProxy({
targetUrl: baseUrlHttp,
});
expect(protocol).toEqual('http');
expect(agent).toBeInstanceOf(HttpProxyAgent);
expect((agent as HttpsProxyAgent<string>).proxy.href).toEqual(proxyUrlHttp);
});
test('should proxy https requests (HTTPS_PROXY)', async () => {
const { agent, protocol } = getAgentWithProxy({
targetUrl: baseUrlHttps,
});
expect(protocol).toEqual('https');
expect(agent).toBeInstanceOf(HttpsProxyAgent);
expect((agent as HttpsProxyAgent<string>).proxy.href).toEqual(proxyUrlHttps);
});
test('should not proxy some hosts based on NO_PROXY', async () => {
const { agent, protocol } = getAgentWithProxy({
targetUrl: 'https://should-not-proxy.com/foo',
});
expect(protocol).toEqual('https');
expect(agent).toBeInstanceOf(Agent);
});
});
});
}); });

View File

@@ -20,11 +20,24 @@ import axios from 'axios';
import crypto, { createHmac } from 'crypto'; import crypto, { createHmac } from 'crypto';
import FormData from 'form-data'; import FormData from 'form-data';
import { IncomingMessage } from 'http'; import { IncomingMessage } from 'http';
import { Agent, type AgentOptions } from 'https'; import { HttpProxyAgent } from 'http-proxy-agent';
import { type AgentOptions, Agent as HttpsAgent } from 'https';
import { Agent as HttpAgent } from 'https';
import { HttpsProxyAgent } from 'https-proxy-agent';
import get from 'lodash/get'; import get from 'lodash/get';
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import merge from 'lodash/merge'; import merge from 'lodash/merge';
import pick from 'lodash/pick'; import pick from 'lodash/pick';
import {
NodeApiError,
NodeOperationError,
NodeSslError,
isObjectEmpty,
ExecutionBaseError,
jsonParse,
ApplicationError,
sleep,
} from 'n8n-workflow';
import type { import type {
GenericValue, GenericValue,
IAdditionalCredentialOptions, IAdditionalCredentialOptions,
@@ -49,21 +62,11 @@ import type {
Workflow, Workflow,
WorkflowExecuteMode, WorkflowExecuteMode,
} from 'n8n-workflow'; } from 'n8n-workflow';
import {
NodeApiError,
NodeOperationError,
NodeSslError,
isObjectEmpty,
ExecutionBaseError,
jsonParse,
ApplicationError,
sleep,
} from 'n8n-workflow';
import type { Token } from 'oauth-1.0a'; import type { Token } from 'oauth-1.0a';
import clientOAuth1 from 'oauth-1.0a'; import clientOAuth1 from 'oauth-1.0a';
import proxyFromEnv from 'proxy-from-env';
import { stringify } from 'qs'; import { stringify } from 'qs';
import { Readable } from 'stream'; import { Readable } from 'stream';
import url, { URL, URLSearchParams } from 'url';
import type { IResponseError } from '@/interfaces'; import type { IResponseError } from '@/interfaces';
@@ -81,15 +84,11 @@ axios.defaults.paramsSerializer = (params) => {
} }
return stringify(params, { arrayFormat: 'indices' }); return stringify(params, { arrayFormat: 'indices' });
}; };
axios.interceptors.request.use((config) => { // Disable axios proxy, we handle it ourselves
// If no content-type is set by us, prevent axios from force-setting the content-type to `application/x-www-form-urlencoded` // Axios proxy option has problems: https://github.com/axios/axios/issues/4531
if (config.data === undefined) { axios.defaults.proxy = false;
config.headers.setContentType(false, false);
}
return config;
});
const validateUrl = (url?: string): boolean => { function validateUrl(url?: string): boolean {
if (!url) return false; if (!url) return false;
try { try {
@@ -98,8 +97,106 @@ const validateUrl = (url?: string): boolean => {
} catch (error) { } catch (error) {
return false; return false;
} }
}
function getUrlFromProxyConfig(proxyConfig: IHttpRequestOptions['proxy'] | string): string | null {
if (typeof proxyConfig === 'string') {
if (!validateUrl(proxyConfig)) {
return null;
}
return proxyConfig;
}
if (!proxyConfig?.host) {
return null;
}
const { protocol, host, port, auth } = proxyConfig;
const safeProtocol = protocol?.endsWith(':') ? protocol.replace(':', '') : (protocol ?? 'http');
try {
const url = new URL(`${safeProtocol}://${host}`);
if (port !== undefined) {
url.port = String(port);
}
if (auth?.username) {
url.username = auth.username;
url.password = auth.password ?? '';
}
return url.href;
} catch (error) {
return null;
}
}
function getTargetUrlFromAxiosConfig(axiosConfig: AxiosRequestConfig): string {
const { url, baseURL } = axiosConfig;
try {
return new URL(url ?? '', baseURL).href;
} catch {
return '';
}
}
type AgentInfo = { protocol: 'http' | 'https'; agent: HttpAgent };
export function getAgentWithProxy({
agentOptions,
proxyConfig,
targetUrl,
}: {
agentOptions?: AgentOptions;
proxyConfig?: IHttpRequestOptions['proxy'] | string;
targetUrl: string;
}): AgentInfo {
// If no proxy is set in config, use HTTP_PROXY/HTTPS_PROXY/ALL_PROXY from env depending on target URL
// Also respect NO_PROXY to disable the proxy for certain hosts
const proxyUrl = getUrlFromProxyConfig(proxyConfig) ?? proxyFromEnv.getProxyForUrl(targetUrl);
const protocol = targetUrl.startsWith('https://') ? 'https' : 'http';
if (proxyUrl) {
const ProxyAgent = protocol === 'http' ? HttpProxyAgent : HttpsProxyAgent;
return { protocol, agent: new ProxyAgent(proxyUrl, agentOptions) };
}
const Agent = protocol === 'http' ? HttpAgent : HttpsAgent;
return { protocol, agent: new Agent(agentOptions) };
}
const applyAgentToAxiosConfig = (
config: AxiosRequestConfig,
{ agent, protocol }: AgentInfo,
): AxiosRequestConfig => {
if (protocol === 'http') {
config.httpAgent = agent;
} else {
config.httpsAgent = agent;
}
return config;
}; };
axios.interceptors.request.use((config) => {
// If no content-type is set by us, prevent axios from force-setting the content-type to `application/x-www-form-urlencoded`
if (config.data === undefined) {
config.headers.setContentType(false, false);
}
if (!config.httpsAgent && !config.httpAgent) {
const agent = getAgentWithProxy({
targetUrl: getTargetUrlFromAxiosConfig(config),
});
applyAgentToAxiosConfig(config, agent);
}
return config;
});
function searchForHeader(config: AxiosRequestConfig, headerName: string) { function searchForHeader(config: AxiosRequestConfig, headerName: string) {
if (config.headers === undefined) { if (config.headers === undefined) {
return undefined; return undefined;
@@ -126,17 +223,30 @@ const getHostFromRequestObject = (
}; };
const getBeforeRedirectFn = const getBeforeRedirectFn =
(agentOptions: AgentOptions, axiosConfig: AxiosRequestConfig) => (
agentOptions: AgentOptions,
axiosConfig: AxiosRequestConfig,
proxyConfig: IHttpRequestOptions['proxy'] | string | undefined,
) =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
(redirectedRequest: Record<string, any>) => { (redirectedRequest: Record<string, any>) => {
const redirectAgent = new Agent({ const redirectAgentOptions = {
...agentOptions, ...agentOptions,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
servername: redirectedRequest.hostname, servername: redirectedRequest.hostname,
};
const redirectAgent = getAgentWithProxy({
agentOptions: redirectAgentOptions,
proxyConfig,
targetUrl: redirectedRequest.href,
}); });
redirectedRequest.agent = redirectAgent;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access redirectedRequest.agent = redirectAgent.agent;
redirectedRequest.agents.https = redirectAgent; if (redirectAgent.protocol === 'http') {
redirectedRequest.agents.http = redirectAgent.agent;
} else {
redirectedRequest.agents.https = redirectAgent.agent;
}
if (axiosConfig.headers?.Authorization) { if (axiosConfig.headers?.Authorization) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
@@ -171,8 +281,8 @@ function digestAuthAxiosConfig(
.createHash('md5') .createHash('md5')
.update(`${auth?.username as string}:${realm}:${auth?.password as string}`) .update(`${auth?.username as string}:${realm}:${auth?.password as string}`)
.digest('hex'); .digest('hex');
const urlURL = new url.URL(axios.getUri(axiosConfig)); const url = new URL(axios.getUri(axiosConfig));
const path = urlURL.pathname + urlURL.search; const path = url.pathname + url.search;
const ha2 = crypto const ha2 = crypto
.createHash('md5') .createHash('md5')
.update(`${axiosConfig.method ?? 'GET'}:${path}`) .update(`${axiosConfig.method ?? 'GET'}:${path}`)
@@ -511,77 +621,19 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
agentOptions.secureOptions = crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT; agentOptions.secureOptions = crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT;
} }
axiosConfig.httpsAgent = new Agent(agentOptions);
axiosConfig.beforeRedirect = getBeforeRedirectFn(agentOptions, axiosConfig);
if (requestObject.timeout !== undefined) { if (requestObject.timeout !== undefined) {
axiosConfig.timeout = requestObject.timeout; axiosConfig.timeout = requestObject.timeout;
} }
if (requestObject.proxy !== undefined) { const agent = getAgentWithProxy({
// try our best to parse the url provided. agentOptions,
if (typeof requestObject.proxy === 'string') { proxyConfig: requestObject.proxy,
try { targetUrl: getTargetUrlFromAxiosConfig(axiosConfig),
const url = new URL(requestObject.proxy); });
// eslint-disable-next-line @typescript-eslint/no-shadow
const host = url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname; applyAgentToAxiosConfig(axiosConfig, agent);
axiosConfig.proxy = {
host, axiosConfig.beforeRedirect = getBeforeRedirectFn(agentOptions, axiosConfig, requestObject.proxy);
port: parseInt(url.port, 10),
protocol: url.protocol,
};
if (!url.port) {
// Sets port to a default if not informed
if (url.protocol === 'http') {
axiosConfig.proxy.port = 80;
} else if (url.protocol === 'https') {
axiosConfig.proxy.port = 443;
}
}
if (url.username || url.password) {
axiosConfig.proxy.auth = {
username: url.username,
password: url.password,
};
}
} catch (error) {
// Not a valid URL. We will try to simply parse stuff
// such as user:pass@host:port without protocol (we'll assume http)
if (requestObject.proxy.includes('@')) {
const [userpass, hostport] = requestObject.proxy.split('@');
const [username, password] = userpass.split(':');
const [hostname, port] = hostport.split(':');
// eslint-disable-next-line @typescript-eslint/no-shadow
const host = hostname.startsWith('[') ? hostname.slice(1, -1) : hostname;
axiosConfig.proxy = {
host,
port: parseInt(port, 10),
protocol: 'http',
auth: {
username,
password,
},
};
} else if (requestObject.proxy.includes(':')) {
const [hostname, port] = requestObject.proxy.split(':');
axiosConfig.proxy = {
host: hostname,
port: parseInt(port, 10),
protocol: 'http',
};
} else {
axiosConfig.proxy = {
host: requestObject.proxy,
port: 80,
protocol: 'http',
};
}
}
} else {
axiosConfig.proxy = requestObject.proxy;
}
}
if (requestObject.useStream) { if (requestObject.useStream) {
axiosConfig.responseType = 'stream'; axiosConfig.responseType = 'stream';
@@ -730,7 +782,6 @@ export function convertN8nRequestToAxios(n8nRequest: IHttpRequestOptions): Axios
method, method,
timeout, timeout,
auth, auth,
proxy,
url, url,
maxBodyLength: Infinity, maxBodyLength: Infinity,
maxContentLength: Infinity, maxContentLength: Infinity,
@@ -762,9 +813,14 @@ export function convertN8nRequestToAxios(n8nRequest: IHttpRequestOptions): Axios
if (n8nRequest.skipSslCertificateValidation === true) { if (n8nRequest.skipSslCertificateValidation === true) {
agentOptions.rejectUnauthorized = false; agentOptions.rejectUnauthorized = false;
} }
axiosRequest.httpsAgent = new Agent(agentOptions); const agent = getAgentWithProxy({
agentOptions,
proxyConfig: proxy,
targetUrl: getTargetUrlFromAxiosConfig(axiosRequest),
});
applyAgentToAxiosConfig(axiosRequest, agent);
axiosRequest.beforeRedirect = getBeforeRedirectFn(agentOptions, axiosRequest); axiosRequest.beforeRedirect = getBeforeRedirectFn(agentOptions, axiosRequest, n8nRequest.proxy);
if (n8nRequest.arrayFormat !== undefined) { if (n8nRequest.arrayFormat !== undefined) {
axiosRequest.paramsSerializer = (params) => { axiosRequest.paramsSerializer = (params) => {

112
pnpm-lock.yaml generated
View File

@@ -63,6 +63,12 @@ catalogs:
form-data: form-data:
specifier: 4.0.0 specifier: 4.0.0
version: 4.0.0 version: 4.0.0
http-proxy-agent:
specifier: 7.0.2
version: 7.0.2
https-proxy-agent:
specifier: 7.0.6
version: 7.0.6
iconv-lite: iconv-lite:
specifier: 0.6.3 specifier: 0.6.3
version: 0.6.3 version: 0.6.3
@@ -760,7 +766,7 @@ importers:
version: 4.3.0 version: 4.3.0
'@getzep/zep-cloud': '@getzep/zep-cloud':
specifier: 1.0.12 specifier: 1.0.12
version: 1.0.12(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(6e4aa47666b8dfceb9beddf0b146b9ac)) version: 1.0.12(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(2ecef5dd5ce3e0c6dee7163d14def631))
'@getzep/zep-js': '@getzep/zep-js':
specifier: 0.9.0 specifier: 0.9.0
version: 0.9.0 version: 0.9.0
@@ -787,7 +793,7 @@ importers:
version: 0.3.2(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) version: 0.3.2(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
'@langchain/community': '@langchain/community':
specifier: 'catalog:' specifier: 'catalog:'
version: 0.3.24(8d6d0c7c173d79d9dc61e6a9334e3ecc) version: 0.3.24(a7747bc06767d45b4fc71d69250d6ec9)
'@langchain/core': '@langchain/core':
specifier: 'catalog:' specifier: 'catalog:'
version: 0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) version: 0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
@@ -885,14 +891,14 @@ importers:
specifier: 9.0.5 specifier: 9.0.5
version: 9.0.5 version: 9.0.5
https-proxy-agent: https-proxy-agent:
specifier: ^7.0.6 specifier: 'catalog:'
version: 7.0.6 version: 7.0.6
jsdom: jsdom:
specifier: 23.0.1 specifier: 23.0.1
version: 23.0.1 version: 23.0.1
langchain: langchain:
specifier: 0.3.11 specifier: 0.3.11
version: 0.3.11(6e4aa47666b8dfceb9beddf0b146b9ac) version: 0.3.11(2ecef5dd5ce3e0c6dee7163d14def631)
lodash: lodash:
specifier: 'catalog:' specifier: 'catalog:'
version: 4.17.21 version: 4.17.21
@@ -1544,6 +1550,12 @@ importers:
form-data: form-data:
specifier: 'catalog:' specifier: 'catalog:'
version: 4.0.0 version: 4.0.0
http-proxy-agent:
specifier: 'catalog:'
version: 7.0.2
https-proxy-agent:
specifier: 'catalog:'
version: 7.0.6
iconv-lite: iconv-lite:
specifier: 'catalog:' specifier: 'catalog:'
version: 0.6.3 version: 0.6.3
@@ -1577,6 +1589,9 @@ importers:
pretty-bytes: pretty-bytes:
specifier: 5.6.0 specifier: 5.6.0
version: 5.6.0 version: 5.6.0
proxy-from-env:
specifier: ^1.1.0
version: 1.1.0
qs: qs:
specifier: 6.11.0 specifier: 6.11.0
version: 6.11.0 version: 6.11.0
@@ -1611,6 +1626,9 @@ importers:
'@types/mime-types': '@types/mime-types':
specifier: ^2.1.0 specifier: ^2.1.0
version: 2.1.1 version: 2.1.1
'@types/proxy-from-env':
specifier: ^1.0.4
version: 1.0.4
'@types/uuid': '@types/uuid':
specifier: 'catalog:' specifier: 'catalog:'
version: 10.0.0 version: 10.0.0
@@ -6707,6 +6725,9 @@ packages:
'@types/prop-types@15.7.14': '@types/prop-types@15.7.14':
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
'@types/proxy-from-env@1.0.4':
resolution: {integrity: sha512-TPR9/bCZAr3V1eHN4G3LD3OLicdJjqX1QRXWuNcCYgE66f/K8jO2ZRtHxI2D9MbnuUP6+qiKSS8eUHp6TFHGCw==}
'@types/psl@1.1.0': '@types/psl@1.1.0':
resolution: {integrity: sha512-HhZnoLAvI2koev3czVPzBNRYvdrzJGLjQbWZhqFmS9Q6a0yumc5qtfSahBGb5g+6qWvA8iiQktqGkwoIXa/BNQ==} resolution: {integrity: sha512-HhZnoLAvI2koev3czVPzBNRYvdrzJGLjQbWZhqFmS9Q6a0yumc5qtfSahBGb5g+6qWvA8iiQktqGkwoIXa/BNQ==}
@@ -7269,10 +7290,6 @@ packages:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'} engines: {node: '>= 6.0.0'}
agent-base@7.1.0:
resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
engines: {node: '>= 14'}
agent-base@7.1.3: agent-base@7.1.3:
resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
@@ -9764,6 +9781,10 @@ packages:
resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
http-proxy-agent@7.0.2:
resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
engines: {node: '>= 14'}
http-signature@1.4.0: http-signature@1.4.0:
resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==} resolution: {integrity: sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==}
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
@@ -16731,7 +16752,7 @@ snapshots:
'@eslint/eslintrc@2.1.4': '@eslint/eslintrc@2.1.4':
dependencies: dependencies:
ajv: 6.12.6 ajv: 6.12.6
debug: 4.4.0 debug: 4.4.1(supports-color@8.1.1)
espree: 9.6.1 espree: 9.6.1
globals: 13.20.0 globals: 13.20.0
ignore: 5.2.4 ignore: 5.2.4
@@ -16796,7 +16817,7 @@ snapshots:
'@gar/promisify@1.1.3': '@gar/promisify@1.1.3':
optional: true optional: true
'@getzep/zep-cloud@1.0.12(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(6e4aa47666b8dfceb9beddf0b146b9ac))': '@getzep/zep-cloud@1.0.12(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(2ecef5dd5ce3e0c6dee7163d14def631))':
dependencies: dependencies:
form-data: 4.0.0 form-data: 4.0.0
node-fetch: 2.7.0(encoding@0.1.13) node-fetch: 2.7.0(encoding@0.1.13)
@@ -16805,7 +16826,7 @@ snapshots:
zod: 3.24.1 zod: 3.24.1
optionalDependencies: optionalDependencies:
'@langchain/core': 0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) '@langchain/core': 0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
langchain: 0.3.11(6e4aa47666b8dfceb9beddf0b146b9ac) langchain: 0.3.11(2ecef5dd5ce3e0c6dee7163d14def631)
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
@@ -16895,7 +16916,7 @@ snapshots:
'@humanwhocodes/config-array@0.11.14': '@humanwhocodes/config-array@0.11.14':
dependencies: dependencies:
'@humanwhocodes/object-schema': 2.0.2 '@humanwhocodes/object-schema': 2.0.2
debug: 4.4.0 debug: 4.4.1(supports-color@8.1.1)
minimatch: 3.1.2 minimatch: 3.1.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -17329,7 +17350,7 @@ snapshots:
- aws-crt - aws-crt
- encoding - encoding
'@langchain/community@0.3.24(8d6d0c7c173d79d9dc61e6a9334e3ecc)': '@langchain/community@0.3.24(a7747bc06767d45b4fc71d69250d6ec9)':
dependencies: dependencies:
'@browserbasehq/stagehand': 1.9.0(@playwright/test@1.49.1)(deepmerge@4.3.1)(dotenv@16.5.0)(encoding@0.1.13)(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))(zod@3.24.1) '@browserbasehq/stagehand': 1.9.0(@playwright/test@1.49.1)(deepmerge@4.3.1)(dotenv@16.5.0)(encoding@0.1.13)(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))(zod@3.24.1)
'@ibm-cloud/watsonx-ai': 1.1.2 '@ibm-cloud/watsonx-ai': 1.1.2
@@ -17340,7 +17361,7 @@ snapshots:
flat: 5.0.2 flat: 5.0.2
ibm-cloud-sdk-core: 5.3.2 ibm-cloud-sdk-core: 5.3.2
js-yaml: 4.1.0 js-yaml: 4.1.0
langchain: 0.3.11(6e4aa47666b8dfceb9beddf0b146b9ac) langchain: 0.3.11(2ecef5dd5ce3e0c6dee7163d14def631)
langsmith: 0.2.15(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) langsmith: 0.2.15(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
openai: 4.78.1(encoding@0.1.13)(zod@3.24.1) openai: 4.78.1(encoding@0.1.13)(zod@3.24.1)
uuid: 10.0.0 uuid: 10.0.0
@@ -17355,7 +17376,7 @@ snapshots:
'@aws-sdk/credential-provider-node': 3.808.0 '@aws-sdk/credential-provider-node': 3.808.0
'@azure/storage-blob': 12.26.0 '@azure/storage-blob': 12.26.0
'@browserbasehq/sdk': 2.6.0(encoding@0.1.13) '@browserbasehq/sdk': 2.6.0(encoding@0.1.13)
'@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(6e4aa47666b8dfceb9beddf0b146b9ac)) '@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)(langchain@0.3.11(2ecef5dd5ce3e0c6dee7163d14def631))
'@getzep/zep-js': 0.9.0 '@getzep/zep-js': 0.9.0
'@google-ai/generativelanguage': 2.6.0(encoding@0.1.13) '@google-ai/generativelanguage': 2.6.0(encoding@0.1.13)
'@google-cloud/storage': 7.12.1(encoding@0.1.13) '@google-cloud/storage': 7.12.1(encoding@0.1.13)
@@ -19816,6 +19837,10 @@ snapshots:
'@types/prop-types@15.7.14': {} '@types/prop-types@15.7.14': {}
'@types/proxy-from-env@1.0.4':
dependencies:
'@types/node': 20.17.57
'@types/psl@1.1.0': {} '@types/psl@1.1.0': {}
'@types/qs@6.9.15': {} '@types/qs@6.9.15': {}
@@ -20037,7 +20062,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.2.0(typescript@5.8.2) '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.8.2)
'@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.8.2) '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.8.2)
debug: 4.4.0 debug: 4.4.1(supports-color@8.1.1)
eslint: 8.57.0 eslint: 8.57.0
ts-api-utils: 1.0.1(typescript@5.8.2) ts-api-utils: 1.0.1(typescript@5.8.2)
optionalDependencies: optionalDependencies:
@@ -20068,7 +20093,7 @@ snapshots:
dependencies: dependencies:
'@typescript-eslint/types': 7.2.0 '@typescript-eslint/types': 7.2.0
'@typescript-eslint/visitor-keys': 7.2.0 '@typescript-eslint/visitor-keys': 7.2.0
debug: 4.4.0 debug: 4.4.1(supports-color@8.1.1)
globby: 11.1.0 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.3 minimatch: 9.0.3
@@ -20126,7 +20151,7 @@ snapshots:
'@typespec/ts-http-runtime@0.2.2': '@typespec/ts-http-runtime@0.2.2':
dependencies: dependencies:
http-proxy-agent: 7.0.0 http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6 https-proxy-agent: 7.0.6
tslib: 2.8.1 tslib: 2.8.1
transitivePeerDependencies: transitivePeerDependencies:
@@ -20544,17 +20569,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
agent-base@7.1.0:
dependencies:
debug: 4.4.1(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
agent-base@7.1.3: {} agent-base@7.1.3: {}
agentkeepalive@4.2.1: agentkeepalive@4.2.1:
dependencies: dependencies:
debug: 4.4.0 debug: 4.4.1(supports-color@8.1.1)
depd: 1.1.2 depd: 1.1.2
humanize-ms: 1.2.1 humanize-ms: 1.2.1
transitivePeerDependencies: transitivePeerDependencies:
@@ -20874,6 +20893,14 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
axios@1.9.0:
dependencies:
follow-redirects: 1.15.9(debug@4.3.6)
form-data: 4.0.2
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
axios@1.9.0(debug@4.3.6): axios@1.9.0(debug@4.3.6):
dependencies: dependencies:
follow-redirects: 1.15.9(debug@4.3.6) follow-redirects: 1.15.9(debug@4.3.6)
@@ -20892,7 +20919,7 @@ snapshots:
axios@1.9.0(debug@4.4.1): axios@1.9.0(debug@4.4.1):
dependencies: dependencies:
follow-redirects: 1.15.9(debug@4.3.6) follow-redirects: 1.15.9(debug@4.4.1)
form-data: 4.0.2 form-data: 4.0.2
proxy-from-env: 1.1.0 proxy-from-env: 1.1.0
transitivePeerDependencies: transitivePeerDependencies:
@@ -23024,7 +23051,7 @@ snapshots:
'@babel/parser': 7.26.10 '@babel/parser': 7.26.10
'@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
acorn-walk: 8.3.4 acorn-walk: 8.3.4
debug: 4.4.0 debug: 4.4.1(supports-color@8.1.1)
globby: 11.1.0 globby: 11.1.0
simple-bin-help: 1.8.0 simple-bin-help: 1.8.0
transitivePeerDependencies: transitivePeerDependencies:
@@ -23062,6 +23089,10 @@ snapshots:
optionalDependencies: optionalDependencies:
debug: 4.4.0 debug: 4.4.0
follow-redirects@1.15.9(debug@4.4.1):
optionalDependencies:
debug: 4.4.1(supports-color@8.1.1)
for-each@0.3.3: for-each@0.3.3:
dependencies: dependencies:
is-callable: 1.2.7 is-callable: 1.2.7
@@ -23616,7 +23647,14 @@ snapshots:
http-proxy-agent@7.0.0: http-proxy-agent@7.0.0:
dependencies: dependencies:
agent-base: 7.1.0 agent-base: 7.1.3
debug: 4.4.1(supports-color@8.1.1)
transitivePeerDependencies:
- supports-color
http-proxy-agent@7.0.2:
dependencies:
agent-base: 7.1.3
debug: 4.4.1(supports-color@8.1.1) debug: 4.4.1(supports-color@8.1.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -23646,7 +23684,7 @@ snapshots:
https-proxy-agent@7.0.6: https-proxy-agent@7.0.6:
dependencies: dependencies:
agent-base: 7.1.3 agent-base: 7.1.3
debug: 4.4.0 debug: 4.4.1(supports-color@8.1.1)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -23675,7 +23713,7 @@ snapshots:
isstream: 0.1.2 isstream: 0.1.2
jsonwebtoken: 9.0.2 jsonwebtoken: 9.0.2
mime-types: 2.1.35 mime-types: 2.1.35
retry-axios: 2.6.0(axios@1.9.0(debug@4.4.1)) retry-axios: 2.6.0(axios@1.9.0)
tough-cookie: 4.1.4 tough-cookie: 4.1.4
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@@ -23740,7 +23778,7 @@ snapshots:
infisical-node@1.3.0: infisical-node@1.3.0:
dependencies: dependencies:
axios: 1.9.0(debug@4.4.1) axios: 1.9.0
dotenv: 16.3.1 dotenv: 16.3.1
tweetnacl: 1.0.3 tweetnacl: 1.0.3
tweetnacl-util: 0.15.1 tweetnacl-util: 0.15.1
@@ -24665,7 +24703,7 @@ snapshots:
kuler@2.0.0: {} kuler@2.0.0: {}
langchain@0.3.11(6e4aa47666b8dfceb9beddf0b146b9ac): langchain@0.3.11(2ecef5dd5ce3e0c6dee7163d14def631):
dependencies: dependencies:
'@langchain/core': 0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) '@langchain/core': 0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))
'@langchain/openai': 0.3.17(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) '@langchain/openai': 0.3.17(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
@@ -24689,7 +24727,7 @@ snapshots:
'@langchain/groq': 0.1.3(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) '@langchain/groq': 0.1.3(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
'@langchain/mistralai': 0.2.0(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))) '@langchain/mistralai': 0.2.0(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))
'@langchain/ollama': 0.1.4(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))) '@langchain/ollama': 0.1.4(@langchain/core@0.3.48(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))
axios: 1.9.0(debug@4.4.1) axios: 1.9.0
cheerio: 1.0.0 cheerio: 1.0.0
handlebars: 4.7.8 handlebars: 4.7.8
transitivePeerDependencies: transitivePeerDependencies:
@@ -26487,7 +26525,7 @@ snapshots:
posthog-node@3.2.1: posthog-node@3.2.1:
dependencies: dependencies:
axios: 1.9.0(debug@4.4.1) axios: 1.9.0
rusha: 0.8.14 rusha: 0.8.14
transitivePeerDependencies: transitivePeerDependencies:
- debug - debug
@@ -27064,9 +27102,9 @@ snapshots:
onetime: 5.1.2 onetime: 5.1.2
signal-exit: 3.0.7 signal-exit: 3.0.7
retry-axios@2.6.0(axios@1.9.0(debug@4.4.1)): retry-axios@2.6.0(axios@1.9.0):
dependencies: dependencies:
axios: 1.9.0(debug@4.4.1) axios: 1.9.0
retry-request@7.0.2(encoding@0.1.13): retry-request@7.0.2(encoding@0.1.13):
dependencies: dependencies:
@@ -27528,7 +27566,7 @@ snapshots:
asn1.js: 5.4.1 asn1.js: 5.4.1
asn1.js-rfc2560: 5.0.1(asn1.js@5.4.1) asn1.js-rfc2560: 5.0.1(asn1.js@5.4.1)
asn1.js-rfc5280: 3.0.0 asn1.js-rfc5280: 3.0.0
axios: 1.9.0(debug@4.4.1) axios: 1.9.0
big-integer: 1.6.52 big-integer: 1.6.52
bignumber.js: 9.1.2 bignumber.js: 9.1.2
binascii: 0.0.2 binascii: 0.0.2

View File

@@ -21,6 +21,8 @@ catalog:
fast-glob: 3.2.12 fast-glob: 3.2.12
flatted: 3.2.7 flatted: 3.2.7
form-data: 4.0.0 form-data: 4.0.0
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
iconv-lite: 0.6.3 iconv-lite: 0.6.3
jsonwebtoken: 9.0.2 jsonwebtoken: 9.0.2
js-base64: 3.7.2 js-base64: 3.7.2