Skip to content

Commit

Permalink
feat(editor): Remove AI Error Debugging (#9337)
Browse files Browse the repository at this point in the history
  • Loading branch information
MiloradFilipovic authored May 8, 2024
1 parent f64a41d commit cda062b
Show file tree
Hide file tree
Showing 14 changed files with 5 additions and 356 deletions.
31 changes: 1 addition & 30 deletions packages/cli/src/controllers/ai.controller.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,11 @@
import { Post, RestController } from '@/decorators';
import { AIRequest } from '@/requests';
import { AIService } from '@/services/ai.service';
import { NodeTypes } from '@/NodeTypes';
import { FailedDependencyError } from '@/errors/response-errors/failed-dependency.error';

@RestController('/ai')
export class AIController {
constructor(
private readonly aiService: AIService,
private readonly nodeTypes: NodeTypes,
) {}

/**
* Suggest a solution for a given error using the AI provider.
*/
@Post('/debug-error')
async debugError(req: AIRequest.DebugError): Promise<{ message: string }> {
const { error } = req.body;

let nodeType;
if (error.node?.type) {
nodeType = this.nodeTypes.getByNameAndVersion(error.node.type, error.node.typeVersion);
}

try {
const message = await this.aiService.debugError(error, nodeType);
return {
message,
};
} catch (aiServiceError) {
throw new FailedDependencyError(
(aiServiceError as Error).message ||
'Failed to debug error due to an issue with an external dependency. Please try again later.',
);
}
}
constructor(private readonly aiService: AIService) {}

/**
* Generate CURL request and additional HTTP Node metadata for given service and request
Expand Down
6 changes: 0 additions & 6 deletions packages/cli/src/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type {
INodeParameters,
INodeTypeNameVersion,
IUser,
NodeError,
} from 'n8n-workflow';

import { IsBoolean, IsEmail, IsIn, IsOptional, IsString, Length } from 'class-validator';
Expand Down Expand Up @@ -149,14 +148,9 @@ export function hasSharing(
// ----------------------------------

export declare namespace AIRequest {
export type DebugError = AuthenticatedRequest<{}, {}, AIDebugErrorPayload>;
export type GenerateCurl = AuthenticatedRequest<{}, {}, AIGenerateCurlPayload>;
}

export interface AIDebugErrorPayload {
error: NodeError;
}

export interface AIGenerateCurlPayload {
service: string;
request: string;
Expand Down
22 changes: 1 addition & 21 deletions packages/cli/src/services/ai.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { Service } from 'typedi';
import config from '@/config';
import type { INodeType, N8nAIProviderType, NodeError } from 'n8n-workflow';
import type { N8nAIProviderType } from 'n8n-workflow';
import { ApplicationError, jsonParse } from 'n8n-workflow';
import { debugErrorPromptTemplate } from '@/services/ai/prompts/debugError';
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 { summarizeNodeTypeProperties } from '@/services/ai/utils/summarizeNodeTypeProperties';
import { Pinecone } from '@pinecone-database/pinecone';
import type { z } from 'zod';
import apiKnowledgebase from '@/services/ai/resources/api-knowledgebase.json';
Expand All @@ -18,8 +16,6 @@ import {
import { generateCurlSchema } from '@/services/ai/schemas/generateCurl';
import { PineconeStore } from '@langchain/pinecone';
import Fuse from 'fuse.js';
import { N8N_DOCS_URL } from '@/constants';

interface APIKnowledgebaseService {
id: string;
title: string;
Expand Down Expand Up @@ -72,22 +68,6 @@ export class AIService {
return await this.provider.invoke(messages, options);
}

async debugError(error: NodeError, nodeType?: INodeType) {
this.checkRequirements();

const chain = debugErrorPromptTemplate.pipe(this.provider.model);
const result = await chain.invoke({
nodeType: nodeType?.description.displayName ?? 'n8n Node',
error: JSON.stringify(error),
properties: JSON.stringify(
summarizeNodeTypeProperties(nodeType?.description.properties ?? []),
),
documentationUrl: nodeType?.description.documentationUrl ?? N8N_DOCS_URL,
});

return this.provider.mapResponse(result);
}

validateCurl(result: { curl: string }) {
if (!result.curl.startsWith('curl')) {
throw new ApplicationError(
Expand Down
40 changes: 0 additions & 40 deletions packages/cli/src/services/ai/prompts/debugError.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/cli/src/services/frontend.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ export class FrontendService {
enabled: config.getEnv('ai.enabled'),
provider: config.getEnv('ai.provider'),
features: {
errorDebugging: !!config.getEnv('ai.openAI.apiKey'),
generateCurl: !!config.getEnv('ai.openAI.apiKey'),
},
},
Expand Down
42 changes: 0 additions & 42 deletions packages/cli/test/unit/controllers/ai.controller.test.ts

This file was deleted.

37 changes: 1 addition & 36 deletions packages/cli/test/unit/services/ai.service.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type { INode, INodeType } from 'n8n-workflow';
import { ApplicationError, jsonParse, NodeOperationError } from 'n8n-workflow';
import { ApplicationError, jsonParse } from 'n8n-workflow';
import { AIService } from '@/services/ai.service';
import config from '@/config';
import { debugErrorPromptTemplate } from '@/services/ai/prompts/debugError';
import {
generateCurlCommandFallbackPromptTemplate,
generateCurlCommandPromptTemplate,
Expand Down Expand Up @@ -96,39 +94,6 @@ describe('AIService', () => {
});
});

describe('debugError', () => {
test('should call prompt with error and nodeType', async () => {
const service = new AIService();

const nodeType = {
description: {
displayName: 'Node Type',
name: 'nodeType',
properties: [],
},
} as unknown as INodeType;
const error = new NodeOperationError(
{
type: 'n8n-nodes-base.error',
typeVersion: 1,
} as INode,
'Error',
);

await service.debugError(error, nodeType);

const messages = await debugErrorPromptTemplate.formatMessages({
nodeType: nodeType.description.displayName,
error: JSON.stringify(error),
properties: JSON.stringify(nodeType.description.properties),
documentationUrl: 'https://docs.n8n.io',
});

expect(service.provider.model.invoke).toHaveBeenCalled();
expect(service.provider.model.invoke.mock.calls[0][0].messages).toEqual(messages);
});
});

describe('generateCurl', () => {
test('should call generateCurl fallback if pinecone key is not defined', async () => {
jest.mocked(config).getEnv.mockImplementation((key: string) => {
Expand Down
1 change: 0 additions & 1 deletion packages/editor-ui/src/__tests__/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ export const defaultSettings: IN8nUISettings = {
ai: {
enabled: false,
provider: '',
errorDebugging: false,
},
workflowHistory: {
pruneTime: 0,
Expand Down
20 changes: 0 additions & 20 deletions packages/editor-ui/src/api/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ import type { IRestApiContext, Schema } from '@/Interface';
import { makeRestApiRequest } from '@/utils/apiUtils';
import type { IDataObject } from 'n8n-workflow';

export interface DebugErrorPayload {
error: Error;
}

export interface DebugErrorResponse {
message: string;
}

export interface GenerateCurlPayload {
service: string;
request: string;
Expand Down Expand Up @@ -47,18 +39,6 @@ export async function generateCodeForPrompt(
} as IDataObject);
}

export const debugError = async (
context: IRestApiContext,
payload: DebugErrorPayload,
): Promise<DebugErrorResponse> => {
return await makeRestApiRequest(
context,
'POST',
'/ai/debug-error',
payload as unknown as IDataObject,
);
};

export const generateCurl = async (
context: IRestApiContext,
payload: GenerateCurlPayload,
Expand Down
Loading

0 comments on commit cda062b

Please sign in to comment.