[AI] Improve tools tab (#19221)

This commit is contained in:
nitin
2026-04-02 19:06:33 +05:30
committed by GitHub
parent cd23a2bc80
commit 3c067f072c
46 changed files with 1134 additions and 486 deletions
@@ -1,11 +0,0 @@
export enum ToolCategory {
DATABASE_CRUD = 'DATABASE_CRUD',
ACTION = 'ACTION',
WORKFLOW = 'WORKFLOW',
METADATA = 'METADATA',
NATIVE_MODEL = 'NATIVE_MODEL',
VIEW = 'VIEW',
VIEW_FIELD = 'VIEW_FIELD',
DASHBOARD = 'DASHBOARD',
LOGIC_FUNCTION = 'LOGIC_FUNCTION',
}
@@ -1,9 +1,8 @@
import { type ToolSet } from 'ai';
import { type CodeExecutionData } from 'twenty-shared/ai';
import { type CodeExecutionData, type ToolCategory } from 'twenty-shared/ai';
import { type ActorMetadata } from 'twenty-shared/types';
import { type WorkspaceAuthContext } from 'src/engine/core-modules/auth/types/workspace-auth-context.type';
import { type ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import {
type ToolDescriptor,
type ToolIndexEntry,
@@ -9,7 +9,7 @@ import {
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 { ToolCategory } from 'twenty-shared/ai';
import {
type StaticToolHandler,
ToolExecutorService,
@@ -159,6 +159,7 @@ export class ActionToolProvider implements ToolProvider {
name: toolId,
description: tool.description,
category: ToolCategory.ACTION,
icon: 'IconPlayerPlay',
...(includeSchemas && {
inputSchema: z.toJSONSchema(tool.inputSchema as z.ZodType),
}),
@@ -9,7 +9,8 @@ import {
} from 'src/engine/core-modules/tool-provider/interfaces/tool-provider.interface';
import { DASHBOARD_TOOL_SERVICE_TOKEN } from 'src/engine/core-modules/tool-provider/constants/dashboard-tool-service.token';
import { ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { ToolCategory } from 'twenty-shared/ai';
import { CoreObjectNameSingular } from 'twenty-shared/types';
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
import {
type ToolDescriptor,
@@ -17,6 +18,7 @@ import {
} 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 { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import type { DashboardToolWorkspaceService } from 'src/modules/dashboard/tools/services/dashboard-tool.workspace-service';
@Injectable()
@@ -29,6 +31,7 @@ export class DashboardToolProvider implements ToolProvider, OnModuleInit {
private readonly dashboardToolService: DashboardToolWorkspaceService | null,
private readonly permissionsService: PermissionsService,
private readonly toolExecutorService: ToolExecutorService,
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
) {}
onModuleInit(): void {
@@ -71,8 +74,33 @@ export class DashboardToolProvider implements ToolProvider, OnModuleInit {
context.rolePermissionConfig,
);
const icon = await this.resolveObjectIcon(
context.workspaceId,
CoreObjectNameSingular.Dashboard,
);
return toolSetToDescriptors(toolSet, ToolCategory.DASHBOARD, {
includeSchemas: options?.includeSchemas ?? true,
icon,
});
}
private async resolveObjectIcon(
workspaceId: string,
nameSingular: string,
): Promise<string | undefined> {
const { flatObjectMetadataMaps } =
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
{
workspaceId,
flatMapsKeys: ['flatObjectMetadataMaps'],
},
);
const flatObject = Object.values(
flatObjectMetadataMaps.byUniversalIdentifier,
).find((obj) => obj?.nameSingular === nameSingular);
return flatObject?.icon ?? undefined;
}
}
@@ -21,7 +21,7 @@ import { generateUpdateRecordInputSchema } from 'src/engine/core-modules/record-
import { DeleteToolInputSchema } from 'src/engine/core-modules/record-crud/zod-schemas/delete-tool.zod-schema';
import { FindOneToolInputSchema } from 'src/engine/core-modules/record-crud/zod-schemas/find-one-tool.zod-schema';
import { generateFindToolInputSchema } from 'src/engine/core-modules/record-crud/zod-schemas/find-tool.zod-schema';
import { ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { ToolCategory } from 'twenty-shared/ai';
import {
type ToolDescriptor,
type ToolIndexEntry,
@@ -122,6 +122,7 @@ export class DatabaseToolProvider implements ToolProvider {
operation: 'find',
},
objectName: objectMetadata.nameSingular,
icon: flatObject.icon ?? undefined,
operation: 'find',
});
@@ -138,6 +139,7 @@ export class DatabaseToolProvider implements ToolProvider {
operation: 'find_one',
},
objectName: objectMetadata.nameSingular,
icon: flatObject.icon ?? undefined,
operation: 'find_one',
});
}
@@ -158,6 +160,7 @@ export class DatabaseToolProvider implements ToolProvider {
operation: 'create',
},
objectName: objectMetadata.nameSingular,
icon: flatObject.icon ?? undefined,
operation: 'create',
});
@@ -179,6 +182,7 @@ export class DatabaseToolProvider implements ToolProvider {
operation: 'create_many',
},
objectName: objectMetadata.nameSingular,
icon: flatObject.icon ?? undefined,
operation: 'create_many',
});
@@ -197,6 +201,7 @@ export class DatabaseToolProvider implements ToolProvider {
operation: 'update',
},
objectName: objectMetadata.nameSingular,
icon: flatObject.icon ?? undefined,
operation: 'update',
});
@@ -218,6 +223,7 @@ export class DatabaseToolProvider implements ToolProvider {
operation: 'update_many',
},
objectName: objectMetadata.nameSingular,
icon: flatObject.icon ?? undefined,
operation: 'update_many',
});
}
@@ -236,6 +242,7 @@ export class DatabaseToolProvider implements ToolProvider {
operation: 'delete',
},
objectName: objectMetadata.nameSingular,
icon: flatObject.icon ?? undefined,
operation: 'delete',
});
}
@@ -9,7 +9,7 @@ import {
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 { ToolCategory } from 'twenty-shared/ai';
import {
type ToolDescriptor,
type ToolIndexEntry,
@@ -8,7 +8,7 @@ import {
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 { ToolCategory } from 'twenty-shared/ai';
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
import {
type ToolDescriptor,
@@ -62,6 +62,7 @@ export class MetadataToolProvider implements ToolProvider, OnModuleInit {
return toolSetToDescriptors(toolSet, ToolCategory.METADATA, {
includeSchemas: options?.includeSchemas ?? true,
icon: 'IconSettings',
});
}
}
@@ -8,7 +8,7 @@ import {
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 { ToolCategory } from 'twenty-shared/ai';
import { AgentModelConfigService } from 'src/engine/metadata-modules/ai/ai-models/services/agent-model-config.service';
import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service';
@@ -8,7 +8,7 @@ import {
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 { ToolCategory } from 'twenty-shared/ai';
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
import {
type ToolDescriptor,
@@ -64,6 +64,7 @@ export class ViewFieldToolProvider implements ToolProvider, OnModuleInit {
): Promise<(ToolIndexEntry | ToolDescriptor)[]> {
const schemaOptions = {
includeSchemas: options?.includeSchemas ?? true,
icon: 'IconTable',
};
const readTools = this.viewFieldToolsFactory.generateReadTools(
@@ -8,7 +8,7 @@ import {
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 { ToolCategory } from 'twenty-shared/ai';
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
import {
type ToolDescriptor,
@@ -74,6 +74,7 @@ export class ViewToolProvider implements ToolProvider, OnModuleInit {
const workspaceMemberId = context.actorContext?.workspaceMemberId;
const schemaOptions = {
includeSchemas: options?.includeSchemas ?? true,
icon: 'IconTable',
};
const readTools = this.viewToolsFactory.generateReadTools(
@@ -9,7 +9,8 @@ import {
} from 'src/engine/core-modules/tool-provider/interfaces/tool-provider.interface';
import { WORKFLOW_TOOL_SERVICE_TOKEN } from 'src/engine/core-modules/tool-provider/constants/workflow-tool-service.token';
import { ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { ToolCategory } from 'twenty-shared/ai';
import { CoreObjectNameSingular } from 'twenty-shared/types';
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
import {
type ToolDescriptor,
@@ -17,6 +18,7 @@ import {
} 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 { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import type { WorkflowToolWorkspaceService } from 'src/modules/workflow/workflow-tools/services/workflow-tool.workspace-service';
@Injectable()
@@ -29,6 +31,7 @@ export class WorkflowToolProvider implements ToolProvider, OnModuleInit {
private readonly workflowToolService: WorkflowToolWorkspaceService | null,
private readonly permissionsService: PermissionsService,
private readonly toolExecutorService: ToolExecutorService,
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
) {}
onModuleInit(): void {
@@ -71,8 +74,33 @@ export class WorkflowToolProvider implements ToolProvider, OnModuleInit {
context.rolePermissionConfig,
);
const icon = await this.resolveObjectIcon(
context.workspaceId,
CoreObjectNameSingular.Workflow,
);
return toolSetToDescriptors(toolSet, ToolCategory.WORKFLOW, {
includeSchemas: options?.includeSchemas ?? true,
icon,
});
}
private async resolveObjectIcon(
workspaceId: string,
nameSingular: string,
): Promise<string | undefined> {
const { flatObjectMetadataMaps } =
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
{
workspaceId,
flatMapsKeys: ['flatObjectMetadataMaps'],
},
);
const flatObject = Object.values(
flatObjectMetadataMaps.byUniversalIdentifier,
).find((obj) => obj?.nameSingular === nameSingular);
return flatObject?.icon ?? undefined;
}
}
@@ -28,6 +28,9 @@ export class ToolIndexEntryDTO {
@Field({ nullable: true })
objectName?: string;
@Field({ nullable: true })
icon?: string;
@Field(() => graphqlTypeJson, { nullable: true })
inputSchema?: object;
}
@@ -22,7 +22,7 @@ import { DeleteRecordService } from 'src/engine/core-modules/record-crud/service
import { FindRecordsService } from 'src/engine/core-modules/record-crud/services/find-records.service';
import { UpdateManyRecordsService } from 'src/engine/core-modules/record-crud/services/update-many-records.service';
import { UpdateRecordService } from 'src/engine/core-modules/record-crud/services/update-record.service';
import { type ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { type ToolCategory } from 'twenty-shared/ai';
import {
type ToolDescriptor,
type ToolIndexEntry,
@@ -10,7 +10,7 @@ import {
} from 'src/engine/core-modules/tool-provider/interfaces/tool-provider.interface';
import { TOOL_PROVIDERS } from 'src/engine/core-modules/tool-provider/constants/tool-providers.token';
import { ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { ToolCategory } from 'twenty-shared/ai';
import { compactToolOutput } from 'src/engine/core-modules/tool-provider/output-serialization/compact-tool-output.util';
import { NativeModelToolProvider } from 'src/engine/core-modules/tool-provider/providers/native-model-tool.provider';
import { ToolExecutorService } from 'src/engine/core-modules/tool-provider/services/tool-executor.service';
@@ -1,6 +1,6 @@
import { z } from 'zod';
import { ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { ToolCategory } from 'twenty-shared/ai';
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';
@@ -1,4 +1,4 @@
import { type ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { type ToolCategory } from 'twenty-shared/ai';
export type DatabaseCrudOperation =
| 'find'
@@ -26,6 +26,7 @@ export type ToolIndexEntry = {
executionRef: ToolExecutionRef;
objectName?: string;
operation?: string;
icon?: string;
};
// Full descriptor with schema (on-demand)
@@ -1,7 +1,7 @@
import { type ToolSet } from 'ai';
import { z } from 'zod';
import { type ToolCategory } from 'src/engine/core-modules/tool-provider/enums/tool-category.enum';
import { type ToolCategory } from 'twenty-shared/ai';
import {
type ToolDescriptor,
type ToolIndexEntry,
@@ -9,6 +9,7 @@ import {
export type ToolSetToDescriptorsOptions = {
includeSchemas?: boolean;
icon?: string;
};
// Converts a ToolSet (with Zod schemas and closures) into an array of
@@ -27,6 +28,7 @@ export const toolSetToDescriptors = (
description: tool.description ?? '',
category,
executionRef: { kind: 'static' as const, toolId: name },
...(options?.icon && { icon: options.icon }),
};
if (!includeSchemas) {