feat(ai): add view management tools for AI chat (#16495)
## Summary Adds a new **VIEW** tool category for the AI chat, enabling it to work with views: - **get-views**: List views in the workspace, optionally filtered by object metadata ID - **get-view-query-parameters**: Convert a view's filters and sorts into GraphQL query parameters that can be passed to existing `find_*` data tools - **create-view**, **update-view**, **delete-view**: CRUD operations for view management ### Key design decisions 1. **No pagination duplication**: Instead of creating a `find-records-from-view` tool that would duplicate pagination logic, `get-view-query-parameters` returns filter/sort parameters that the AI can pass to existing record-fetching tools. 2. **Permission model**: - Read tools (get-views, get-view-query-parameters) are available to all users - Write tools require the `VIEW` permission - UNLISTED views can only be modified by their creator 3. **Leverages existing utilities**: Uses `computeRecordGqlOperationFilter` from `twenty-shared` for filter conversion. ### Files changed - Added `ViewToolProvider`, `ViewToolsFactory`, and `ViewQueryParamsService` - Added `VIEW` to `ToolCategory` enum and tool registry - Updated `chat-execution.service.ts` to include view tools in the catalog and pass viewId in browsing context - Extracted shared `formatValidationErrors` utility to reduce duplication ## Test plan - [x] Unit tests for `ViewToolsFactory` - [x] Unit tests for `ViewQueryParamsService` - [x] Lint and typecheck pass
This commit is contained in:
+1
-27
@@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { type ToolSet } from 'ai';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { formatValidationErrors } from 'src/engine/core-modules/tool-provider/utils/format-validation-errors.util';
|
||||
import { fromFlatObjectMetadataToObjectMetadataDto } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-to-object-metadata-dto.util';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
@@ -116,33 +117,6 @@ const DeleteObjectMetadataInputSchema = z.object({
|
||||
}),
|
||||
});
|
||||
|
||||
const formatValidationErrors = (
|
||||
error: WorkspaceMigrationBuilderExceptionV2,
|
||||
): string => {
|
||||
const report = error.failedWorkspaceMigrationBuildResult.report;
|
||||
const errorMessages: string[] = [];
|
||||
|
||||
for (const [entityType, failures] of Object.entries(report)) {
|
||||
if (Array.isArray(failures) && failures.length > 0) {
|
||||
for (const failure of failures) {
|
||||
if (failure.errors && Array.isArray(failure.errors)) {
|
||||
for (const validationError of failure.errors) {
|
||||
const message = validationError.message || validationError.code;
|
||||
|
||||
errorMessages.push(`[${entityType}] ${message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errorMessages.length === 0) {
|
||||
return error.message;
|
||||
}
|
||||
|
||||
return `Validation errors:\n${errorMessages.join('\n')}`;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class ObjectMetadataToolsFactory {
|
||||
constructor(private readonly objectMetadataService: ObjectMetadataService) {}
|
||||
|
||||
Reference in New Issue
Block a user