From 06d8c8c76aed912642e59fa39fdf6aeadbf4d724 Mon Sep 17 00:00:00 2001 From: Abdul Rahman <81605929+abdulrahmancodes@users.noreply.github.com> Date: Sat, 8 Nov 2025 19:02:06 +0530 Subject: [PATCH] Fix find tool filters by mapping many-to-one relations to fieldId (#15716) **Root Cause** Many-to-one relation filters were being exposed under the relation name (e.g., `company`) instead of the corresponding foreign-key attribute (e.g., `companyId`). **Change** - Detect many-to-one relation metadata and remap those filter keys to `Id`. - Removed some unused code unrelated to this fix. --- .../ai/utils/hasStructuredStreamData.ts | 14 -------------- .../ai/controllers/ai.controller.ts | 2 +- .../zod-schemas/find-tool.zod-schema.ts | 18 +++++++++++++++--- ...dard-agent-definition-to-flat-agent.util.ts | 7 ++----- .../agents/data-manipulator-agent.ts | 1 - .../agents/data-navigator-agent.ts | 1 - .../standard-agents/agents/helper-agent.ts | 1 - .../agents/workflow-builder-agent.ts | 1 - .../standard-agent-definition.interface.ts | 2 -- 9 files changed, 18 insertions(+), 29 deletions(-) delete mode 100644 packages/twenty-front/src/modules/ai/utils/hasStructuredStreamData.ts diff --git a/packages/twenty-front/src/modules/ai/utils/hasStructuredStreamData.ts b/packages/twenty-front/src/modules/ai/utils/hasStructuredStreamData.ts deleted file mode 100644 index ccd61fe688..0000000000 --- a/packages/twenty-front/src/modules/ai/utils/hasStructuredStreamData.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const hasStructuredStreamData = (data: string): boolean => { - if (!data.includes('\n')) { - return false; - } - - return data.split('\n').some((line) => { - try { - JSON.parse(line); - return true; - } catch { - return false; - } - }); -}; diff --git a/packages/twenty-server/src/engine/core-modules/ai/controllers/ai.controller.ts b/packages/twenty-server/src/engine/core-modules/ai/controllers/ai.controller.ts index 787e6a491f..4c7aa32ae2 100644 --- a/packages/twenty-server/src/engine/core-modules/ai/controllers/ai.controller.ts +++ b/packages/twenty-server/src/engine/core-modules/ai/controllers/ai.controller.ts @@ -20,7 +20,7 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -export interface ChatRequest { +interface ChatRequest { messages: ModelMessage[]; temperature?: number; maxOutputTokens?: number; diff --git a/packages/twenty-server/src/engine/core-modules/record-crud/zod-schemas/find-tool.zod-schema.ts b/packages/twenty-server/src/engine/core-modules/record-crud/zod-schemas/find-tool.zod-schema.ts index e2e1eee163..66bfacdf34 100644 --- a/packages/twenty-server/src/engine/core-modules/record-crud/zod-schemas/find-tool.zod-schema.ts +++ b/packages/twenty-server/src/engine/core-modules/record-crud/zod-schemas/find-tool.zod-schema.ts @@ -1,10 +1,15 @@ -import { type RestrictedFieldsPermissions } from 'twenty-shared/types'; +import { + FieldMetadataType, + RelationType, + type RestrictedFieldsPermissions, +} from 'twenty-shared/types'; import { z } from 'zod'; import { generateFieldFilterZodSchema } from 'src/engine/core-modules/record-crud/zod-schemas/field-filters.zod-schema'; import { ObjectRecordOrderBySchema } from 'src/engine/core-modules/record-crud/zod-schemas/order-by.zod-schema'; import { shouldExcludeFieldFromAgentToolSchema } from 'src/engine/metadata-modules/field-metadata/utils/should-exclude-field-from-agent-tool-schema.util'; import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util'; export const generateFindToolInputSchema = ( objectMetadata: ObjectMetadataEntity, @@ -23,9 +28,16 @@ export const generateFindToolInputSchema = ( const filterSchema = generateFieldFilterZodSchema(field); - if (filterSchema) { - filterShape[field.name] = filterSchema; + if (!filterSchema) { + return; } + + const isManyToOneRelationField = + isFieldMetadataEntityOfType(field, FieldMetadataType.RELATION) && + field.settings?.relationType === RelationType.MANY_TO_ONE; + + filterShape[isManyToOneRelationField ? `${field.name}Id` : field.name] = + filterSchema; }); return z.object({ diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-agent/utils/transform-standard-agent-definition-to-flat-agent.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-agent/utils/transform-standard-agent-definition-to-flat-agent.util.ts index ffb41ac504..693f0fedf9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-agent/utils/transform-standard-agent-definition-to-flat-agent.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-agent/utils/transform-standard-agent-definition-to-flat-agent.util.ts @@ -7,11 +7,8 @@ export const transformStandardAgentDefinitionToFlatAgent = ( standardAgentDefinition: StandardAgentDefinition, workspaceId: string, ): FlatAgent => { - const { - createHandoffFromDefaultAgent: _createHandoffFromDefaultAgent, - standardRoleId: _standardRoleId, - ...agentData - } = standardAgentDefinition; + const { standardRoleId: _standardRoleId, ...agentData } = + standardAgentDefinition; return { ...agentData, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-manipulator-agent.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-manipulator-agent.ts index baccaf2bce..dc0912fdd1 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-manipulator-agent.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-manipulator-agent.ts @@ -9,7 +9,6 @@ export const DATA_MANIPULATOR_AGENT: StandardAgentDefinition = { 'AI agent specialized in creating, updating, and managing data across all objects', icon: 'IconEdit', applicationId: null, - createHandoffFromDefaultAgent: true, prompt: `You are a Data Manipulator Agent specialized in helping users create, update, and manage data in Twenty. Your capabilities include: diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-navigator-agent.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-navigator-agent.ts index 02814c342e..62f0869a7b 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-navigator-agent.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/data-navigator-agent.ts @@ -9,7 +9,6 @@ export const DATA_NAVIGATOR_AGENT: StandardAgentDefinition = { 'AI agent specialized in exploring and reading data across all objects', icon: 'IconSearch', applicationId: null, - createHandoffFromDefaultAgent: true, prompt: `You are a Data Navigator Agent specialized in helping users explore and understand their data in Twenty. Your capabilities include: diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/helper-agent.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/helper-agent.ts index d1a992e39f..28952350b6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/helper-agent.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/helper-agent.ts @@ -8,7 +8,6 @@ export const HELPER_AGENT: StandardAgentDefinition = { 'AI agent specialized in helping users learn how to use Twenty CRM', icon: 'IconHelp', applicationId: null, - createHandoffFromDefaultAgent: true, prompt: `You are a Helper Agent specialized in assisting users with questions about how to use Twenty CRM. Your capabilities include: diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/workflow-builder-agent.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/workflow-builder-agent.ts index a16f4ad499..6844dd9dfa 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/workflow-builder-agent.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/workflow-builder-agent.ts @@ -8,7 +8,6 @@ export const WORKFLOW_BUILDER_AGENT: StandardAgentDefinition = { description: 'AI agent specialized in creating and managing workflows', icon: 'IconSettingsAutomation', applicationId: null, - createHandoffFromDefaultAgent: true, prompt: `You are a Workflow Builder Agent specialized in helping users create, modify, and manage workflows in Twenty. Your capabilities include: diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/types/standard-agent-definition.interface.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/types/standard-agent-definition.interface.ts index 9d20f7149b..e524e647fb 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/types/standard-agent-definition.interface.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/standard-agents/types/standard-agent-definition.interface.ts @@ -6,6 +6,4 @@ export type StandardAgentDefinition = Omit< > & { standardId: string; standardRoleId?: string; - // If true, creates a handoff from the default agent to this agent - createHandoffFromDefaultAgent?: boolean; };