1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-10-05 17:17:45 +03:00

refactor(core): Remove Ask AI HTTP request feature (no-changelog) (#9931)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2024-07-04 12:09:45 +02:00 committed by GitHub
parent cef177455e
commit 86018aa6e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 30 additions and 5198 deletions

View File

@ -90,10 +90,6 @@
"ts-essentials": "^7.0.3"
},
"dependencies": {
"@langchain/community": "0.2.2",
"@langchain/core": "0.2.9",
"@langchain/openai": "0.0.33",
"@langchain/pinecone": "0.0.6",
"@n8n/client-oauth2": "workspace:*",
"@n8n/localtunnel": "2.1.0",
"@n8n/n8n-nodes-langchain": "workspace:*",
@ -101,7 +97,6 @@
"@n8n/typeorm": "0.3.20-10",
"@n8n_io/license-sdk": "2.13.0",
"@oclif/core": "4.0.7",
"@pinecone-database/pinecone": "2.1.0",
"@rudderstack/rudder-sdk-node": "2.0.7",
"@sentry/integrations": "7.87.0",
"@sentry/node": "7.87.0",
@ -130,7 +125,6 @@
"fast-glob": "3.2.12",
"flatted": "3.2.7",
"formidable": "3.5.1",
"fuse.js": "^7.0.0",
"google-timezones-json": "1.1.0",
"handlebars": "4.7.8",
"helmet": "7.1.0",
@ -141,7 +135,6 @@
"json-diff": "1.0.6",
"jsonschema": "1.4.1",
"jsonwebtoken": "9.0.2",
"langchain": "0.2.2",
"ldapts": "4.2.6",
"lodash": "4.17.21",
"luxon": "3.3.0",
@ -185,7 +178,6 @@
"xml2js": "0.6.2",
"xmllint-wasm": "3.0.1",
"yamljs": "0.3.0",
"zod": "3.22.4",
"zod-to-json-schema": "3.22.4"
"zod": "3.22.4"
}
}

View File

@ -37,9 +37,9 @@ import { InternalHooks } from '@/InternalHooks';
import { handleMfaDisable, isMfaFeatureEnabled } from '@/Mfa/helpers';
import type { FrontendService } from '@/services/frontend.service';
import { OrchestrationService } from '@/services/orchestration.service';
import { AuditEventRelay } from './eventbus/audit-event-relay.service';
import '@/controllers/activeWorkflows.controller';
import '@/controllers/ai.controller';
import '@/controllers/auth.controller';
import '@/controllers/binaryData.controller';
import '@/controllers/curl.controller';
@ -66,7 +66,6 @@ import '@/ExternalSecrets/ExternalSecrets.controller.ee';
import '@/license/license.controller';
import '@/workflows/workflowHistory/workflowHistory.controller.ee';
import '@/workflows/workflows.controller';
import { AuditEventRelay } from './eventbus/audit-event-relay.service';
const exec = promisify(callbackExec);

View File

