refactor(twenty-server): consolidate AI tool provider architecture (#16355)
## Summary Consolidates the AI tool provider architecture by creating a single `ToolProviderService` as the entry point for all tool generation. This removes multiple intermediate services and simplifies the codebase. ## Changes ### New Architecture - **`ToolProviderService`**: Single service for all tool generation with: - `getTools(spec)` - Get tools by category with permissions - `getToolByType(type)` - Get specific tool for workflow execution - **`ToolCategory` enum**: Declarative specification of tool types: - `DATABASE_CRUD` - Record CRUD operations - `ACTION` - HTTP requests, email sending, article search - `WORKFLOW` - Workflow management tools - `METADATA` - Object/field metadata tools - `NATIVE_MODEL` - Model-specific tools (e.g., web search) - **`ToolSpecification` type**: Clean API for requesting tools with permissions ### Removed - `AiToolsModule` - No longer needed - `ToolService` - Logic inlined into ToolProviderService - `ToolAdapterService` - Logic inlined into ToolProviderService - `ToolRegistryService` - Logic inlined into ToolProviderService ### Updated - All consumers (agents, chat, MCP, workflows) now use `ToolProviderService` - Test files updated accordingly ## Stats - **547 insertions, 1146 deletions** (net ~600 lines removed) - 4 services deleted - 1 module deleted ## Testing - [x] Typecheck passes - [x] Lint passes
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
export enum ToolType {
|
||||
HTTP_REQUEST = 'HTTP_REQUEST',
|
||||
SEND_EMAIL = 'SEND_EMAIL',
|
||||
SEARCH_ARTICLES = 'SEARCH_ARTICLES',
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { ToolType } from 'src/engine/core-modules/tool/enums/tool-type.enum';
|
||||
import { HttpTool } from 'src/engine/core-modules/tool/tools/http-tool/http-tool';
|
||||
import { SendEmailTool } from 'src/engine/core-modules/tool/tools/send-email-tool/send-email-tool';
|
||||
import { type SendEmailInput } from 'src/engine/core-modules/tool/tools/send-email-tool/types/send-email-input.type';
|
||||
import { type Tool } from 'src/engine/core-modules/tool/types/tool.type';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants';
|
||||
|
||||
@Injectable()
|
||||
export class ToolRegistryService {
|
||||
private readonly toolFactories: Map<ToolType, () => Tool>;
|
||||
|
||||
constructor(
|
||||
private readonly sendEmailTool: SendEmailTool,
|
||||
private readonly twentyConfigService: TwentyConfigService,
|
||||
) {
|
||||
this.toolFactories = new Map<ToolType, () => Tool>([
|
||||
[
|
||||
ToolType.HTTP_REQUEST,
|
||||
() => {
|
||||
const httpTool = new HttpTool(twentyConfigService);
|
||||
|
||||
return {
|
||||
description: httpTool.description,
|
||||
inputSchema: httpTool.inputSchema,
|
||||
execute: (params) => httpTool.execute(params),
|
||||
flag: PermissionFlagType.HTTP_REQUEST_TOOL,
|
||||
};
|
||||
},
|
||||
],
|
||||
[
|
||||
ToolType.SEND_EMAIL,
|
||||
() => ({
|
||||
description: this.sendEmailTool.description,
|
||||
inputSchema: this.sendEmailTool.inputSchema,
|
||||
execute: (params) =>
|
||||
this.sendEmailTool.execute(params as SendEmailInput),
|
||||
flag: PermissionFlagType.SEND_EMAIL_TOOL,
|
||||
}),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
getTool(toolType: ToolType): Tool {
|
||||
const factory = this.toolFactories.get(toolType);
|
||||
|
||||
if (!factory) {
|
||||
throw new Error(`Unknown tool type: ${toolType}`);
|
||||
}
|
||||
|
||||
return factory();
|
||||
}
|
||||
|
||||
getAllToolTypes(): ToolType[] {
|
||||
return Array.from(this.toolFactories.keys());
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity';
|
||||
import { FileModule } from 'src/engine/core-modules/file/file.module';
|
||||
import { ToolRegistryService } from 'src/engine/core-modules/tool/services/tool-registry.service';
|
||||
import { HttpTool } from 'src/engine/core-modules/tool/tools/http-tool/http-tool';
|
||||
import { SearchArticlesTool } from 'src/engine/core-modules/tool/tools/search-articles-tool/search-articles-tool';
|
||||
import { SendEmailTool } from 'src/engine/core-modules/tool/tools/send-email-tool/send-email-tool';
|
||||
@@ -15,7 +14,7 @@ import { MessagingImportManagerModule } from 'src/modules/messaging/message-impo
|
||||
TypeOrmModule.forFeature([FileEntity]),
|
||||
FileModule,
|
||||
],
|
||||
providers: [HttpTool, SendEmailTool, SearchArticlesTool, ToolRegistryService],
|
||||
exports: [ToolRegistryService],
|
||||
providers: [HttpTool, SendEmailTool, SearchArticlesTool],
|
||||
exports: [HttpTool, SendEmailTool, SearchArticlesTool],
|
||||
})
|
||||
export class ToolModule {}
|
||||
|
||||
Reference in New Issue
Block a user