AI tools to create a demo workspace (#18236)
This PR adds the necessary tool to create a demo workspace with : relevant custom objects and fields, mock data and a real dashboard with graph widgets. It is still a bit under-optimized and slow but it works. This PR also adds an AI tool that allows to see what happens in real time, it navigates the app and waits when necessary. --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
+1
@@ -5,6 +5,7 @@ export enum ToolCategory {
|
||||
METADATA = 'METADATA',
|
||||
NATIVE_MODEL = 'NATIVE_MODEL',
|
||||
VIEW = 'VIEW',
|
||||
VIEW_FIELD = 'VIEW_FIELD',
|
||||
DASHBOARD = 'DASHBOARD',
|
||||
LOGIC_FUNCTION = 'LOGIC_FUNCTION',
|
||||
}
|
||||
|
||||
+13
-2
@@ -19,10 +19,11 @@ import {
|
||||
type ToolIndexEntry,
|
||||
} from 'src/engine/core-modules/tool-provider/types/tool-descriptor.type';
|
||||
import { CodeInterpreterTool } from 'src/engine/core-modules/tool/tools/code-interpreter-tool/code-interpreter-tool';
|
||||
import { HttpTool } from 'src/engine/core-modules/tool/tools/http-tool/http-tool';
|
||||
import { SearchHelpCenterTool } from 'src/engine/core-modules/tool/tools/search-help-center-tool/search-help-center-tool';
|
||||
import { DraftEmailTool } from 'src/engine/core-modules/tool/tools/email-tool/draft-email-tool';
|
||||
import { SendEmailTool } from 'src/engine/core-modules/tool/tools/email-tool/send-email-tool';
|
||||
import { HttpTool } from 'src/engine/core-modules/tool/tools/http-tool/http-tool';
|
||||
import { NavigateAppTool } from 'src/engine/core-modules/tool/tools/navigate-tool/navigate-app-tool';
|
||||
import { SearchHelpCenterTool } from 'src/engine/core-modules/tool/tools/search-help-center-tool/search-help-center-tool';
|
||||
import { type ToolInput } from 'src/engine/core-modules/tool/types/tool-input.type';
|
||||
import { type Tool } from 'src/engine/core-modules/tool/types/tool.type';
|
||||
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
|
||||
@@ -39,6 +40,7 @@ export class ActionToolProvider implements ToolProvider {
|
||||
private readonly draftEmailTool: DraftEmailTool,
|
||||
private readonly searchHelpCenterTool: SearchHelpCenterTool,
|
||||
private readonly codeInterpreterTool: CodeInterpreterTool,
|
||||
private readonly navigateAppTool: NavigateAppTool,
|
||||
private readonly permissionsService: PermissionsService,
|
||||
private readonly toolExecutorService: ToolExecutorService,
|
||||
) {
|
||||
@@ -48,6 +50,7 @@ export class ActionToolProvider implements ToolProvider {
|
||||
['draft_email', this.draftEmailTool],
|
||||
['search_help_center', this.searchHelpCenterTool],
|
||||
['code_interpreter', this.codeInterpreterTool],
|
||||
['navigate_app', this.navigateAppTool],
|
||||
]);
|
||||
|
||||
// Register each action tool as a static handler in the executor
|
||||
@@ -116,6 +119,14 @@ export class ActionToolProvider implements ToolProvider {
|
||||
),
|
||||
);
|
||||
|
||||
descriptors.push(
|
||||
this.buildDescriptor(
|
||||
'navigate_app',
|
||||
this.navigateAppTool,
|
||||
includeSchemas,
|
||||
),
|
||||
);
|
||||
|
||||
const hasCodeInterpreterPermission =
|
||||
await this.permissionsService.hasToolPermission(
|
||||
context.rolePermissionConfig,
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
||||
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
|
||||
import {
|
||||
type GenerateDescriptorOptions,
|
||||
type ToolProvider,
|
||||
type ToolProviderContext,
|
||||
} from 'src/engine/core-modules/tool-provider/interfaces/tool-provider.interface';
|
||||
|
||||
import { ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
|
||||
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
|
||||
import {
|
||||
type ToolDescriptor,
|
||||
type ToolIndexEntry,
|
||||
} from 'src/engine/core-modules/tool-provider/types/tool-descriptor.type';
|
||||
import { toolSetToDescriptors } from 'src/engine/core-modules/tool-provider/utils/tool-set-to-descriptors.util';
|
||||
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
|
||||
import { ViewFieldToolsFactory } from 'src/engine/metadata-modules/view-field/tools/view-field-tools.factory';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFieldToolProvider implements ToolProvider, OnModuleInit {
|
||||
readonly category = ToolCategory.VIEW_FIELD;
|
||||
|
||||
constructor(
|
||||
private readonly viewFieldToolsFactory: ViewFieldToolsFactory,
|
||||
private readonly permissionsService: PermissionsService,
|
||||
private readonly toolExecutorService: ToolExecutorService,
|
||||
) {}
|
||||
|
||||
onModuleInit(): void {
|
||||
const factory = this.viewFieldToolsFactory;
|
||||
|
||||
this.toolExecutorService.registerCategoryGenerator(
|
||||
ToolCategory.VIEW_FIELD,
|
||||
async (context) => {
|
||||
const readTools = factory.generateReadTools(context.workspaceId);
|
||||
|
||||
const hasViewPermission =
|
||||
await this.permissionsService.checkRolesPermissions(
|
||||
context.rolePermissionConfig,
|
||||
context.workspaceId,
|
||||
PermissionFlagType.VIEWS,
|
||||
);
|
||||
|
||||
if (hasViewPermission) {
|
||||
const writeTools = factory.generateWriteTools(context.workspaceId);
|
||||
|
||||
return { ...readTools, ...writeTools };
|
||||
}
|
||||
|
||||
return readTools;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async isAvailable(_context: ToolProviderContext): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
async generateDescriptors(
|
||||
context: ToolProviderContext,
|
||||
options?: GenerateDescriptorOptions,
|
||||
): Promise<(ToolIndexEntry | ToolDescriptor)[]> {
|
||||
const schemaOptions = {
|
||||
includeSchemas: options?.includeSchemas ?? true,
|
||||
};
|
||||
|
||||
const readTools = this.viewFieldToolsFactory.generateReadTools(
|
||||
context.workspaceId,
|
||||
);
|
||||
|
||||
const hasViewPermission =
|
||||
await this.permissionsService.checkRolesPermissions(
|
||||
context.rolePermissionConfig,
|
||||
context.workspaceId,
|
||||
PermissionFlagType.VIEWS,
|
||||
);
|
||||
|
||||
if (hasViewPermission) {
|
||||
const writeTools = this.viewFieldToolsFactory.generateWriteTools(
|
||||
context.workspaceId,
|
||||
);
|
||||
|
||||
return toolSetToDescriptors(
|
||||
{ ...readTools, ...writeTools },
|
||||
ToolCategory.VIEW_FIELD,
|
||||
schemaOptions,
|
||||
);
|
||||
}
|
||||
|
||||
return toolSetToDescriptors(
|
||||
readTools,
|
||||
ToolCategory.VIEW_FIELD,
|
||||
schemaOptions,
|
||||
);
|
||||
}
|
||||
}
|
||||
+9
-2
@@ -7,9 +7,10 @@ import { TOOL_PROVIDERS } from 'src/engine/core-modules/tool-provider/constants/
|
||||
import { ActionToolProvider } from 'src/engine/core-modules/tool-provider/providers/action-tool.provider';
|
||||
import { DashboardToolProvider } from 'src/engine/core-modules/tool-provider/providers/dashboard-tool.provider';
|
||||
import { DatabaseToolProvider } from 'src/engine/core-modules/tool-provider/providers/database-tool.provider';
|
||||
import { LogicFunctionToolProvider } from 'src/engine/core-modules/tool-provider/providers/logic-function-tool.provider';
|
||||
import { MetadataToolProvider } from 'src/engine/core-modules/tool-provider/providers/metadata-tool.provider';
|
||||
import { NativeModelToolProvider } from 'src/engine/core-modules/tool-provider/providers/native-model-tool.provider';
|
||||
import { LogicFunctionToolProvider } from 'src/engine/core-modules/tool-provider/providers/logic-function-tool.provider';
|
||||
import { ViewFieldToolProvider } from 'src/engine/core-modules/tool-provider/providers/view-field-tool.provider';
|
||||
import { ViewToolProvider } from 'src/engine/core-modules/tool-provider/providers/view-tool.provider';
|
||||
import { WorkflowToolProvider } from 'src/engine/core-modules/tool-provider/providers/workflow-tool.provider';
|
||||
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
|
||||
@@ -19,10 +20,11 @@ import { AiAgentExecutionModule } from 'src/engine/metadata-modules/ai/ai-agent-
|
||||
import { AiModelsModule } from 'src/engine/metadata-modules/ai/ai-models/ai-models.module';
|
||||
import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { LogicFunctionModule } from 'src/engine/metadata-modules/logic-function/logic-function.module';
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { LogicFunctionModule } from 'src/engine/metadata-modules/logic-function/logic-function.module';
|
||||
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
|
||||
import { ViewFieldModule } from 'src/engine/metadata-modules/view-field/view-field.module';
|
||||
import { ViewModule } from 'src/engine/metadata-modules/view/view.module';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
|
||||
@@ -45,6 +47,7 @@ import { ToolRegistryService } from './services/tool-registry.service';
|
||||
FieldMetadataModule,
|
||||
PermissionsModule,
|
||||
ViewModule,
|
||||
ViewFieldModule,
|
||||
WorkspaceCacheModule,
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
LogicFunctionModule,
|
||||
@@ -60,6 +63,7 @@ import { ToolRegistryService } from './services/tool-registry.service';
|
||||
MetadataToolProvider,
|
||||
NativeModelToolProvider,
|
||||
LogicFunctionToolProvider,
|
||||
ViewFieldToolProvider,
|
||||
ViewToolProvider,
|
||||
WorkflowToolProvider,
|
||||
{
|
||||
@@ -72,6 +76,7 @@ import { ToolRegistryService } from './services/tool-registry.service';
|
||||
databaseProvider: DatabaseToolProvider,
|
||||
metadataProvider: MetadataToolProvider,
|
||||
logicFunctionProvider: LogicFunctionToolProvider,
|
||||
viewFieldProvider: ViewFieldToolProvider,
|
||||
viewProvider: ViewToolProvider,
|
||||
workflowProvider: WorkflowToolProvider,
|
||||
) => [
|
||||
@@ -80,6 +85,7 @@ import { ToolRegistryService } from './services/tool-registry.service';
|
||||
databaseProvider,
|
||||
metadataProvider,
|
||||
logicFunctionProvider,
|
||||
viewFieldProvider,
|
||||
viewProvider,
|
||||
workflowProvider,
|
||||
],
|
||||
@@ -89,6 +95,7 @@ import { ToolRegistryService } from './services/tool-registry.service';
|
||||
DatabaseToolProvider,
|
||||
MetadataToolProvider,
|
||||
LogicFunctionToolProvider,
|
||||
ViewFieldToolProvider,
|
||||
ViewToolProvider,
|
||||
WorkflowToolProvider,
|
||||
],
|
||||
|
||||
+6
-1
@@ -1,16 +1,21 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
|
||||
import { type ToolRegistryService } from 'src/engine/core-modules/tool-provider/services/tool-registry.service';
|
||||
import { type ToolIndexEntry } from 'src/engine/core-modules/tool-provider/types/tool-descriptor.type';
|
||||
|
||||
export const GET_TOOL_CATALOG_TOOL_NAME = 'get_tool_catalog';
|
||||
|
||||
const availableCategories = Object.values(ToolCategory)
|
||||
.map((entry) => entry.toString())
|
||||
.join(', ');
|
||||
|
||||
export const getToolCatalogInputSchema = z.object({
|
||||
categories: z
|
||||
.array(z.string())
|
||||
.optional()
|
||||
.describe(
|
||||
'Filter by category (e.g. DATABASE_CRUD, METADATA, VIEW, WORKFLOW, DASHBOARD, LOGIC_FUNCTION, ACTION). Omit to get all.',
|
||||
`Filter by category. Available categories: ${availableCategories}. Omit to get all.`,
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user