@ -1380,34 +1380,6 @@ export const schema = {
default: false,
env: 'N8N_AI_ENABLED',
},
provider: {
doc: 'AI provider to use. Currently only "openai" is supported.',
format: String,
default: 'openai',
env: 'N8N_AI_PROVIDER',
},
openAI: {
apiKey: {
doc: 'Enable AI features using OpenAI API key',
format: String,
default: '',
env: 'N8N_AI_OPENAI_API_KEY',
},
model: {
doc: 'OpenAI model to use',
format: String,
default: 'gpt-4-turbo',
env: 'N8N_AI_OPENAI_MODEL',
},
},
pinecone: {
apiKey: {
doc: 'Enable AI features using Pinecone API key',
format: String,
default: '',
env: 'N8N_AI_PINECONE_API_KEY',
},
},
},
expression: {

View File

@ -148,8 +148,6 @@ export const TEST_WEBHOOK_TIMEOUT = 2 * TIME.MINUTE;
export const TEST_WEBHOOK_TIMEOUT_BUFFER = 30 * TIME.SECOND;
export const N8N_DOCS_URL = 'https://docs.n8n.io';
export const GENERIC_OAUTH2_CREDENTIALS_WITH_EDITABLE_SCOPE = [
'oAuth2Api',
'googleOAuth2Api',

View File

@ -1,26 +0,0 @@
import { Post, RestController } from '@/decorators';
import { AIRequest } from '@/requests';
import { AIService } from '@/services/ai.service';
import { FailedDependencyError } from '@/errors/response-errors/failed-dependency.error';
@RestController('/ai')
export class AIController {
constructor(private readonly aiService: AIService) {}
/**
* Generate CURL request and additional HTTP Node metadata for given service and request
*/
@Post('/generate-curl')
async generateCurl(req: AIRequest.GenerateCurl): Promise<{ curl: string; metadata?: object }> {
const { service, request } = req.body;
try {
return await this.aiService.generateCurl(service, request);
} catch (aiServiceError) {
throw new FailedDependencyError(
(aiServiceError as Error).message ||
'Failed to generate HTTP Request Node parameters due to an issue with an external dependency. Please try again later.',
);
}
}
}

View File

@ -1,7 +0,0 @@
import { ResponseError } from './abstract/response.error';
export class FailedDependencyError extends ResponseError {
constructor(message: string, errorCode = 424) {
super(message, 424, errorCode);
}
}

View File

@ -169,19 +169,6 @@ export function hasSharing(
return workflows.some((w) => 'shared' in w);
}
// ----------------------------------
// /ai
// ----------------------------------
export declare namespace AIRequest {
export type GenerateCurl = AuthenticatedRequest<{}, {}, AIGenerateCurlPayload>;
}
export interface AIGenerateCurlPayload {
service: string;
request: string;
}
// ----------------------------------
// /credentials
// ----------------------------------

View File

@ -1,192 +0,0 @@
import { Service } from 'typedi';
import config from '@/config';
import type { N8nAIProviderType } from 'n8n-workflow';
import { ApplicationError, jsonParse } from 'n8n-workflow';
import type { BaseMessageLike } from '@langchain/core/messages';
import { AIProviderOpenAI } from '@/services/ai/providers/openai';
import type { BaseChatModelCallOptions } from '@langchain/core/language_models/chat_models';
import { Pinecone } from '@pinecone-database/pinecone';
import type { z } from 'zod';
import apiKnowledgebase from '@/services/ai/resources/api-knowledgebase.json';
import { JsonOutputFunctionsParser } from 'langchain/output_parsers';
import {
generateCurlCommandFallbackPromptTemplate,
generateCurlCommandPromptTemplate,
} from '@/services/ai/prompts/generateCurl';
import { generateCurlSchema } from '@/services/ai/schemas/generateCurl';
import { PineconeStore } from '@langchain/pinecone';
import Fuse from 'fuse.js';
interface APIKnowledgebaseService {
id: string;
title: string;
description?: string;
}
function isN8nAIProviderType(value: string): value is N8nAIProviderType {
return ['openai'].includes(value);
}
@Service()
export class AIService {
private providerType: N8nAIProviderType = 'unknown';
public provider: AIProviderOpenAI;
public pinecone: Pinecone;
private jsonOutputParser = new JsonOutputFunctionsParser();
constructor() {
const providerName = config.getEnv('ai.provider');
if (isN8nAIProviderType(providerName)) {
this.providerType = providerName;
}
if (this.providerType === 'openai') {
const openAIApiKey = config.getEnv('ai.openAI.apiKey');
const openAIModelName = config.getEnv('ai.openAI.model');
if (openAIApiKey) {
this.provider = new AIProviderOpenAI({ openAIApiKey, modelName: openAIModelName });
}
}
const pineconeApiKey = config.getEnv('ai.pinecone.apiKey');
if (pineconeApiKey) {
this.pinecone = new Pinecone({
apiKey: pineconeApiKey,
});
}
}
async prompt(messages: BaseMessageLike[], options?: BaseChatModelCallOptions) {
if (!this.provider) {
throw new ApplicationError('No AI provider has been configured.');
}
return await this.provider.invoke(messages, options);
}
validateCurl(result: { curl: string }) {
if (!result.curl.startsWith('curl')) {
throw new ApplicationError(
'The generated HTTP Request Node parameters format is incorrect. Please adjust your request and try again.',
);
}
result.curl = result.curl
/*
* Replaces placeholders like `{VALUE}` or `{{VALUE}}` with quoted placeholders `"{VALUE}"` or `"{{VALUE}}"`,
* ensuring that the placeholders are properly formatted within the curl command.
* - ": a colon followed by a double quote and a space
* - ( starts a capturing group
* - \{\{ two opening curly braces
* - [A-Za-z0-9_]+ one or more alphanumeric characters or underscores
* - }} two closing curly braces
* - | OR
* - \{ an opening curly brace
* - [A-Za-z0-9_]+ one or more alphanumeric characters or underscores
* - } a closing curly brace
* - ) ends the capturing group
* - /g performs a global search and replace
*
*/
.replace(/": (\{\{[A-Za-z0-9_]+}}|\{[A-Za-z0-9_]+})/g, '": "$1"') // Fix for placeholders `curl -d '{ "key": {VALUE} }'`
/*
* Removes the rogue curly bracket at the end of the curl command if it is present.
* It ensures that the curl command is properly formatted and doesn't have an extra closing curly bracket.
* - ( starts a capturing group
* - -d flag in the curl command
* - ' a single quote
* - [^']+ one or more characters that are not a single quote
* - ' a single quote
* - ) ends the capturing group
* - } a closing curly bracket
*/
.replace(/(-d '[^']+')}/, '$1'); // Fix for rogue curly bracket `curl -d '{ "key": "value" }'}`
return result;
}
async generateCurl(serviceName: string, serviceRequest: string) {
this.checkRequirements();
if (!this.pinecone) {
return await this.generateCurlGeneric(serviceName, serviceRequest);
}
const fuse = new Fuse(apiKnowledgebase as unknown as APIKnowledgebaseService[], {
threshold: 0.25,
useExtendedSearch: true,
keys: ['id', 'title'],
});
const matchedServices = fuse
.search(serviceName.replace(/ +/g, '|'))
.map((result) => result.item);
if (matchedServices.length === 0) {
return await this.generateCurlGeneric(serviceName, serviceRequest);
}
const pcIndex = this.pinecone.Index('api-knowledgebase');
const vectorStore = await PineconeStore.fromExistingIndex(this.provider.embeddings, {
namespace: 'endpoints',
pineconeIndex: pcIndex,
});
const matchedDocuments = await vectorStore.similaritySearch(
`${serviceName} ${serviceRequest}`,
4,
{
id: {
$in: matchedServices.map((service) => service.id),
},
},
);
if (matchedDocuments.length === 0) {
return await this.generateCurlGeneric(serviceName, serviceRequest);
}
const aggregatedDocuments = matchedDocuments.reduce<unknown[]>((acc, document) => {
const pageData = jsonParse(document.pageContent);
acc.push(pageData);
return acc;
}, []);
const generateCurlChain = generateCurlCommandPromptTemplate
.pipe(this.provider.modelWithOutputParser(generateCurlSchema))
.pipe(this.jsonOutputParser);
const result = (await generateCurlChain.invoke({
endpoints: JSON.stringify(aggregatedDocuments),
serviceName,
serviceRequest,
})) as z.infer<typeof generateCurlSchema>;
return this.validateCurl(result);
}
async generateCurlGeneric(serviceName: string, serviceRequest: string) {
this.checkRequirements();
const generateCurlFallbackChain = generateCurlCommandFallbackPromptTemplate
.pipe(this.provider.modelWithOutputParser(generateCurlSchema))
.pipe(this.jsonOutputParser);
const result = (await generateCurlFallbackChain.invoke({
serviceName,
serviceRequest,
})) as z.infer<typeof generateCurlSchema>;
return this.validateCurl(result);
}
checkRequirements() {
if (!this.provider) {
throw new ApplicationError('No AI provider has been configured.');
}
}
}

View File

@ -1,67 +0,0 @@
import {
ChatPromptTemplate,
HumanMessagePromptTemplate,
SystemMessagePromptTemplate,
} from '@langchain/core/prompts';
export const generateCurlCommandPromptTemplate = new ChatPromptTemplate({
promptMessages: [
SystemMessagePromptTemplate.fromTemplate(`# What you need to do
You are a curl command generator engine. Your task is to provide a curl command that the user could run to call the endpoint they described.
When generating the curl data, make sure it's a 100% valid stringified JSON format.
Use placeholders with the \`{{PLACEHOLDER}}\` format for the parameters that need to be filled with real-world example values.
# What you need to know
Here is the specification for an API you will be working with:
\`\`\`json
{endpoints}
\`\`\`
# How to complete the task
To do this, take your time to analyze the API specification entries and then follow these steps:
1. Carefully read the user's prompt to determine which specific API endpoint and HTTP method (GET, POST, etc.) they need to use.
2. List out the required parameters needed to make a successful request to that endpoint. Parameters can be included in the url, query string, headers, or request body.
3. Include the correct authentication mechanism to make a successful request to that endpoint. Ensure the curl command includes all the necessary headers and authentication information.
4. Outline the structure of the curl command, including the HTTP method, full URL, and all the required parameters.
5. Write out the final curl command that the user could copy and paste to execute the API request they described.
IMPORTANT: Only construct a curl command for the specific endpoint and method that matches what the user described. Ensure that the command is valid and respects the steps above. If you fail to provide a valid curl command, your response will be rejected.`),
HumanMessagePromptTemplate.fromTemplate(`Service name: {serviceName}
Service request: {serviceRequest}`),
],
inputVariables: ['endpoints', 'serviceName', 'serviceRequest'],
});
export const generateCurlCommandFallbackPromptTemplate = new ChatPromptTemplate({
promptMessages: [
SystemMessagePromptTemplate.fromTemplate(`# What you need to do
You are a curl command generator engine. Your task is to provide a curl command that the user could run to call the endpoint they described.
When generating the curl data, make sure it's a 100% valid stringified JSON format.
Use placeholders with the \`{{PLACEHOLDER}}\` format for the parameters that need to be filled with real-world example values.
# How to complete the task
To construct the curl command, follow these steps:
1. Carefully read the user's prompt to determine which specific API the user will interact with based on the provided service name and description. List out the HTTP method (GET, POST, etc.), full endpoint URL, and all the required parameters, including the \`url\`, \`method\`, \`headers\`, \`query\`, \`body\`, and authentication mechanism.
2. List out the required parameters needed to make a successful request to that endpoint. Parameters can be included in the url, query string, headers, or request body.
3. Include the correct authentication mechanism to make a successful request to that endpoint. Ensure the curl command includes all the necessary headers and authentication information. If you are unsure about the authentication mechanism, you can infer the most likely authentication method based on the API specification.
4. Outline the structure of the curl command, including the HTTP method, full URL, and all the required parameters. Fill the required parameters with real-world example values.
5. Write out the final curl command that the user could copy and paste to execute the API request they described.
IMPORTANT: Only construct a curl command for the specific endpoint and method that matches what the user described. Ensure that the command is valid and respects the steps above. If you fail to provide a valid curl command, your response will be rejected.`),
HumanMessagePromptTemplate.fromTemplate(`Service name: {serviceName}
Service request: {serviceRequest}`),
],
inputVariables: ['serviceName', 'serviceRequest'],
});

View File

@ -1,21 +0,0 @@
import {
ChatPromptTemplate,
HumanMessagePromptTemplate,
SystemMessagePromptTemplate,
} from '@langchain/core/prompts';
export const retrieveServicePromptTemplate = new ChatPromptTemplate({
promptMessages: [
SystemMessagePromptTemplate.fromTemplate(`Based on the list of available service APIs in the CSV, please return the \`id\` of the CSV entry that is most relevant for the user provided request.
List Available service APIs in the following CSV Format: \`id\` | \`title\` | \`description\`
\`\`\`csv
{services}
\`\`\`
IMPORTANT: Return the \`id\` of the service exactly as found in the CSV. If none of the services match perfectly, always return the \`id\` as empty string, NEVER hallucinate a service that is not on this list.`),
HumanMessagePromptTemplate.fromTemplate(`Service API name: {serviceName}
Service API Request: {serviceRequest}`),
],
inputVariables: ['services', 'serviceName', 'serviceRequest'],
});

View File

@ -1,64 +0,0 @@
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
import type { BaseMessageChunk, BaseMessageLike } from '@langchain/core/messages';
import type { N8nAIProvider } from '@/types/ai.types';
import type { BaseChatModelCallOptions } from '@langchain/core/language_models/chat_models';
import { zodToJsonSchema } from 'zod-to-json-schema';
import type { ZodSchema } from 'zod';
export class AIProviderOpenAI implements N8nAIProvider {
public model: ChatOpenAI;
public embeddings: OpenAIEmbeddings;
constructor({ openAIApiKey, modelName }: { openAIApiKey: string; modelName: string }) {
this.model = new ChatOpenAI({
openAIApiKey,
modelName,
timeout: 60000,
maxRetries: 2,
temperature: 0,
});
this.embeddings = new OpenAIEmbeddings({
openAIApiKey,
modelName: 'text-embedding-3-small',
});
}
modelWithOutputParser<T extends ZodSchema>(schema: T) {
return this.model.bind({
functions: [
{
name: 'output_formatter',
description: 'Should always be used to properly format output',
parameters: zodToJsonSchema(schema),
},
],
function_call: {
name: 'output_formatter',
},
});
}
mapResponse(data: BaseMessageChunk): string {
if (Array.isArray(data.content)) {
return data.content
.map((message): string =>
'text' in message
? (message.text as string)
: 'image_url' in message
? (message.image_url as string)
: '',
)
.join('\n');
}
return data.content;
}
async invoke(messages: BaseMessageLike[], options?: BaseChatModelCallOptions) {
const data = await this.model.invoke(messages, options);
return this.mapResponse(data);
}
}

View File

@ -1,9 +0,0 @@
# AI Resources
## API Knowledgebase
**File**: `api-knowledgebase.json`
The relevant repository for generating this file is [here](https://github.com/n8n-io/n8n-ai-apis-knowledgebase).
This file is **auto-generated** for the AI Service, and it contains a list of all the available APIs that can be used to train the AI model from our Vector Store. Currently, this is used when generating a `curl` command for the HTTP Request Node.

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +0,0 @@
import { z } from 'zod';
export const generateCurlSchema = z.object({
curl: z
.string()
.describe('The curl command that the user could run to call the endpoint they described.'),
});

View File

@ -1,9 +0,0 @@
import { z } from 'zod';
export const retrieveServiceSchema = z.object({
id: z
.string()
.describe(
'The id of the service, has to match the `id` of one of the entries in the CSV file or empty string',
),
});

View File

@ -1,35 +0,0 @@
/* eslint-disable @typescript-eslint/no-use-before-define */
import type { INodeProperties, INodePropertyCollection, INodePropertyOptions } from 'n8n-workflow';
export function summarizeOption(
option: INodePropertyOptions | INodeProperties | INodePropertyCollection,
): Partial<INodePropertyOptions | INodeProperties | INodePropertyCollection> {
if ('value' in option) {
return {
name: option.name,
value: option.value,
};
} else if ('values' in option) {
return {
name: option.name,
values: option.values.map(summarizeProperty) as INodeProperties[],
};
} else {
return summarizeProperty(option);
}
}
export function summarizeProperty(property: INodeProperties): Partial<INodeProperties> {
return {
name: property.displayName,
type: property.type,
...(property.displayOptions ? { displayOptions: property.displayOptions } : {}),
...((property.options
? { options: property.options.map(summarizeOption) }
: {}) as INodeProperties['options']),
};
}
export function summarizeNodeTypeProperties(nodeTypeProperties: INodeProperties[]) {
return nodeTypeProperties.map(summarizeProperty);
}

View File

@ -216,10 +216,6 @@ export class FrontendService {
},
ai: {
enabled: config.getEnv('ai.enabled'),
provider: config.getEnv('ai.provider'),
features: {
generateCurl: !!config.getEnv('ai.openAI.apiKey'),
},
},
workflowHistory: {
pruneTime: -1,

View File

@ -1,7 +0,0 @@
import type { BaseMessageChunk, BaseMessageLike } from '@langchain/core/messages';
import type { BaseChatModelCallOptions } from '@langchain/core/language_models/chat_models';
export interface N8nAIProvider {
invoke(message: BaseMessageLike[], options?: BaseChatModelCallOptions): Promise<string>;
mapResponse(data: BaseMessageChunk): string;
}

View File

@ -1,225 +0,0 @@
import { ApplicationError, jsonParse } from 'n8n-workflow';
import { AIService } from '@/services/ai.service';
import config from '@/config';
import {
generateCurlCommandFallbackPromptTemplate,
generateCurlCommandPromptTemplate,
} from '@/services/ai/prompts/generateCurl';
import { PineconeStore } from '@langchain/pinecone';
jest.mock('@/config', () => {
return {
getEnv: jest.fn().mockReturnValue('openai'),
};
});
jest.mock('langchain/output_parsers', () => {
return {
JsonOutputFunctionsParser: jest.fn().mockImplementation(() => {
return {
parse: jest.fn(),
};
}),
};
});
jest.mock('@langchain/pinecone', () => {
const similaritySearch = jest.fn().mockImplementation(async () => []);
return {
PineconeStore: {
similaritySearch,
fromExistingIndex: jest.fn().mockImplementation(async () => ({
similaritySearch,
})),
},
};
});
jest.mock('@pinecone-database/pinecone', () => ({
Pinecone: jest.fn().mockImplementation(() => ({
Index: jest.fn().mockImplementation(() => ({})),
})),
}));
jest.mock('@/services/ai/providers/openai', () => {
const modelInvoke = jest.fn().mockImplementation(() => ({ curl: 'curl -X GET https://n8n.io' }));
return {
AIProviderOpenAI: jest.fn().mockImplementation(() => {
return {
mapResponse: jest.fn((v) => v),
invoke: modelInvoke,
model: {
invoke: modelInvoke,
},
modelWithOutputParser: () => ({
invoke: modelInvoke,
}),
};
}),
};
});
afterEach(() => {
jest.clearAllMocks();
});
describe('AIService', () => {
describe('constructor', () => {
test('should not assign provider with unknown provider type', async () => {
jest.mocked(config).getEnv.mockReturnValue('unknown');
const aiService = new AIService();
expect(aiService.provider).not.toBeDefined();
});
});
describe('prompt', () => {
test('should throw if prompting with unknown provider type', async () => {
jest.mocked(config).getEnv.mockReturnValue('unknown');
const aiService = new AIService();
await expect(async () => await aiService.prompt([])).rejects.toThrow(ApplicationError);
});
test('should call provider.invoke', async () => {
jest.mocked(config).getEnv.mockReturnValue('openai');
const service = new AIService();
await service.prompt(['message']);
expect(service.provider.invoke).toHaveBeenCalled();
});
});
describe('generateCurl', () => {
test('should call generateCurl fallback if pinecone key is not defined', async () => {
jest.mocked(config).getEnv.mockImplementation((key: string) => {
if (key === 'ai.pinecone.apiKey') {
return undefined;
}
return 'openai';
});
const service = new AIService();
const generateCurlGenericSpy = jest.spyOn(service, 'generateCurlGeneric');
service.validateCurl = (v) => v;
const serviceName = 'Service Name';
const serviceRequest = 'Please make a request';
await service.generateCurl(serviceName, serviceRequest);
expect(generateCurlGenericSpy).toHaveBeenCalled();
});
test('should call generateCurl fallback if no matched service', async () => {
jest.mocked(config).getEnv.mockReturnValue('openai');
const service = new AIService();
const generateCurlGenericSpy = jest.spyOn(service, 'generateCurlGeneric');
service.validateCurl = (v) => v;
const serviceName = 'NoMatchedServiceName';
const serviceRequest = 'Please make a request';
await service.generateCurl(serviceName, serviceRequest);
expect(generateCurlGenericSpy).toHaveBeenCalled();
});
test('should call generateCurl fallback command if no matched vector store documents', async () => {
jest.mocked(config).getEnv.mockReturnValue('openai');
const service = new AIService();
const generateCurlGenericSpy = jest.spyOn(service, 'generateCurlGeneric');
service.validateCurl = (v) => v;
const serviceName = 'OpenAI';
const serviceRequest = 'Please make a request';
await service.generateCurl(serviceName, serviceRequest);
expect(generateCurlGenericSpy).toHaveBeenCalled();
});
test('should call generateCurl command with documents from vectorStore', async () => {
const endpoints = [
{
id: '1',
title: 'OpenAI',
pageContent: '{ "example": "value" }',
},
];
const serviceName = 'OpenAI';
const serviceRequest = 'Please make a request';
jest.mocked(config).getEnv.mockReturnValue('openai');
jest
.mocked((PineconeStore as unknown as { similaritySearch: () => {} }).similaritySearch)
.mockImplementation(async () => endpoints);
const service = new AIService();
service.validateCurl = (v) => v;
await service.generateCurl(serviceName, serviceRequest);
const messages = await generateCurlCommandPromptTemplate.formatMessages({
serviceName,
serviceRequest,
endpoints: JSON.stringify(endpoints.map((document) => jsonParse(document.pageContent))),
});
expect(service.provider.model.invoke).toHaveBeenCalled();
expect(service.provider.model.invoke.mock.calls[0][0].messages).toEqual(messages);
});
});
describe('generateCurlGeneric', () => {
test('should call prompt with serviceName and serviceRequest', async () => {
const serviceName = 'Service Name';
const serviceRequest = 'Please make a request';
const service = new AIService();
service.validateCurl = (v) => v;
await service.generateCurlGeneric(serviceName, serviceRequest);
const messages = await generateCurlCommandFallbackPromptTemplate.formatMessages({
serviceName,
serviceRequest,
});
expect(service.provider.model.invoke).toHaveBeenCalled();
expect(jest.mocked(service.provider.model.invoke).mock.calls[0][0].messages).toEqual(
messages,
);
});
});
describe('validateCurl', () => {
it('should return the result if curl command starts with "curl"', () => {
const aiService = new AIService();
const result = { curl: 'curl -X GET https://n8n.io' };
const validatedResult = aiService.validateCurl(result);
expect(validatedResult).toEqual(result);
});
it('should replace boolean and number placeholders in the curl command', () => {
const aiService = new AIService();
const result = { curl: 'curl -X GET https://n8n.io -d "{ "key": {{value}} }"' };
const expected = { curl: 'curl -X GET https://n8n.io -d "{ "key": "{{value}}" }"' };
const validatedResult = aiService.validateCurl(result);
expect(validatedResult).toEqual(expected);
});
it('should throw an error if curl command does not start with "curl"', () => {
const aiService = new AIService();
const result = { curl: 'wget -O - https://n8n.io' };
expect(() => aiService.validateCurl(result)).toThrow(ApplicationError);
});
});
});

View File

@ -1,193 +0,0 @@
import type { INodeProperties, INodePropertyCollection, INodePropertyOptions } from 'n8n-workflow';
import {
summarizeNodeTypeProperties,
summarizeOption,
summarizeProperty,
} from '@/services/ai/utils/summarizeNodeTypeProperties';
describe('summarizeOption', () => {
it('should return summarized option with value', () => {
const option: INodePropertyOptions = {
name: 'testOption',
value: 'testValue',
};
const result = summarizeOption(option);
expect(result).toEqual({
name: 'testOption',
value: 'testValue',
});
});
it('should return summarized option with values', () => {
const option: INodePropertyCollection = {
name: 'testOption',
displayName: 'testDisplayName',
values: [
{
name: 'testName',
default: '',
displayName: 'testDisplayName',
type: 'string',
},
],
};
const result = summarizeOption(option);
expect(result).toEqual({
name: 'testOption',
values: [
{
name: 'testDisplayName',
type: 'string',
},
],
});
});
it('should return summarized property', () => {
const option: INodeProperties = {
name: 'testName',
default: '',
displayName: 'testDisplayName',
type: 'string',
};
const result = summarizeOption(option);
expect(result).toEqual({
name: 'testDisplayName',
type: 'string',
});
});
});
describe('summarizeProperty', () => {
it('should return summarized property with displayOptions', () => {
const property: INodeProperties = {
default: '',
name: 'testName',
displayName: 'testDisplayName',
type: 'string',
displayOptions: {
show: {
testOption: ['testValue'],
},
},
};
const result = summarizeProperty(property);
expect(result).toEqual({
name: 'testDisplayName',
type: 'string',
displayOptions: {
show: {
testOption: ['testValue'],
},
},
});
});
it('should return summarized property with options', () => {
const property: INodeProperties = {
name: 'testName',
displayName: 'testDisplayName',
default: '',
type: 'string',
options: [
{
name: 'testOption',
value: 'testValue',
},
],
};
const result = summarizeProperty(property);
expect(result).toEqual({
name: 'testDisplayName',
type: 'string',
options: [
{
name: 'testOption',
value: 'testValue',
},
],
});
});
it('should return summarized property without displayOptions and options', () => {
const property: INodeProperties = {
name: 'testName',
default: '',
displayName: 'testDisplayName',
type: 'string',
};
const result = summarizeProperty(property);
expect(result).toEqual({
name: 'testDisplayName',
type: 'string',
});
});
});
describe('summarizeNodeTypeProperties', () => {
it('should return summarized properties', () => {
const properties: INodeProperties[] = [
{
name: 'testName1',
default: '',
displayName: 'testDisplayName1',
type: 'string',
options: [
{
name: 'testOption1',
value: 'testValue1',
},
],
},
{
name: 'testName2',
default: '',
displayName: 'testDisplayName2',
type: 'number',
options: [
{
name: 'testOption2',
value: 'testValue2',
},
],
},
];
const result = summarizeNodeTypeProperties(properties);
expect(result).toEqual([
{
name: 'testDisplayName1',
type: 'string',
options: [
{
name: 'testOption1',
value: 'testValue1',
},
],
},
{
name: 'testDisplayName2',
type: 'number',
options: [
{
name: 'testOption2',
value: 'testValue2',
},
],
},
]);
});
});

View File

@ -26,9 +26,6 @@
<component :is="Component" v-else />
</router-view>
</div>
<div id="chat" :class="{ [$style.chat]: true, [$style.open]: aiStore.assistantChatOpen }">
<AIAssistantChat v-if="aiStore.assistantChatOpen" />
</div>
<Modals />
<Telemetry />
</div>
@ -60,8 +57,6 @@ import { useUsageStore } from '@/stores/usage.store';
import { useUsersStore } from '@/stores/users.store';
import { useHistoryHelper } from '@/composables/useHistoryHelper';
import { useRoute } from 'vue-router';
import { useAIStore } from './stores/ai.store';
import AIAssistantChat from './components/AIAssistantChat/AIAssistantChat.vue';
export default defineComponent({
name: 'App',
@ -70,7 +65,6 @@ export default defineComponent({
LoadingView,
Telemetry,
Modals,
AIAssistantChat,
},
setup() {
return {
@ -91,7 +85,6 @@ export default defineComponent({
useSourceControlStore,
useCloudPlanStore,
useUsageStore,
useAIStore,
),
defaultLocale(): string {
return this.rootStore.defaultLocale;
@ -134,10 +127,10 @@ export default defineComponent({
.container {
display: grid;
grid-template-areas:
'banners banners banners'
'sidebar header chat'
'sidebar content chat';
grid-auto-columns: fit-content($sidebar-expanded-width) 1fr fit-content($chat-width);
'banners banners'
'sidebar header'
'sidebar content';
grid-auto-columns: fit-content($sidebar-expanded-width) 1fr;
grid-template-rows: auto fit-content($header-height) 1fr;
height: 100vh;
}
@ -171,15 +164,4 @@ export default defineComponent({
height: 100%;
z-index: 999;
}
.chat {
grid-area: chat;
z-index: 999;
height: 100%;
width: 0;
transition: all 0.2s ease-in-out;
&.open {
width: $chat-width;
}
}
</style>

View File

@ -1856,10 +1856,6 @@ export type NewConnectionInfo = {
endpointUuid?: string;
};
export type AIAssistantConnectionInfo = NewConnectionInfo & {
stepName?: string;
};
export type EnterpriseEditionFeatureKey =
| 'AdvancedExecutionFilters'
| 'Sharing'

View File

@ -114,10 +114,6 @@ export const defaultSettings: IN8nUISettings = {
},
ai: {
enabled: false,
provider: '',
features: {
generateCurl: false,
},
},
workflowHistory: {
pruneTime: 0,

View File

@ -2,16 +2,6 @@ import type { IRestApiContext, Schema } from '@/Interface';
import { makeRestApiRequest } from '@/utils/apiUtils';
import type { IDataObject } from 'n8n-workflow';
export interface GenerateCurlPayload {
service: string;
request: string;
}
export interface GenerateCurlResponse {
curl: string;
metadata: object;
}
export async function generateCodeForPrompt(
ctx: IRestApiContext,
{
@ -38,15 +28,3 @@ export async function generateCodeForPrompt(
n8nVersion,
} as IDataObject);
}
export const generateCurl = async (
context: IRestApiContext,
payload: GenerateCurlPayload,
): Promise<GenerateCurlResponse> => {
return await makeRestApiRequest(
context,
'POST',
'/ai/generate-curl',
payload as unknown as IDataObject,
);
};

View File

@ -1,225 +0,0 @@
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n';
import { useUsersStore } from '@/stores/users.store';
import ChatComponent from '@n8n/chat/components/Chat.vue';
import { ChatOptionsSymbol, ChatSymbol } from '@n8n/chat/constants';
import type { Chat, ChatMessage, ChatOptions } from '@n8n/chat/types';
import type { Ref } from 'vue';
import { computed, provide, ref, onMounted, onBeforeUnmount } from 'vue';
import QuickReplies from './QuickReplies.vue';
import { DateTime } from 'luxon';
import { useAIStore } from '@/stores/ai.store';
import { chatEventBus } from '@n8n/chat/event-buses';
import {
AI_ASSISTANT_EXPERIMENT_URLS,
AI_ASSISTANT_LOCAL_STORAGE_KEY,
MODAL_CONFIRM,
} from '@/constants';
import { useStorage } from '@/composables/useStorage';
import { useMessage } from '@/composables/useMessage';
import { useTelemetry } from '@/composables/useTelemetry';
const locale = useI18n();
const telemetry = useTelemetry();
const { confirm } = useMessage();
const usersStore = useUsersStore();
const aiStore = useAIStore();
const messages: Ref<ChatMessage[]> = ref([]);
const waitingForResponse = ref(false);
const currentSessionId = ref<string>(String(Date.now()));
const disableChat = ref(false);
const userName = computed(() => usersStore.currentUser?.firstName ?? 'there');
const latestConnectionInfo = computed(() => aiStore.latestConnectionInfo);
const chatTitle = locale.baseText('aiAssistantChat.title');
const nowMilliseconds = () => String(DateTime.now().toMillis());
const nowIsoString = () => new Date().toISOString();
const thanksResponses: ChatMessage[] = [
{
id: nowMilliseconds(),
sender: 'bot',
text: locale.baseText('aiAssistantChat.response.message1'),
createdAt: nowIsoString(),
},
{
id: nowMilliseconds(),
sender: 'bot',
text: locale.baseText('aiAssistantChat.response.message2'),
createdAt: nowIsoString(),
},
{
id: nowMilliseconds(),
sender: 'bot',
text: '🙏',
createdAt: new Date().toISOString(),
},
{
id: nowMilliseconds(),
type: 'component',
key: 'QuickReplies',
sender: 'user',
createdAt: nowIsoString(),
transparent: true,
arguments: {
suggestions: [
{ label: locale.baseText('aiAssistantChat.response.quickReply.close'), key: 'close' },
{
label: locale.baseText('aiAssistantChat.response.quickReply.giveFeedback'),
key: 'give_feedback',
},
{
label: locale.baseText('aiAssistantChat.response.quickReply.signUp'),
key: 'sign_up',
},
],
onReplySelected: ({ key }: { key: string; label: string }) => {
switch (key) {
case 'give_feedback':
window.open(AI_ASSISTANT_EXPERIMENT_URLS.FEEDBACK_FORM, '_blank');
break;
case 'sign_up':
window.open(AI_ASSISTANT_EXPERIMENT_URLS.SIGN_UP, '_blank');
break;
}
aiStore.assistantChatOpen = false;
},
},
},
];
const initialMessageText = computed(() => {
if (latestConnectionInfo.value?.stepName) {
return locale.baseText('aiAssistantChat.initialMessage.nextStep', {
interpolate: { currentAction: latestConnectionInfo.value.stepName },
});
}
return locale.baseText('aiAssistantChat.initialMessage.firstStep');
});
const initialMessages: Ref<ChatMessage[]> = ref([
{
id: '1',
type: 'text',
sender: 'bot',
createdAt: new Date().toISOString(),
text: `${locale.baseText('aiAssistantChat.greeting', { interpolate: { username: userName.value ?? 'there' } })} ${initialMessageText.value}`,
},
]);
const sendMessage = async (message: string) => {
disableChat.value = true;
waitingForResponse.value = true;
messages.value.push({
id: String(messages.value.length + 1),
sender: 'user',
text: message,
createdAt: new Date().toISOString(),
});
trackUserMessage(message);
thanksResponses.forEach((response, index) => {
// Push each response with a delay of 1500ms
setTimeout(
() => {
messages.value.push(response);
chatEventBus.emit('scrollToBottom');
if (index === thanksResponses.length - 1) {
waitingForResponse.value = false;
// Once last message is sent, disable the experiment
useStorage(AI_ASSISTANT_LOCAL_STORAGE_KEY).value = 'true';
}
},
1500 * (index + 1),
);
});
chatEventBus.emit('scrollToBottom');
};
const trackUserMessage = (message: string) => {
telemetry.track('User responded in AI chat', {
prompt: message,
chatMode: 'nextStepAssistant',
initialMessage: initialMessageText.value,
});
};
const chatOptions: ChatOptions = {
i18n: {
en: {
title: chatTitle,
footer: '',
subtitle: '',
inputPlaceholder: locale.baseText('aiAssistantChat.chatPlaceholder'),
getStarted: locale.baseText('aiAssistantChat.getStarted'),
closeButtonTooltip: locale.baseText('aiAssistantChat.closeButtonTooltip'),
},
},
webhookUrl: 'https://webhook.url',
mode: 'window',
showWindowCloseButton: true,
messageComponents: {
QuickReplies,
},
disabled: disableChat,
};
const chatConfig: Chat = {
messages,
sendMessage,
initialMessages,
currentSessionId,
waitingForResponse,
};
provide(ChatSymbol, chatConfig);
provide(ChatOptionsSymbol, chatOptions);
onMounted(() => {
chatEventBus.emit('focusInput');
chatEventBus.on('close', onBeforeClose);
});
onBeforeUnmount(() => {
chatEventBus.off('close', onBeforeClose);
});
async function onBeforeClose() {
const confirmModal = await confirm(locale.baseText('aiAssistantChat.closeChatConfirmation'), {
confirmButtonText: locale.baseText('aiAssistantChat.closeChatConfirmation.confirm'),
cancelButtonText: locale.baseText('aiAssistantChat.closeChatConfirmation.cancel'),
});
if (confirmModal === MODAL_CONFIRM) {
aiStore.assistantChatOpen = false;
}
}
</script>
<template>
<div :class="[$style.container, 'ignore-key-press']">
<ChatComponent />
</div>
</template>
<style module lang="scss">
.container {
height: 100%;
background-color: var(--color-background-light);
filter: drop-shadow(0px 8px 24px #41424412);
border-left: 1px solid var(--color-foreground-dark);
overflow: hidden;
}
.header {
font-size: var(--font-size-l);
background-color: #fff;
padding: var(--spacing-xs);
}
.content {
padding: var(--spacing-xs);
}
</style>

View File

@ -1,148 +0,0 @@
<script setup lang="ts">
import { useAIStore } from '@/stores/ai.store';
import { useI18n } from '@/composables/useI18n';
import { computed } from 'vue';
import { useTelemetry } from '@/composables/useTelemetry';
const aiStore = useAIStore();
const locale = useI18n();
const telemetry = useTelemetry();
const emit = defineEmits<{ optionSelected: [option: string] }>();
const aiAssistantChatOpen = computed(() => aiStore.assistantChatOpen);
const title = computed(() => {
return aiStore.nextStepPopupConfig.title;
});
const options = computed(() => [
{
label: locale.baseText('nextStepPopup.option.choose'),
icon: '',
key: 'choose',
disabled: false,
},
{
label: locale.baseText('nextStepPopup.option.generate'),
icon: '✨',
key: 'generate',
disabled: aiAssistantChatOpen.value,
},
]);
const position = computed(() => {
return [aiStore.nextStepPopupConfig.position[0], aiStore.nextStepPopupConfig.position[1]];
});
const style = computed(() => {
return {
left: `${position.value[0]}px`,
top: `${position.value[1]}px`,
};
});
const close = () => {
aiStore.closeNextStepPopup();
};
const onOptionSelected = (option: string) => {
if (option === 'choose') {
emit('optionSelected', option);
} else if (option === 'generate') {
telemetry.track('User clicked generate AI button', {}, { withPostHog: true });
aiStore.assistantChatOpen = true;
}
close();
};
</script>
<template>
<div v-on-click-outside="close" :class="$style.container" :style="style">
<div :class="$style.title">{{ title }}</div>
<ul :class="$style.options">
<li
v-for="option in options"
:key="option.key"
:class="{ [$style.option]: true, [$style.disabled]: option.disabled }"
@click="onOptionSelected(option.key)"
>
<div :class="$style.icon">
{{ option.icon }}
</div>
<div :class="$style.label">
{{ option.label }}
</div>
</li>
</ul>
</div>
</template>
<style module lang="scss">
.container {
position: fixed;
display: flex;
flex-direction: column;
min-width: 190px;
font-size: var(--font-size-2xs);
background: var(--color-background-xlight);
filter: drop-shadow(0px 6px 16px #441c170f);
border: var(--border-width-base) var(--border-style-base) var(--color-foreground-light);
border-radius: var(--border-radius-base);
// Arrow border is created as the outer triange
&:before {
content: '';
position: relative;
left: -11px;
top: calc(50% - 8px);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid var(--color-foreground-light);
position: absolute;
}
// Arrow background is created as the inner triangle
&:after {
content: '';
position: relative;
left: -10px;
top: calc(50% - 8px);
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid var(--color-background-xlight);
position: absolute;
}
}
.title {
padding: var(--spacing-xs);
color: var(--color-text-base);
font-weight: var(--font-weight-bold);
}
.options {
list-style: none;
display: flex;
flex-direction: column;
padding-bottom: var(--spacing-2xs);
}
.option {
display: flex;
padding: var(--spacing-3xs) var(--spacing-xs);
gap: var(--spacing-xs);
cursor: pointer;
color: var(--color-text-dark);
&:hover {
background: var(--color-background-base);
font-weight: var(--font-weight-bold);
}
&.disabled {
pointer-events: none;
color: var(--color-text-light);
}
}
</style>

View File

@ -1,66 +0,0 @@
<script setup lang="ts">
import { useI18n } from '@/composables/useI18n';
import Button from 'n8n-design-system/components/N8nButton/Button.vue';
type QuickReply = {
label: string;
key: string;
};
const locale = useI18n();
const emit = defineEmits<{
replySelected: [value: QuickReply];
}>();
defineProps<{
suggestions: QuickReply[];
}>();
function onButtonClick(action: QuickReply) {
emit('replySelected', action);
}
</script>
<template>
<div :class="$style.container">
<p :class="$style.hint">{{ locale.baseText('aiAssistantChat.quickReply.title') }}</p>
<div :class="$style.suggestions">
<Button
v-for="action in suggestions"
:key="action.key"
:class="$style.replyButton"
outline
type="secondary"
@click="onButtonClick(action)"
>
{{ action.label }}
</Button>
</div>
</div>
</template>
<style module lang="scss">
.container {
display: flex;
flex-direction: column;
gap: var(--spacing-2xs);
width: auto;
justify-content: flex-end;
align-items: flex-end;
}
.suggestions {
display: flex;
flex-direction: column;
width: fit-content;
gap: var(--spacing-4xs);
}
.hint {
color: var(--color-text-base);
font-size: var(--font-size-2xs);
}
.replyButton {
display: flex;
background: var(--chat--color-white);
}
</style>

View File

@ -1,216 +0,0 @@
<template>
<Modal
width="700px"
:title="i18n.baseText('generateCurlModal.title')"
:event-bus="modalBus"
:name="GENERATE_CURL_MODAL_KEY"
:center="true"
>
<template #content>
<div :class="$style.container">
<N8nFormInputs
:inputs="formInputs"
:event-bus="formBus"
column-view
@update="onUpdate"
@submit="onSubmit"
/>
</div>
</template>
<template #footer>
<div :class="$style.modalFooter">
<N8nNotice
:class="$style.notice"
:content="i18n.baseText('generateCurlModal.notice.content')"
/>
<div>
<N8nButton
float="right"
:loading="loading"
:label="i18n.baseText('generateCurlModal.button.label')"
@click="onGenerate"
/>
</div>
</div>
</template>
</Modal>
</template>
<script lang="ts" setup>
import Modal from '@/components/Modal.vue';
import { GENERATE_CURL_MODAL_KEY } from '@/constants';
import { ref } from 'vue';
import { createEventBus } from 'n8n-design-system/utils';
import { useTelemetry } from '@/composables/useTelemetry';
import { useI18n } from '@/composables/useI18n';
import { useAIStore } from '@/stores/ai.store';
import type { IFormInput } from 'n8n-design-system';
import { useToast } from '@/composables/useToast';
import { useImportCurlCommand } from '@/composables/useImportCurlCommand';
import { useUIStore } from '@/stores/ui.store';
import { useNDVStore } from '@/stores/ndv.store';
const telemetry = useTelemetry();
const i18n = useI18n();
const toast = useToast();
const uiStore = useUIStore();
const aiStore = useAIStore();
const ndvStore = useNDVStore();
const modalBus = createEventBus();
const formBus = createEventBus();
const initialServiceValue = uiStore.modalsById[GENERATE_CURL_MODAL_KEY].data?.service as string;
const initialRequestValue = uiStore.modalsById[GENERATE_CURL_MODAL_KEY].data?.request as string;
const formInputs: IFormInput[] = [
{
name: 'service',
initialValue: initialServiceValue,
properties: {
label: i18n.baseText('generateCurlModal.service.label'),
placeholder: i18n.baseText('generateCurlModal.service.placeholder'),
type: 'text',
required: true,
capitalize: true,
},
},
{
name: 'request',
initialValue: initialRequestValue,
properties: {
label: i18n.baseText('generateCurlModal.request.label'),
placeholder: i18n.baseText('generateCurlModal.request.placeholder'),
type: 'text',
required: true,
capitalize: true,
},
},
];
const formValues = ref<{ service: string; request: string }>({
service: initialServiceValue ?? '',
request: initialRequestValue ?? '',
});
const loading = ref(false);
const { importCurlCommand } = useImportCurlCommand({
onImportSuccess,
onImportFailure,
onAfterImport,
i18n: {
invalidCurCommand: {
title: 'generateCurlModal.invalidCurlCommand.title',
message: 'generateCurlModal.invalidCurlCommand.message',
},
},
});
function closeDialog(): void {
modalBus.emit('close');
}
function onImportSuccess() {
sendImportCurlTelemetry();
toast.showMessage({
title: i18n.baseText('generateCurlModal.success.title'),
message: i18n.baseText('generateCurlModal.success.message'),
type: 'success',
});
closeDialog();
}
function onImportFailure(data: { invalidProtocol: boolean; protocol?: string }) {
sendImportCurlTelemetry({ valid: false, ...data });
}
function onAfterImport() {
uiStore.setModalData({
name: GENERATE_CURL_MODAL_KEY,
data: {
service: formValues.value.service,
request: formValues.value.request,
},
});
}
function sendImportCurlTelemetry(
data: { valid: boolean; invalidProtocol: boolean; protocol?: string } = {
valid: true,
invalidProtocol: false,
protocol: '',
},
): void {
const service = formValues.value.service;
const request = formValues.value.request;
telemetry.track(
'User generated curl command using AI',
{
request,
request_service_name: service,
valid_curl_response: data.valid,
api_docs_returned: false,
invalidProtocol: data.invalidProtocol,
protocol: data.protocol,
node_type: ndvStore.activeNode?.type,
node_name: ndvStore.activeNode?.name,
},
{ withPostHog: true },
);
}
async function onUpdate(field: { name: string; value: string }) {
formValues.value = {
...formValues.value,
[field.name]: field.value,
};
}
async function onGenerate() {
formBus.emit('submit');
}
async function onSubmit() {
const service = formValues.value.service;
const request = formValues.value.request;
try {
loading.value = true;
const data = await aiStore.generateCurl({
service,
request,
});
await importCurlCommand(data.curl);
} catch (error) {
toast.showError(error, i18n.baseText('error'));
} finally {
loading.value = false;
}
}
</script>
<style module lang="scss">
.modalFooter {
justify-content: space-between;
display: flex;
flex-direction: row;
}
.notice {
margin: 0;
}
.container > * {
margin-bottom: var(--spacing-s);
&:last-child {
margin-bottom: 0;
}
}
</style>

View File

@ -1,22 +1,16 @@
<script lang="ts" setup>
import { GENERATE_CURL_MODAL_KEY, IMPORT_CURL_MODAL_KEY } from '@/constants';
import { IMPORT_CURL_MODAL_KEY } from '@/constants';
import { useUIStore } from '@/stores/ui.store';
import { useAIStore } from '@/stores/ai.store';
defineProps<{
isReadOnly: boolean;
}>();
const uiStore = useUIStore();
const aiStore = useAIStore();
function onImportCurlClicked() {
uiStore.openModal(IMPORT_CURL_MODAL_KEY);
}
function onGenerateCurlClicked() {
uiStore.openModal(GENERATE_CURL_MODAL_KEY);
}
</script>
<template>
@ -28,16 +22,6 @@ function onGenerateCurlClicked() {
size="mini"
@click="onImportCurlClicked"
/>
<n8n-button
v-if="aiStore.isGenerateCurlEnabled"
class="mr-2xs"
type="secondary"
:label="$locale.baseText('generateCurlParameter.label')"
:disabled="isReadOnly"
size="mini"
@click="onGenerateCurlClicked"
/>
</div>
</template>

View File

@ -29,7 +29,6 @@ import {
MFA_SETUP_MODAL_KEY,
WORKFLOW_HISTORY_VERSION_RESTORE,
SETUP_CREDENTIALS_MODAL_KEY,
GENERATE_CURL_MODAL_KEY,
PROJECT_MOVE_RESOURCE_MODAL,
PROJECT_MOVE_RESOURCE_CONFIRM_MODAL,
} from '@/constants';
@ -55,7 +54,6 @@ import WorkflowSettings from '@/components/WorkflowSettings.vue';
import DeleteUserModal from '@/components/DeleteUserModal.vue';
import ActivationModal from '@/components/ActivationModal.vue';
import ImportCurlModal from '@/components/ImportCurlModal.vue';
import GenerateCurlModal from '@/components/GenerateCurlModal.vue';
import MfaSetupModal from '@/components/MfaSetupModal.vue';
import WorkflowShareModal from '@/components/WorkflowShareModal.ee.vue';
import EventDestinationSettingsModal from '@/components/SettingsLogStreaming/EventDestinationSettingsModal.ee.vue';
@ -166,10 +164,6 @@ import ProjectMoveResourceConfirmModal from '@/components/Projects/ProjectMoveRe
<ImportCurlModal />
</ModalRoot>
<ModalRoot :name="GENERATE_CURL_MODAL_KEY">
<GenerateCurlModal />
</ModalRoot>
<ModalRoot :name="COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY">
<template #default="{ modalName, activeId, mode }">
<CommunityPackageManageConfirmModal

View File

@ -10,7 +10,7 @@
<div
v-if="active"
ref="nodeCreator"
:class="{ [$style.nodeCreator]: true, [$style.chatOpened]: chatSidebarOpen }"
:class="{ [$style.nodeCreator]: true }"
:style="nodeCreatorInlineStyle"
data-test-id="node-creator"
@dragover="onDragOver"
@ -37,7 +37,6 @@ import { useActionsGenerator } from './composables/useActionsGeneration';
import NodesListPanel from './Panel/NodesListPanel.vue';
import { useCredentialsStore } from '@/stores/credentials.store';
import { useUIStore } from '@/stores/ui.store';
import { useAIStore } from '@/stores/ai.store';
import { DRAG_EVENT_DATA_KEY } from '@/constants';
export interface Props {
@ -53,7 +52,6 @@ const emit = defineEmits<{
nodeTypeSelected: [value: string[]];
}>();
const uiStore = useUIStore();
const aiStore = useAIStore();
const { setShowScrim, setActions, setMergeNodes } = useNodeCreatorStore();
const { generateMergedNodesAndActions } = useActionsGenerator();
@ -67,8 +65,6 @@ const showScrim = computed(() => useNodeCreatorStore().showScrim);
const viewStacksLength = computed(() => useViewStacks().viewStacks.length);
const chatSidebarOpen = computed(() => aiStore.assistantChatOpen);
const nodeCreatorInlineStyle = computed(() => {
return { top: `${uiStore.bannersHeight + uiStore.headerHeight}px` };
});
@ -177,10 +173,6 @@ onBeforeUnmount(() => {
z-index: 200;
width: $node-creator-width;
color: $node-creator-text-color;
&.chatOpened {
right: $chat-width;
}
}
.nodeCreatorScrim {

View File

@ -58,7 +58,6 @@ export const ONBOARDING_CALL_SIGNUP_MODAL_KEY = 'onboardingCallSignup';
export const COMMUNITY_PACKAGE_INSTALL_MODAL_KEY = 'communityPackageInstall';
export const COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY = 'communityPackageManageConfirm';
export const IMPORT_CURL_MODAL_KEY = 'importCurl';
export const GENERATE_CURL_MODAL_KEY = 'generateCurl';
export const LOG_STREAM_MODAL_KEY = 'settingsLogStream';
export const SOURCE_CONTROL_PUSH_MODAL_KEY = 'sourceControlPush';
export const SOURCE_CONTROL_PULL_MODAL_KEY = 'sourceControlPull';
@ -671,12 +670,6 @@ export const ASK_AI_EXPERIMENT = {
export const TEMPLATE_CREDENTIAL_SETUP_EXPERIMENT = '017_template_credential_setup_v2';
export const AI_ASSISTANT_EXPERIMENT = {
name: '19_ai_assistant_experiment',
control: 'control',
variant: 'variant',
};
export const CANVAS_AUTO_ADD_MANUAL_TRIGGER_EXPERIMENT = {
name: '20_canvas_auto_add_manual_trigger',
control: 'control',
@ -686,7 +679,6 @@ export const CANVAS_AUTO_ADD_MANUAL_TRIGGER_EXPERIMENT = {
export const EXPERIMENTS_TO_TRACK = [
ASK_AI_EXPERIMENT.name,
TEMPLATE_CREDENTIAL_SETUP_EXPERIMENT,
AI_ASSISTANT_EXPERIMENT.name,
CANVAS_AUTO_ADD_MANUAL_TRIGGER_EXPERIMENT.name,
];
@ -848,13 +840,6 @@ export const INSECURE_CONNECTION_WARNING = `
</div>
</body>`;
export const AI_ASSISTANT_EXPERIMENT_URLS = {
FEEDBACK_FORM: 'https://chat.arro.co/to4639rATEMV',
SIGN_UP: 'https://adore.app.n8n.cloud/form/4704cce3-4cef-4dc8-b67f-8a510c5d561a',
};
export const AI_ASSISTANT_LOCAL_STORAGE_KEY = 'N8N_AI_ASSISTANT_EXPERIMENT';
/**
* Injection Keys
*/

View File

@ -36,7 +36,6 @@ $warning-tooltip-color: var(--color-danger);
// sass variable is used for scss files
$header-height: calc(var(--header-height) * 1px);
$chat-width: calc(var(--chat-width) * 1px);
// sidebar
$sidebar-width: 65px;

View File

@ -4,34 +4,6 @@
:root {
// Using native css variable enables us to use this value in JS
--header-height: 65;
--chat-width: 350;
// n8n-chat customizations
--chat--spacing: var(--spacing-2xs);
--chat--header-height: calc(var(--header-height) * 1px);
--chat--header--padding: 0 var(--spacing-xs);
--chat--heading--font-size: var(--font-size-m);
--chat--subtitle--font-size: var(--font-size-s);
--chat--subtitle--line-height: var(--font-line-height-base);
--chat--header--background: var(--color-background-xlight);
--chat--header--color: var(--color-text-dark);
--chat--header--border-bottom: var(--border-base);
--chat--close--button--color-hover: var(--color-primary);
// Message styles
--chat--message--padding: var(--spacing-3xs);
--chat--message--font-size: 14px;
--chat--message-line-height: 1.5;
--chat--message--bot--border: 1px solid var(--color-foreground-light);
--chat--message--bot--color: var(--color-text-dark);
--chat--message--user--color: var(--color-text-dark);
--chat--message--user--background: var(--color-success-tint-1);
--chat--message--user--border: 1px solid var(--color-success-light-2);
// Chat input
--chat--input--font-size: var(--font-size-s);
--chat--input--send--button--color: var(--color-success);
}
.clickable {

View File

@ -96,22 +96,6 @@
"activationModal.yourTriggersWillNowFire": "Your triggers will now fire production executions automatically.",
"activationModal.yourWorkflowWillNowListenForEvents": "Your workflow will now listen for events from {serviceName} and trigger executions.",
"activationModal.yourWorkflowWillNowRegularlyCheck": "Your workflow will now regularly check {serviceName} for events and trigger executions for them.",
"aiAssistantChat.title": "✨ Generate workflow step with AI",
"aiAssistantChat.greeting": "Hi {username}!",
"aiAssistantChat.chatPlaceholder": "Enter your response...",
"aiAssistantChat.getStarted": "Get started",
"aiAssistantChat.initialMessage.firstStep": "What should the first step in your workflow do?",
"aiAssistantChat.initialMessage.nextStep": "Can you describe the next step after the __{currentAction}__ action in your workflow?",
"aiAssistantChat.response.message1": "Thanks for trying our new __Generate Workflow Step__ feature. Currently, the feature is not ready yet. We're gathering real-world prompts like yours to ensure we're creating a high-quality, valuable feature.",
"aiAssistantChat.response.message2": "We understand this may be disappointing, but we believe it's crucial to developing the best possible feature for you and others. Wed love to invite you to be one of the first users to get their hands on the real feature once its ready.",
"aiAssistantChat.response.quickReply.close": "Close chat thread",
"aiAssistantChat.response.quickReply.signUp": "Sign up for early access",
"aiAssistantChat.response.quickReply.giveFeedback": "Give feedback to product team",
"aiAssistantChat.closeButtonTooltip": "Close chat",
"aiAssistantChat.closeChatConfirmation": "Are you sure you want to end this chat session?",
"aiAssistantChat.closeChatConfirmation.confirm": "Yes, close it",
"aiAssistantChat.closeChatConfirmation.cancel": "No, stay",
"aiAssistantChat.quickReply.title": "Quick reply 👇",
"auth.changePassword": "Change password",
"auth.changePassword.currentPassword": "Current password",
"auth.changePassword.error": "Problem changing the password",
@ -966,10 +950,6 @@
"ndv.httpRequest.credentialOnly.docsNotice": "Use the <a target=\"_blank\" href=\"{docsUrl}\">{nodeName} docs</a> to construct your request. We'll take care of the authentication part if you add a {nodeName} credential below.",
"noTagsView.readyToOrganizeYourWorkflows": "Ready to organize your workflows?",
"noTagsView.withWorkflowTagsYouReFree": "With workflow tags, you're free to create the perfect tagging system for your flows",
"nextStepPopup.title.firstStep": "What triggers this workflow?",
"nextStepPopup.title.nextStep": "What happens next?",
"nextStepPopup.option.choose": "Choose from list...",
"nextStepPopup.option.generate": "Generate step with AI...",
"node.thisIsATriggerNode": "This is a Trigger node. <a target=\"_blank\" href=\"https://docs.n8n.io/workflows/components/nodes/\">Learn more</a>",
"node.activateDeactivateNode": "Activate/Deactivate Node",
"node.changeColor": "Change color",
@ -2265,18 +2245,6 @@
"importCurlParameter.showError.invalidProtocol1.title": "Use the {node} node",
"importCurlParameter.showError.invalidProtocol2.title": "Invalid Protocol",
"importCurlParameter.showError.invalidProtocol.message": "The HTTP node doesnt support {protocol} requests",
"generateCurlParameter.label": "Ask AI ✨",
"generateCurlModal.title": "Generate HTTP Request",
"generateCurlModal.notice.content": "This will overwrite any changes you have already made to the current node",
"generateCurlModal.button.label": "Generate",
"generateCurlModal.service.label": "Service",
"generateCurlModal.service.placeholder": "Enter the name of the service",
"generateCurlModal.request.label": "Request",
"generateCurlModal.request.placeholder": "Describe the request you want to make",
"generateCurlModal.invalidCurlCommand.title": "Generation failed",
"generateCurlModal.invalidCurlCommand.message": "The AI couldn't process your request",
"generateCurlModal.success.title": "HTTP Request filled out",
"generateCurlModal.success.message": "Please check carefully as AI content can be inaccurate",
"variables.heading": "Variables",
"variables.add": "Add variable",
"variables.add.unavailable": "Upgrade plan to keep using variables",

View File

@ -1,67 +0,0 @@
import { defineStore } from 'pinia';
import * as aiApi from '@/api/ai';
import type { GenerateCurlPayload } from '@/api/ai';
import { useRootStore } from '@/stores/root.store';
import { useSettingsStore } from '@/stores/settings.store';
import { computed, reactive, ref } from 'vue';
import type { Ref } from 'vue';
import type { AIAssistantConnectionInfo, XYPosition } from '@/Interface';
import { usePostHog } from './posthog.store';
import { AI_ASSISTANT_EXPERIMENT } from '@/constants';
const CURRENT_POPUP_HEIGHT = 94;
/**
* Calculates the position for the next step popup based on the specified element
* so they are aligned vertically.
*/
const getPopupCenterPosition = (relativeElement: HTMLElement) => {
const bounds = relativeElement.getBoundingClientRect();
const rectMiddle = bounds.top + bounds.height / 2;
const x = bounds.left + bounds.width + 22;
const y = rectMiddle - CURRENT_POPUP_HEIGHT / 2;
return [x, y] as XYPosition;
};
export const useAIStore = defineStore('ai', () => {
const rootStore = useRootStore();
const settingsStore = useSettingsStore();
const posthogStore = usePostHog();
const assistantChatOpen = ref(false);
const nextStepPopupConfig = reactive({
open: false,
title: '',
position: [0, 0] as XYPosition,
});
const latestConnectionInfo: Ref<AIAssistantConnectionInfo | null> = ref(null);
const isGenerateCurlEnabled = computed(() => settingsStore.settings.ai.features.generateCurl);
const isAssistantExperimentEnabled = computed(
() => posthogStore.getVariant(AI_ASSISTANT_EXPERIMENT.name) === AI_ASSISTANT_EXPERIMENT.variant,
);
function openNextStepPopup(title: string, relativeElement: HTMLElement) {
nextStepPopupConfig.open = true;
nextStepPopupConfig.title = title;
nextStepPopupConfig.position = getPopupCenterPosition(relativeElement);
}
function closeNextStepPopup() {
nextStepPopupConfig.open = false;
}
async function generateCurl(payload: GenerateCurlPayload) {
return await aiApi.generateCurl(rootStore.restApiContext, payload);
}
return {
assistantChatOpen,
nextStepPopupConfig,
openNextStepPopup,
closeNextStepPopup,
latestConnectionInfo,
generateCurl,
isGenerateCurlEnabled,
isAssistantExperimentEnabled,
};
});

View File

@ -12,7 +12,7 @@ import type {
SimplifiedNodeType,
ActionsRecord,
ToggleNodeCreatorOptions,
AIAssistantConnectionInfo,
NewConnectionInfo,
} from '@/Interface';
import { computed, ref } from 'vue';
@ -172,7 +172,7 @@ export const useNodeCreatorStore = defineStore(STORES.NODE_CREATOR, () => {
});
}
function openNodeCreatorForConnectingNode(info: AIAssistantConnectionInfo) {
function openNodeCreatorForConnectingNode(info: NewConnectionInfo) {
const type = info.outputType ?? NodeConnectionType.Main;
// Get the node and set it as active that new nodes
// which get created get automatically connected

View File

@ -34,7 +34,6 @@ import {
N8N_PRICING_PAGE_URL,
WORKFLOW_HISTORY_VERSION_RESTORE,
SETUP_CREDENTIALS_MODAL_KEY,
GENERATE_CURL_MODAL_KEY,
PROJECT_MOVE_RESOURCE_MODAL,
PROJECT_MOVE_RESOURCE_CONFIRM_MODAL,
} from '@/constants';
@ -141,13 +140,6 @@ export const useUIStore = defineStore(STORES.UI, () => {
curlCommand: '',
},
},
[GENERATE_CURL_MODAL_KEY]: {
open: false,
data: {
service: '',
request: '',
},
},
[LOG_STREAM_MODAL_KEY]: {
open: false,
data: undefined,

View File

@ -120,9 +120,6 @@
<Suspense>
<ContextMenu @action="onContextMenuAction" />
</Suspense>
<Suspense>
<NextStepPopup v-show="isNextStepPopupVisible" @option-selected="onNextStepSelected" />
</Suspense>
<div v-if="!isReadOnlyRoute && !readOnlyEnv" class="workflow-execute-wrapper">
<span
v-if="!isManualChatOnly"
@ -246,7 +243,6 @@ import {
AI_NODE_CREATOR_VIEW,
DRAG_EVENT_DATA_KEY,
UPDATE_WEBHOOK_ID_NODE_TYPES,
AI_ASSISTANT_LOCAL_STORAGE_KEY,
CANVAS_AUTO_ADD_MANUAL_TRIGGER_EXPERIMENT,
} from '@/constants';
@ -268,7 +264,6 @@ import Node from '@/components/Node.vue';
import Sticky from '@/components/Sticky.vue';
import CanvasAddButton from './CanvasAddButton.vue';
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
import NextStepPopup from '@/components/AIAssistantChat/NextStepPopup.vue';
import { v4 as uuid } from 'uuid';
import type {
IConnection,
@ -314,7 +309,6 @@ import type {
AddedNodesAndConnections,
ToggleNodeCreatorOptions,
IPushDataExecutionFinished,
AIAssistantConnectionInfo,
NodeFilterType,
} from '@/Interface';
@ -389,8 +383,6 @@ import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
import { useRunWorkflow } from '@/composables/useRunWorkflow';
import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectSharingData } from '@/types/projects.types';
import { useAIStore } from '@/stores/ai.store';
import { useStorage } from '@/composables/useStorage';
import { isJSPlumbEndpointElement, isJSPlumbConnection } from '@/utils/typeGuards';
import { usePostHog } from '@/stores/posthog.store';
import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
@ -424,7 +416,6 @@ export default defineComponent({
CanvasControls,
ContextMenu,
SetupWorkflowCredentialsButton,
NextStepPopup,
},
async beforeRouteLeave(to, from, next) {
if (
@ -587,7 +578,6 @@ export default defineComponent({
useSourceControlStore,
useExecutionsStore,
useProjectsStore,
useAIStore,
useNpsSurveyStore,
),
nativelyNumberSuffixedDefaults(): string[] {
@ -752,16 +742,6 @@ export default defineComponent({
isReadOnlyRoute() {
return this.$route?.meta?.readOnlyCanvas === true;
},
isNextStepPopupVisible(): boolean {
return this.aiStore.nextStepPopupConfig.open;
},
shouldShowNextStepDialog(): boolean {
const userHasSeenAIAssistantExperiment =
useStorage(AI_ASSISTANT_LOCAL_STORAGE_KEY).value === 'true';
const experimentEnabled = this.aiStore.isAssistantExperimentEnabled;
const isCloudDeployment = this.settingsStore.isCloudDeployment;
return isCloudDeployment && experimentEnabled && !userHasSeenAIAssistantExperiment;
},
isProductionExecutionPreview(): boolean {
return this.nodeHelpers.isProductionExecutionPreview.value;
},
@ -1247,32 +1227,8 @@ export default defineComponent({
}
}
},
async onCanvasAddButtonCLick(event: PointerEvent) {
if (event) {
if (this.shouldShowNextStepDialog) {
const newNodeButton = (event.target as HTMLElement).closest('button');
if (newNodeButton) {
this.aiStore.latestConnectionInfo = null;
this.aiStore.openNextStepPopup(
this.$locale.baseText('nextStepPopup.title.firstStep'),
newNodeButton,
);
}
return;
}
this.showTriggerCreator(NODE_CREATOR_OPEN_SOURCES.TRIGGER_PLACEHOLDER_BUTTON);
return;
}
},
onNextStepSelected(action: string) {
if (action === 'choose') {
const lastConnectionInfo = this.aiStore.latestConnectionInfo as NewConnectionInfo;
if (lastConnectionInfo === null) {
this.showTriggerCreator(NODE_CREATOR_OPEN_SOURCES.TRIGGER_PLACEHOLDER_BUTTON);
} else {
this.insertNodeAfterSelected(lastConnectionInfo);
}
}
async onCanvasAddButtonCLick() {
this.showTriggerCreator(NODE_CREATOR_OPEN_SOURCES.TRIGGER_PLACEHOLDER_BUTTON);
},
showTriggerCreator(source: NodeCreatorOpenSource) {
if (this.createNodeActive) return;
@ -1508,7 +1464,6 @@ export default defineComponent({
// Save the location of the mouse click
this.lastClickPosition = this.getMousePositionWithinNodeView(e);
if (e instanceof MouseEvent && e.button === 1) {
this.aiStore.closeNextStepPopup();
this.moveCanvasKeyPressed = true;
}
@ -1535,7 +1490,6 @@ export default defineComponent({
},
async keyDown(e: KeyboardEvent) {
this.contextMenu.close();
this.aiStore.closeNextStepPopup();
const ctrlModifier = this.deviceSupport.isCtrlKeyPressed(e) && !e.shiftKey && !e.altKey;
const shiftModifier = e.shiftKey && !e.altKey && !this.deviceSupport.isCtrlKeyPressed(e);
@ -2904,7 +2858,7 @@ export default defineComponent({
return filter;
},
insertNodeAfterSelected(info: AIAssistantConnectionInfo) {
insertNodeAfterSelected(info: NewConnectionInfo) {
const type = info.outputType ?? NodeConnectionType.Main;
// Get the node and set it as active that new nodes
// which get created get automatically connected
@ -2982,59 +2936,12 @@ export default defineComponent({
}
return;
}
// When connection is aborted, we want to show the 'Next step' popup
const endpointId = `${connection.parameters.nodeId}-output${connection.parameters.index}`;
const endpoint = connection.instance.getEndpoint(endpointId);
// First, show node creator if endpoint is not a plus endpoint
// or if the AI Assistant experiment doesn't need to be shown to user
if (!endpoint?.endpoint?.canvas || !this.shouldShowNextStepDialog) {
this.insertNodeAfterSelected({
sourceId: connection.parameters.nodeId,
index: connection.parameters.index,
eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_DROP,
connection,
outputType: connection.parameters.type,
});
return;
}
// Else render the popup
const endpointElement: HTMLElement = endpoint.endpoint.canvas;
// Use observer to trigger the popup once the endpoint is rendered back again
// after connection drag is aborted (so we can get it's position and dimensions)
const observer = new MutationObserver((mutations) => {
// Find the mutation in which the current endpoint becomes visible again
const endpointMutation = mutations.find((mutation) => {
const target = mutation.target;
return (
isJSPlumbEndpointElement(target) &&
target.jtk?.endpoint?.uuid === endpoint.uuid &&
target.style.display === 'block'
);
});
if (endpointMutation) {
// When found, display the popup
const newConnectionInfo: AIAssistantConnectionInfo = {
sourceId: connection.parameters.nodeId,
index: connection.parameters.index,
eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_DROP,
outputType: connection.parameters.type,
endpointUuid: endpoint.uuid,
stepName: endpoint.__meta.nodeName,
};
this.aiStore.latestConnectionInfo = newConnectionInfo;
this.aiStore.openNextStepPopup(
this.$locale.baseText('nextStepPopup.title.nextStep'),
endpointElement,
);
observer.disconnect();
return;
}
});
observer.observe(this.$refs.nodeViewRef as HTMLElement, {
attributes: true,
attributeFilter: ['style'],
subtree: true,
this.insertNodeAfterSelected({
sourceId: connection.parameters.nodeId,
index: connection.parameters.index,
eventSource: NODE_CREATOR_OPEN_SOURCES.NODE_CONNECTION_DROP,
connection,
outputType: connection.parameters.type,
});
} catch (e) {
console.error(e);
@ -3562,32 +3469,13 @@ export default defineComponent({
.forEach((endpoint) => setTimeout(() => endpoint.instance.revalidate(endpoint.element), 0));
},
onPlusEndpointClick(endpoint: Endpoint) {
if (this.shouldShowNextStepDialog) {
if (endpoint?.__meta) {
this.aiStore.latestConnectionInfo = {
sourceId: endpoint.__meta.nodeId,
index: endpoint.__meta.index,
eventSource: NODE_CREATOR_OPEN_SOURCES.PLUS_ENDPOINT,
outputType: getEndpointScope(endpoint.scope),
endpointUuid: endpoint.uuid,
stepName: endpoint.__meta.nodeName,
};
const endpointElement = endpoint.endpoint.canvas;
this.aiStore.openNextStepPopup(
this.$locale.baseText('nextStepPopup.title.nextStep'),
endpointElement,
);
}
} else {
this.insertNodeAfterSelected({
sourceId: endpoint.__meta.nodeId,
index: endpoint.__meta.index,
eventSource: NODE_CREATOR_OPEN_SOURCES.PLUS_ENDPOINT,
outputType: getEndpointScope(endpoint.scope),
endpointUuid: endpoint.uuid,
stepName: endpoint.__meta.nodeName,
});
}
this.insertNodeAfterSelected({
sourceId: endpoint.__meta.nodeId,
index: endpoint.__meta.index,
eventSource: NODE_CREATOR_OPEN_SOURCES.PLUS_ENDPOINT,
outputType: getEndpointScope(endpoint.scope),
endpointUuid: endpoint.uuid,
});
},
onAddInputEndpointClick(endpoint: Endpoint) {
if (endpoint?.__meta) {

View File

@ -2681,10 +2681,6 @@ export interface IN8nUISettings {
};
ai: {
enabled: boolean;
provider: string;
features: {
generateCurl: boolean;
};
};
workflowHistory: {
pruneTime: number;

View File

@ -526,18 +526,6 @@ importers:
packages/cli:
dependencies:
'@langchain/community':
specifier: 0.2.2
version: 0.2.2(@aws-sdk/client-bedrock-runtime@3.535.0)(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@getzep/zep-js@0.9.0)(@google-cloud/storage@6.11.0(encoding@0.1.13))(@huggingface/inference@2.7.0)(@mozilla/readability@0.5.0)(@pinecone-database/pinecone@2.1.0)(@qdrant/js-client-rest@1.9.0(typescript@5.5.2))(@smithy/eventstream-codec@2.2.0)(@smithy/protocol-http@3.3.0)(@smithy/signature-v4@2.2.1)(@smithy/util-utf8@2.3.0)(@supabase/postgrest-js@1.15.2)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(cohere-ai@7.10.1(encoding@0.1.13))(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(jsonwebtoken@9.0.2)(lodash@4.17.21)(mammoth@1.7.2)(mysql2@3.10.0)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(pg@8.11.3)(redis@4.6.14)(ws@8.17.1)
'@langchain/core':
specifier: 0.2.9
version: 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
'@langchain/openai':
specifier: 0.0.33
version: 0.0.33(encoding@0.1.13)(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))
'@langchain/pinecone':
specifier: 0.0.6
version: 0.0.6(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
'@n8n/client-oauth2':
specifier: workspace:*
version: link:../@n8n/client-oauth2
@ -559,9 +547,6 @@ importers:
'@oclif/core':
specifier: 4.0.7
version: 4.0.7
'@pinecone-database/pinecone':
specifier: 2.1.0
version: 2.1.0
'@rudderstack/rudder-sdk-node':
specifier: 2.0.7
version: 2.0.7(tslib@2.6.2)
@ -646,9 +631,6 @@ importers:
formidable:
specifier: 3.5.1
version: 3.5.1
fuse.js:
specifier: ^7.0.0
version: 7.0.0
google-timezones-json:
specifier: 1.1.0
version: 1.1.0
@ -679,9 +661,6 @@ importers:
jsonwebtoken:
specifier: 9.0.2
version: 9.0.2
langchain:
specifier: 0.2.2
version: 0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1)
ldapts:
specifier: 4.2.6
version: 4.2.6
@ -814,9 +793,6 @@ importers:
zod:
specifier: 3.22.4
version: 3.22.4
zod-to-json-schema:
specifier: 3.22.4
version: 3.22.4(zod@3.22.4)
devDependencies:
'@redocly/cli':
specifier: ^1.6.0
@ -3945,363 +3921,6 @@ packages:
youtubei.js:
optional: true
'@langchain/community@0.2.2':
resolution: {integrity: sha512-TtlZnPBYt7Sujc1hAYvdZKUmV97wuF15O7b4nBX4lBfQeW38N0DwGbhqpitDbpaJqZ2s8DM4rjapECk0kIdAww==}
engines: {node: '>=18'}
peerDependencies:
'@aws-crypto/sha256-js': ^5.0.0
'@aws-sdk/client-bedrock-agent-runtime': ^3.485.0
'@aws-sdk/client-bedrock-runtime': ^3.422.0
'@aws-sdk/client-dynamodb': ^3.310.0
'@aws-sdk/client-kendra': ^3.352.0
'@aws-sdk/client-lambda': ^3.310.0
'@aws-sdk/client-s3': ^3.310.0
'@aws-sdk/client-sagemaker-runtime': ^3.310.0
'@aws-sdk/client-sfn': ^3.310.0
'@aws-sdk/credential-provider-node': ^3.388.0
'@azure/search-documents': ^12.0.0
'@azure/storage-blob': ^12.15.0
'@browserbasehq/sdk': '*'
'@clickhouse/client': ^0.2.5
'@cloudflare/ai': '*'
'@datastax/astra-db-ts': ^1.0.0
'@elastic/elasticsearch': ^8.4.0
'@getmetal/metal-sdk': '*'
'@getzep/zep-js': ^0.9.0
'@gomomento/sdk': ^1.51.1
'@gomomento/sdk-core': ^1.51.1
'@google-ai/generativelanguage': ^0.2.1
'@google-cloud/storage': ^6.10.1 || ^7.7.0
'@gradientai/nodejs-sdk': ^1.2.0
'@huggingface/inference': ^2.6.4
'@layerup/layerup-security': ^1.5.12
'@mendable/firecrawl-js': ^0.0.13
'@mlc-ai/web-llm': ^0.2.35
'@mozilla/readability': '*'
'@neondatabase/serverless': '*'
'@notionhq/client': ^2.2.10
'@opensearch-project/opensearch': '*'
'@pinecone-database/pinecone': '*'
'@planetscale/database': ^1.8.0
'@premai/prem-sdk': ^0.3.25
'@qdrant/js-client-rest': ^1.8.2
'@raycast/api': ^1.55.2
'@rockset/client': ^0.9.1
'@smithy/eventstream-codec': ^2.0.5
'@smithy/protocol-http': ^3.0.6
'@smithy/signature-v4': ^2.0.10
'@smithy/util-utf8': ^2.0.0
'@spider-cloud/spider-client': ^0.0.21
'@supabase/postgrest-js': ^1.1.1
'@supabase/supabase-js': ^2.10.0
'@tensorflow-models/universal-sentence-encoder': '*'
'@tensorflow/tfjs-converter': '*'
'@tensorflow/tfjs-core': '*'
'@upstash/redis': ^1.20.6
'@upstash/vector': ^1.0.7
'@vercel/kv': ^0.2.3
'@vercel/postgres': ^0.5.0
'@writerai/writer-sdk': ^0.40.2
'@xata.io/client': ^0.28.0
'@xenova/transformers': ^2.5.4
'@zilliz/milvus2-sdk-node': '>=2.2.7'
apify-client: ^2.7.1
assemblyai: ^4.0.0
better-sqlite3: ^9.4.0
cassandra-driver: ^4.7.2
cborg: ^4.1.1
cheerio: ^1.0.0-rc.12
chromadb: '*'
closevector-common: 0.1.3
closevector-node: 0.1.6
closevector-web: 0.1.6
cohere-ai: '*'
convex: ^1.3.1
couchbase: ^4.3.0
d3-dsv: ^2.0.0
discord.js: ^14.14.1
dria: ^0.0.3
duck-duck-scrape: ^2.2.5
epub2: ^3.0.1
faiss-node: ^0.5.1
firebase-admin: ^11.9.0 || ^12.0.0
google-auth-library: ^8.9.0
googleapis: ^126.0.1
hnswlib-node: ^3.0.0
html-to-text: ^9.0.5
ignore: ^5.2.0
interface-datastore: ^8.2.11
ioredis: ^5.3.2
it-all: ^3.0.4
jsdom: '*'
jsonwebtoken: ^9.0.2
llmonitor: ^0.5.9
lodash: ^4.17.21
lunary: ^0.6.11
mammoth: ^1.6.0
mongodb: '>=5.2.0'
mysql2: ^3.3.3
neo4j-driver: '*'
node-llama-cpp: '*'
notion-to-md: ^3.1.0
officeparser: ^4.0.4
pdf-parse: 1.1.1
pg: ^8.11.0
pg-copy-streams: ^6.0.5
pickleparser: ^0.2.1
playwright: ^1.32.1
portkey-ai: ^0.1.11
puppeteer: ^19.7.2
redis: '*'
replicate: ^0.18.0
sonix-speech-recognition: ^2.1.1
srt-parser-2: ^1.2.3
typeorm: ^0.3.12
typesense: ^1.5.3
usearch: ^1.1.1
vectordb: ^0.1.4
voy-search: 0.6.2
weaviate-ts-client: '*'
web-auth-library: ^1.0.3
ws: '>=8.17.1'
youtube-transcript: ^1.0.6
youtubei.js: ^9.1.0
peerDependenciesMeta:
'@aws-crypto/sha256-js':
optional: true
'@aws-sdk/client-bedrock-agent-runtime':
optional: true
'@aws-sdk/client-bedrock-runtime':
optional: true
'@aws-sdk/client-dynamodb':
optional: true
'@aws-sdk/client-kendra':
optional: true
'@aws-sdk/client-lambda':
optional: true
'@aws-sdk/client-s3':
optional: true
'@aws-sdk/client-sagemaker-runtime':
optional: true
'@aws-sdk/client-sfn':
optional: true
'@aws-sdk/credential-provider-node':
optional: true
'@azure/search-documents':
optional: true
'@azure/storage-blob':
optional: true
'@browserbasehq/sdk':
optional: true
'@clickhouse/client':
optional: true
'@cloudflare/ai':
optional: true
'@datastax/astra-db-ts':
optional: true
'@elastic/elasticsearch':
optional: true
'@getmetal/metal-sdk':
optional: true
'@getzep/zep-js':
optional: true
'@gomomento/sdk':
optional: true
'@gomomento/sdk-core':
optional: true
'@google-ai/generativelanguage':
optional: true
'@google-cloud/storage':
optional: true
'@gradientai/nodejs-sdk':
optional: true
'@huggingface/inference':
optional: true
'@layerup/layerup-security':
optional: true
'@mendable/firecrawl-js':
optional: true
'@mlc-ai/web-llm':
optional: true
'@mozilla/readability':
optional: true
'@neondatabase/serverless':
optional: true
'@notionhq/client':
optional: true
'@opensearch-project/opensearch':
optional: true
'@pinecone-database/pinecone':
optional: true
'@planetscale/database':
optional: true
'@premai/prem-sdk':
optional: true
'@qdrant/js-client-rest':
optional: true
'@raycast/api':
optional: true
'@rockset/client':
optional: true
'@smithy/eventstream-codec':
optional: true
'@smithy/protocol-http':
optional: true
'@smithy/signature-v4':
optional: true
'@smithy/util-utf8':
optional: true
'@spider-cloud/spider-client':
optional: true
'@supabase/postgrest-js':
optional: true
'@supabase/supabase-js':
optional: true
'@tensorflow-models/universal-sentence-encoder':
optional: true
'@tensorflow/tfjs-converter':
optional: true
'@tensorflow/tfjs-core':
optional: true
'@upstash/redis':
optional: true
'@upstash/vector':
optional: true
'@vercel/kv':
optional: true
'@vercel/postgres':
optional: true
'@writerai/writer-sdk':
optional: true
'@xata.io/client':
optional: true
'@xenova/transformers':
optional: true
'@zilliz/milvus2-sdk-node':
optional: true
apify-client:
optional: true
assemblyai:
optional: true
better-sqlite3:
optional: true
cassandra-driver:
optional: true
cborg:
optional: true
cheerio:
optional: true
chromadb:
optional: true
closevector-common:
optional: true
closevector-node:
optional: true
closevector-web:
optional: true
cohere-ai:
optional: true
convex:
optional: true
couchbase:
optional: true
d3-dsv:
optional: true
discord.js:
optional: true
dria:
optional: true
duck-duck-scrape:
optional: true
epub2:
optional: true
faiss-node:
optional: true
firebase-admin:
optional: true
google-auth-library:
optional: true
googleapis:
optional: true
hnswlib-node:
optional: true
html-to-text:
optional: true
ignore:
optional: true
interface-datastore:
optional: true
ioredis:
optional: true
it-all:
optional: true
jsdom:
optional: true
jsonwebtoken:
optional: true
llmonitor:
optional: true
lodash:
optional: true
lunary:
optional: true
mammoth:
optional: true
mongodb:
optional: true
mysql2:
optional: true
neo4j-driver:
optional: true
node-llama-cpp:
optional: true
notion-to-md:
optional: true
officeparser:
optional: true
pdf-parse:
optional: true
pg:
optional: true
pg-copy-streams:
optional: true
pickleparser:
optional: true
playwright:
optional: true
portkey-ai:
optional: true
puppeteer:
optional: true
redis:
optional: true
replicate:
optional: true
sonix-speech-recognition:
optional: true
srt-parser-2:
optional: true
typeorm:
optional: true
typesense:
optional: true
usearch:
optional: true
vectordb:
optional: true
voy-search:
optional: true
weaviate-ts-client:
optional: true
web-auth-library:
optional: true
ws:
optional: true
youtube-transcript:
optional: true
youtubei.js:
optional: true
'@langchain/core@0.2.9':
resolution: {integrity: sha512-pJshopBZqMNF020q0OrrO+vfApWTZUlZecRYMM7TWA5M8/zvEyU/mgA9DlzeRjjDmG6pwF6dIKVjpl6fIGVXlQ==}
engines: {node: '>=18'}
@ -4578,10 +4197,6 @@ packages:
'@otplib/preset-v11@12.0.1':
resolution: {integrity: sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==}
'@pinecone-database/pinecone@2.1.0':
resolution: {integrity: sha512-sbU5+FZ2yhG+tJYwEochoZei5988OLWZyM2aT4wenWc6sbKGV69Jm9Yl4yix10NNglzfksF9avkte1a0/k7x5Q==}
engines: {node: '>=14.0.0'}
'@pinecone-database/pinecone@2.2.1':
resolution: {integrity: sha512-8i6oT8EzYLlxi5Th4tJ8Cae+VPyHzlEsiVSxCOEx+EahbzaiWmpQMZSmO/RlXF/dOjOI+pXvqfcFYcF1awtPlw==}
engines: {node: '>=14.0.0'}
@ -8833,10 +8448,6 @@ packages:
functions-have-names@1.2.3:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
fuse.js@7.0.0:
resolution: {integrity: sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==}
engines: {node: '>=10'}
gauge@4.0.4:
resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
@ -13913,8 +13524,8 @@ packages:
vue-component-type-helpers@2.0.19:
resolution: {integrity: sha512-cN3f1aTxxKo4lzNeQAkVopswuImUrb5Iurll9Gaw5cqpnbTAxtEMM1mgi6ou4X79OCyqYv1U1mzBHJkzmiK82w==}
vue-component-type-helpers@2.0.22:
resolution: {integrity: sha512-gPr2Ba7efUwy/Vfbuf735bHSVdN4ycoZUCHfypkI33M9DUH+ieRblLLVM2eImccFYaWNWwEzURx02EgoXDBmaQ==}
vue-component-type-helpers@2.0.24:
resolution: {integrity: sha512-Jr5N8QVYEcbQuMN1LRgvg61758G8HTnzUlQsAFOxx6Y6X8kmhJ7C+jOvWsQruYxi3uHhhS6BghyRlyiwO99DBg==}
vue-demi@0.14.5:
resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==}
@ -14326,11 +13937,6 @@ packages:
engines: {node: '>=8.0.0'}
hasBin: true
zod-to-json-schema@3.22.4:
resolution: {integrity: sha512-2Ed5dJ+n/O3cU383xSY28cuVi0BCQhF8nYqWU5paEpl7fVdqdAmiLdqLyfblbNdfOFwFfi/mqU4O1pwc60iBhQ==}
peerDependencies:
zod: ^3.22.4
zod-to-json-schema@3.23.0:
resolution: {integrity: sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==}
peerDependencies:
@ -17374,63 +16980,6 @@ snapshots:
- pyodide
- supports-color
'@langchain/community@0.2.2(@aws-sdk/client-bedrock-runtime@3.535.0)(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@getzep/zep-js@0.9.0)(@google-cloud/storage@6.11.0(encoding@0.1.13))(@huggingface/inference@2.7.0)(@mozilla/readability@0.5.0)(@pinecone-database/pinecone@2.1.0)(@qdrant/js-client-rest@1.9.0(typescript@5.5.2))(@smithy/eventstream-codec@2.2.0)(@smithy/protocol-http@3.3.0)(@smithy/signature-v4@2.2.1)(@smithy/util-utf8@2.3.0)(@supabase/postgrest-js@1.15.2)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(cohere-ai@7.10.1(encoding@0.1.13))(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(jsonwebtoken@9.0.2)(lodash@4.17.21)(mammoth@1.7.2)(mysql2@3.10.0)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(pg@8.11.3)(redis@4.6.14)(ws@8.17.1)':
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
'@langchain/openai': 0.0.33(encoding@0.1.13)(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))
binary-extensions: 2.2.0
expr-eval: 2.0.2
flat: 5.0.2
js-yaml: 4.1.0
langchain: 0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1)
langsmith: 0.1.12
uuid: 9.0.1
zod: 3.23.8
zod-to-json-schema: 3.23.0(zod@3.23.8)
optionalDependencies:
'@aws-sdk/client-bedrock-runtime': 3.535.0
'@aws-sdk/client-s3': 3.478.0
'@aws-sdk/credential-provider-node': 3.535.0
'@getzep/zep-js': 0.9.0
'@google-cloud/storage': 6.11.0(encoding@0.1.13)
'@huggingface/inference': 2.7.0
'@mozilla/readability': 0.5.0
'@pinecone-database/pinecone': 2.1.0
'@qdrant/js-client-rest': 1.9.0(typescript@5.5.2)
'@smithy/eventstream-codec': 2.2.0
'@smithy/protocol-http': 3.3.0
'@smithy/signature-v4': 2.2.1
'@smithy/util-utf8': 2.3.0
'@supabase/postgrest-js': 1.15.2
'@supabase/supabase-js': 2.43.4
'@xata.io/client': 0.28.4(typescript@5.5.2)
cheerio: 1.0.0-rc.12
cohere-ai: 7.10.1(encoding@0.1.13)
d3-dsv: 2.0.0
epub2: 3.0.2(ts-toolbelt@9.6.0)
html-to-text: 9.0.5
ignore: 5.2.4
ioredis: 5.3.2
jsdom: 23.0.1
jsonwebtoken: 9.0.2
lodash: 4.17.21
mammoth: 1.7.2
mysql2: 3.10.0
pdf-parse: 1.1.1
pg: 8.11.3
redis: 4.6.14
ws: 8.17.1
transitivePeerDependencies:
- '@gomomento/sdk-web'
- axios
- encoding
- fast-xml-parser
- handlebars
- openai
- peggy
- pyodide
- supports-color
'@langchain/core@0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@google-ai/generativelanguage@2.5.0(encoding@0.1.13))(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))':
dependencies:
ansi-styles: 5.2.0
@ -17449,42 +16998,6 @@ snapshots:
- langchain
- openai
'@langchain/core@0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))':
dependencies:
ansi-styles: 5.2.0
camelcase: 6.3.0
decamelize: 1.2.0
js-tiktoken: 1.0.12
langsmith: 0.1.34(@langchain/core@0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13)))(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
ml-distance: 4.0.1
mustache: 4.2.0
p-queue: 6.6.2
p-retry: 4.6.2
uuid: 9.0.1
zod: 3.23.8
zod-to-json-schema: 3.23.0(zod@3.23.8)
transitivePeerDependencies:
- langchain
- openai
'@langchain/core@0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))':
dependencies:
ansi-styles: 5.2.0
camelcase: 6.3.0
decamelize: 1.2.0
js-tiktoken: 1.0.12
langsmith: 0.1.34(@langchain/core@0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13)))(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
ml-distance: 4.0.1
mustache: 4.2.0
p-queue: 6.6.2
p-retry: 4.6.2
uuid: 9.0.1
zod: 3.23.8
zod-to-json-schema: 3.23.0(zod@3.23.8)
transitivePeerDependencies:
- langchain
- openai
'@langchain/core@0.2.9(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))':
dependencies:
ansi-styles: 5.2.0
@ -17605,18 +17118,6 @@ snapshots:
- langchain
- supports-color
'@langchain/openai@0.0.33(encoding@0.1.13)(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))':
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
js-tiktoken: 1.0.12
openai: 4.47.1(encoding@0.1.13)
zod: 3.23.8
zod-to-json-schema: 3.23.0(zod@3.23.8)
transitivePeerDependencies:
- encoding
- langchain
- supports-color
'@langchain/openai@0.0.33(encoding@0.1.13)(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))':
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
@ -17664,16 +17165,6 @@ snapshots:
- langchain
- openai
'@langchain/pinecone@0.0.6(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))':
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
'@pinecone-database/pinecone': 2.2.1
flat: 5.0.2
uuid: 9.0.1
transitivePeerDependencies:
- langchain
- openai
'@langchain/redis@0.0.5(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@google-ai/generativelanguage@2.5.0(encoding@0.1.13))(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))':
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@google-ai/generativelanguage@2.5.0(encoding@0.1.13))(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
@ -17690,14 +17181,6 @@ snapshots:
- langchain
- openai
'@langchain/textsplitters@0.0.2(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))':
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
js-tiktoken: 1.0.12
transitivePeerDependencies:
- langchain
- openai
'@langchain/textsplitters@0.0.2(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))':
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
@ -18025,13 +17508,6 @@ snapshots:
'@otplib/plugin-crypto': 12.0.1
'@otplib/plugin-thirty-two': 12.0.1
'@pinecone-database/pinecone@2.1.0':
dependencies:
'@sinclair/typebox': 0.29.6
ajv: 8.12.0
cross-fetch: 3.1.8(encoding@0.1.13)
encoding: 0.1.13
'@pinecone-database/pinecone@2.2.1':
dependencies:
'@sinclair/typebox': 0.29.6
@ -19809,7 +19285,7 @@ snapshots:
ts-dedent: 2.2.0
type-fest: 2.19.0
vue: 3.4.21(typescript@5.5.2)
vue-component-type-helpers: 2.0.22
vue-component-type-helpers: 2.0.24
transitivePeerDependencies:
- encoding
- prettier
@ -23715,8 +23191,6 @@ snapshots:
functions-have-names@1.2.3: {}
fuse.js@7.0.0: {}
gauge@4.0.4:
dependencies:
aproba: 2.0.0
@ -25337,49 +24811,6 @@ snapshots:
- openai
- supports-color
langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1):
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
'@langchain/openai': 0.0.33(encoding@0.1.13)(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))
'@langchain/textsplitters': 0.0.2(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
binary-extensions: 2.2.0
js-tiktoken: 1.0.12
js-yaml: 4.1.0
jsonpointer: 5.0.1
langchainhub: 0.0.8
langsmith: 0.1.12
ml-distance: 4.0.1
openapi-types: 12.1.3
p-retry: 4.6.2
uuid: 9.0.1
yaml: 2.3.4
zod: 3.23.8
zod-to-json-schema: 3.23.0(zod@3.23.8)
optionalDependencies:
'@aws-sdk/client-s3': 3.478.0
'@aws-sdk/credential-provider-node': 3.535.0
'@pinecone-database/pinecone': 2.1.0
'@supabase/supabase-js': 2.43.4
'@xata.io/client': 0.28.4(typescript@5.5.2)
axios: 1.6.7(debug@3.2.7)
cheerio: 1.0.0-rc.12
d3-dsv: 2.0.0
epub2: 3.0.2(ts-toolbelt@9.6.0)
fast-xml-parser: 4.3.5
handlebars: 4.7.8
html-to-text: 9.0.5
ignore: 5.2.4
ioredis: 5.3.2
jsdom: 23.0.1
mammoth: 1.7.2
pdf-parse: 1.1.1
redis: 4.6.14
ws: 8.17.1
transitivePeerDependencies:
- encoding
- openai
- supports-color
langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1):
dependencies:
'@langchain/core': 0.2.9(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
@ -25473,32 +24904,6 @@ snapshots:
langchain: 0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@google-ai/generativelanguage@2.5.0(encoding@0.1.13))(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1)
openai: 4.47.1(encoding@0.1.13)
? langsmith@0.1.34(@langchain/core@0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13)))(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
: dependencies:
'@types/uuid': 9.0.7
commander: 10.0.1
lodash.set: 4.3.2
p-queue: 6.6.2
p-retry: 4.6.2
uuid: 9.0.1
optionalDependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
langchain: 0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1)
openai: 4.47.1(encoding@0.1.13)
? langsmith@0.1.34(@langchain/core@0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13)))(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
: dependencies:
'@types/uuid': 9.0.7
commander: 10.0.1
lodash.set: 4.3.2
p-queue: 6.6.2
p-retry: 4.6.2
uuid: 9.0.1
optionalDependencies:
'@langchain/core': 0.2.9(langchain@0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1))(openai@4.52.1(encoding@0.1.13))
langchain: 0.2.2(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.1.0)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2)(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.52.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.14)(ws@8.17.1)
openai: 4.52.1(encoding@0.1.13)
? langsmith@0.1.34(@langchain/core@0.2.9(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13)))(langchain@0.2.3(@aws-sdk/client-s3@3.478.0)(@aws-sdk/credential-provider-node@3.535.0)(@pinecone-database/pinecone@2.2.1)(@supabase/supabase-js@2.43.4)(@xata.io/client@0.28.4(typescript@5.5.2))(axios@1.6.7)(cheerio@1.0.0-rc.12)(d3-dsv@2.0.0)(encoding@0.1.13)(epub2@3.0.2(ts-toolbelt@9.6.0))(fast-xml-parser@4.3.5)(handlebars@4.7.8)(html-to-text@9.0.5)(ignore@5.2.4)(ioredis@5.3.2)(jsdom@23.0.1)(mammoth@1.7.2)(openai@4.47.1(encoding@0.1.13))(pdf-parse@1.1.1)(redis@4.6.12)(ws@8.17.1))(openai@4.47.1(encoding@0.1.13))
: dependencies:
'@types/uuid': 9.0.7
@ -29514,7 +28919,7 @@ snapshots:
vue-component-type-helpers@2.0.19: {}
vue-component-type-helpers@2.0.22: {}
vue-component-type-helpers@2.0.24: {}
vue-demi@0.14.5(vue@3.4.21(typescript@5.5.2)):
dependencies:
@ -29995,10 +29400,6 @@ snapshots:
optionalDependencies:
commander: 9.4.1
zod-to-json-schema@3.22.4(zod@3.22.4):
dependencies:
zod: 3.22.4
zod-to-json-schema@3.23.0(zod@3.23.8):
dependencies:
zod: 3.23.8