diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 5640ac7455..78f664ea9f 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -113,13 +113,6 @@ export type AgentChatThread = { updatedAt: Scalars['DateTime']; }; -export type AgentHandoff = { - __typename?: 'AgentHandoff'; - description?: Maybe; - id: Scalars['UUID']; - toAgent: Agent; -}; - export type AgentIdInput = { /** The id of the agent. */ id: Scalars['UUID']; @@ -755,12 +748,6 @@ export type CoreViewSort = { workspaceId: Scalars['UUID']; }; -export type CreateAgentHandoffInput = { - description?: InputMaybe; - fromAgentId: Scalars['UUID']; - toAgentId: Scalars['UUID']; -}; - export type CreateAgentInput = { description?: InputMaybe; icon?: InputMaybe; @@ -1754,7 +1741,6 @@ export type Mutation = { checkPublicDomainValidRecords?: Maybe; checkoutSession: BillingSessionOutput; computeStepOutputSchema: Scalars['JSON']; - createAgentHandoff: Scalars['Boolean']; createApiKey: ApiKey; createApprovedAccessDomain: ApprovedAccessDomain; createChatThread: AgentChatThread; @@ -1853,7 +1839,6 @@ export type Mutation = { initiateOTPProvisioning: InitiateTwoFactorAuthenticationProvisioningOutput; initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioningOutput; publishServerlessFunction: ServerlessFunction; - removeAgentHandoff: Scalars['Boolean']; removeRoleFromAgent: Scalars['Boolean']; renewToken: AuthTokens; resendEmailVerificationToken: ResendEmailVerificationTokenOutput; @@ -1980,11 +1965,6 @@ export type MutationComputeStepOutputSchemaArgs = { }; -export type MutationCreateAgentHandoffArgs = { - input: CreateAgentHandoffInput; -}; - - export type MutationCreateApiKeyArgs = { input: CreateApiKeyInput; }; @@ -2455,11 +2435,6 @@ export type MutationPublishServerlessFunctionArgs = { }; -export type MutationRemoveAgentHandoffArgs = { - input: RemoveAgentHandoffInput; -}; - - export type MutationRemoveRoleFromAgentArgs = { agentId: Scalars['UUID']; }; @@ -3206,8 +3181,6 @@ export type Query = { currentWorkspace: Workspace; field: Field; fields: FieldConnection; - findAgentHandoffTargets: Array; - findAgentHandoffs: Array; findDistantTablesWithStatus: Array; findManyAgents: Array; findManyApplications: Array; @@ -3323,16 +3296,6 @@ export type QueryFieldsArgs = { }; -export type QueryFindAgentHandoffTargetsArgs = { - input: AgentIdInput; -}; - - -export type QueryFindAgentHandoffsArgs = { - input: AgentIdInput; -}; - - export type QueryFindDistantTablesWithStatusArgs = { input: FindManyRemoteTablesInput; }; @@ -3733,11 +3696,6 @@ export enum RemoteTableStatus { SYNCED = 'SYNCED' } -export type RemoveAgentHandoffInput = { - fromAgentId: Scalars['UUID']; - toAgentId: Scalars['UUID']; -}; - export type ResendEmailVerificationTokenOutput = { __typename?: 'ResendEmailVerificationTokenOutput'; success: Scalars['Boolean']; @@ -4462,6 +4420,7 @@ export type UpdateWorkspaceInput = { defaultRoleId?: InputMaybe; displayName?: InputMaybe; editableProfileFields?: InputMaybe>; + fastModel?: InputMaybe; inviteHash?: InputMaybe; isGoogleAuthBypassEnabled?: InputMaybe; isGoogleAuthEnabled?: InputMaybe; @@ -4472,7 +4431,7 @@ export type UpdateWorkspaceInput = { isPublicInviteLinkEnabled?: InputMaybe; isTwoFactorAuthenticationEnforced?: InputMaybe; logo?: InputMaybe; - routerModel?: InputMaybe; + smartModel?: InputMaybe; subdomain?: InputMaybe; trashRetentionDays?: InputMaybe; }; @@ -4809,6 +4768,7 @@ export type Workspace = { deletedAt?: Maybe; displayName?: Maybe; editableProfileFields?: Maybe>; + fastModel: Scalars['String']; featureFlags?: Maybe>; hasValidEnterpriseKey: Scalars['Boolean']; id: Scalars['UUID']; @@ -4825,6 +4785,7 @@ export type Workspace = { logo?: Maybe; metadataVersion: Scalars['Float']; routerModel: Scalars['String']; + smartModel: Scalars['String']; subdomain: Scalars['String']; trashRetentionDays: Scalars['Float']; updatedAt: Scalars['DateTime']; @@ -4950,13 +4911,6 @@ export type AssignRoleToAgentMutationVariables = Exact<{ export type AssignRoleToAgentMutation = { __typename?: 'Mutation', assignRoleToAgent: boolean }; -export type CreateAgentHandoffMutationVariables = Exact<{ - input: CreateAgentHandoffInput; -}>; - - -export type CreateAgentHandoffMutation = { __typename?: 'Mutation', createAgentHandoff: boolean }; - export type CreateChatThreadMutationVariables = Exact<{ [key: string]: never; }>; @@ -4976,13 +4930,6 @@ export type DeleteOneAgentMutationVariables = Exact<{ export type DeleteOneAgentMutation = { __typename?: 'Mutation', deleteOneAgent: { __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, applicationId?: string | null, createdAt: string, updatedAt: string } }; -export type RemoveAgentHandoffMutationVariables = Exact<{ - input: RemoveAgentHandoffInput; -}>; - - -export type RemoveAgentHandoffMutation = { __typename?: 'Mutation', removeAgentHandoff: boolean }; - export type RemoveRoleFromAgentMutationVariables = Exact<{ agentId: Scalars['UUID']; }>; @@ -4997,20 +4944,6 @@ export type UpdateOneAgentMutationVariables = Exact<{ export type UpdateOneAgentMutation = { __typename?: 'Mutation', updateOneAgent: { __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, applicationId?: string | null, createdAt: string, updatedAt: string } }; -export type FindAgentHandoffTargetsQueryVariables = Exact<{ - input: AgentIdInput; -}>; - - -export type FindAgentHandoffTargetsQuery = { __typename?: 'Query', findAgentHandoffTargets: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, modelId: string, prompt: string, isCustom: boolean, createdAt: string, updatedAt: string }> }; - -export type FindAgentHandoffsQueryVariables = Exact<{ - input: AgentIdInput; -}>; - - -export type FindAgentHandoffsQuery = { __typename?: 'Query', findAgentHandoffs: Array<{ __typename?: 'AgentHandoff', id: string, description?: string | null, toAgent: { __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, modelId: string, prompt: string, isCustom: boolean, createdAt: string, updatedAt: string } }> }; - export type FindManyAgentsQueryVariables = Exact<{ [key: string]: never; }>; @@ -5981,7 +5914,7 @@ export type BillingSubscriptionFragmentFragment = { __typename?: 'BillingSubscri export type CurrentBillingSubscriptionFragmentFragment = { __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, interval?: SubscriptionInterval | null, metadata: any, currentPeriodEnd?: string | null, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }>, billingSubscriptionItems?: Array<{ __typename?: 'BillingSubscriptionItemDTO', id: string, hasReachedCurrentPeriodCap: boolean, quantity?: number | null, stripePriceId: string, billingProduct: { __typename?: 'BillingLicensedProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } | { __typename?: 'BillingMeteredProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } }> | null }; -export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, hasPassword: boolean, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars?: any | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, calendarStartDay?: number | null, numberFormat?: WorkspaceMemberNumberFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, deletedWorkspaceMembers?: Array<{ __typename?: 'DeletedWorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', id: string, permissionFlags?: Array | null, objectsPermissions?: Array<{ __typename?: 'ObjectPermission', objectMetadataId: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null, restrictedFields?: any | null }> | null, twoFactorAuthenticationMethodSummary?: Array<{ __typename?: 'TwoFactorAuthenticationMethodDTO', twoFactorAuthenticationMethodId: string, status: string, strategy: string }> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, isGoogleAuthBypassEnabled: boolean, isMicrosoftAuthBypassEnabled: boolean, isPasswordAuthBypassEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, isCustomDomainEnabled: boolean, metadataVersion: number, workspaceMembersCount?: number | null, routerModel: string, isTwoFactorAuthenticationEnforced: boolean, trashRetentionDays: number, editableProfileFields?: Array | null, workspaceCustomApplication?: { __typename?: 'Application', id: string } | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlagDTO', key: FeatureFlagKey, value: boolean }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, interval?: SubscriptionInterval | null, metadata: any, currentPeriodEnd?: string | null, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }>, billingSubscriptionItems?: Array<{ __typename?: 'BillingSubscriptionItemDTO', id: string, hasReachedCurrentPeriodCap: boolean, quantity?: number | null, stripePriceId: string, billingProduct: { __typename?: 'BillingLicensedProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } | { __typename?: 'BillingMeteredProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } }> | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, metadata: any, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }> }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings: boolean, canAccessAllTools: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean, canBeAssignedToUsers: boolean, canBeAssignedToAgents: boolean, canBeAssignedToApiKeys: boolean } | null } | null, availableWorkspaces: { __typename?: 'AvailableWorkspaces', availableWorkspacesForSignIn: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }>, availableWorkspacesForSignUp: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }> } }; +export type UserQueryFragmentFragment = { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, hasPassword: boolean, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars?: any | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, calendarStartDay?: number | null, numberFormat?: WorkspaceMemberNumberFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, deletedWorkspaceMembers?: Array<{ __typename?: 'DeletedWorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', id: string, permissionFlags?: Array | null, objectsPermissions?: Array<{ __typename?: 'ObjectPermission', objectMetadataId: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null, restrictedFields?: any | null }> | null, twoFactorAuthenticationMethodSummary?: Array<{ __typename?: 'TwoFactorAuthenticationMethodDTO', twoFactorAuthenticationMethodId: string, status: string, strategy: string }> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, isGoogleAuthBypassEnabled: boolean, isMicrosoftAuthBypassEnabled: boolean, isPasswordAuthBypassEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, isCustomDomainEnabled: boolean, metadataVersion: number, workspaceMembersCount?: number | null, fastModel: string, smartModel: string, isTwoFactorAuthenticationEnforced: boolean, trashRetentionDays: number, editableProfileFields?: Array | null, workspaceCustomApplication?: { __typename?: 'Application', id: string } | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlagDTO', key: FeatureFlagKey, value: boolean }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, interval?: SubscriptionInterval | null, metadata: any, currentPeriodEnd?: string | null, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }>, billingSubscriptionItems?: Array<{ __typename?: 'BillingSubscriptionItemDTO', id: string, hasReachedCurrentPeriodCap: boolean, quantity?: number | null, stripePriceId: string, billingProduct: { __typename?: 'BillingLicensedProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } | { __typename?: 'BillingMeteredProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } }> | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, metadata: any, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }> }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings: boolean, canAccessAllTools: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean, canBeAssignedToUsers: boolean, canBeAssignedToAgents: boolean, canBeAssignedToApiKeys: boolean } | null } | null, availableWorkspaces: { __typename?: 'AvailableWorkspaces', availableWorkspacesForSignIn: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }>, availableWorkspacesForSignUp: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }> } }; export type WorkspaceUrlsFragmentFragment = { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }; @@ -6007,7 +5940,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>; -export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, hasPassword: boolean, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars?: any | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, calendarStartDay?: number | null, numberFormat?: WorkspaceMemberNumberFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, deletedWorkspaceMembers?: Array<{ __typename?: 'DeletedWorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', id: string, permissionFlags?: Array | null, objectsPermissions?: Array<{ __typename?: 'ObjectPermission', objectMetadataId: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null, restrictedFields?: any | null }> | null, twoFactorAuthenticationMethodSummary?: Array<{ __typename?: 'TwoFactorAuthenticationMethodDTO', twoFactorAuthenticationMethodId: string, status: string, strategy: string }> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, isGoogleAuthBypassEnabled: boolean, isMicrosoftAuthBypassEnabled: boolean, isPasswordAuthBypassEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, isCustomDomainEnabled: boolean, metadataVersion: number, workspaceMembersCount?: number | null, routerModel: string, isTwoFactorAuthenticationEnforced: boolean, trashRetentionDays: number, editableProfileFields?: Array | null, workspaceCustomApplication?: { __typename?: 'Application', id: string } | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlagDTO', key: FeatureFlagKey, value: boolean }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, interval?: SubscriptionInterval | null, metadata: any, currentPeriodEnd?: string | null, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }>, billingSubscriptionItems?: Array<{ __typename?: 'BillingSubscriptionItemDTO', id: string, hasReachedCurrentPeriodCap: boolean, quantity?: number | null, stripePriceId: string, billingProduct: { __typename?: 'BillingLicensedProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } | { __typename?: 'BillingMeteredProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } }> | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, metadata: any, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }> }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings: boolean, canAccessAllTools: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean, canBeAssignedToUsers: boolean, canBeAssignedToAgents: boolean, canBeAssignedToApiKeys: boolean } | null } | null, availableWorkspaces: { __typename?: 'AvailableWorkspaces', availableWorkspacesForSignIn: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }>, availableWorkspacesForSignUp: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }> } } }; +export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, firstName: string, lastName: string, email: string, hasPassword: boolean, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars?: any | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, calendarStartDay?: number | null, numberFormat?: WorkspaceMemberNumberFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, deletedWorkspaceMembers?: Array<{ __typename?: 'DeletedWorkspaceMember', id: string, avatarUrl?: string | null, userEmail: string, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', id: string, permissionFlags?: Array | null, objectsPermissions?: Array<{ __typename?: 'ObjectPermission', objectMetadataId: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null, restrictedFields?: any | null }> | null, twoFactorAuthenticationMethodSummary?: Array<{ __typename?: 'TwoFactorAuthenticationMethodDTO', twoFactorAuthenticationMethodId: string, status: string, strategy: string }> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: string, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, isGoogleAuthBypassEnabled: boolean, isMicrosoftAuthBypassEnabled: boolean, isPasswordAuthBypassEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, isCustomDomainEnabled: boolean, metadataVersion: number, workspaceMembersCount?: number | null, fastModel: string, smartModel: string, isTwoFactorAuthenticationEnforced: boolean, trashRetentionDays: number, editableProfileFields?: Array | null, workspaceCustomApplication?: { __typename?: 'Application', id: string } | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlagDTO', key: FeatureFlagKey, value: boolean }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, interval?: SubscriptionInterval | null, metadata: any, currentPeriodEnd?: string | null, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }>, billingSubscriptionItems?: Array<{ __typename?: 'BillingSubscriptionItemDTO', id: string, hasReachedCurrentPeriodCap: boolean, quantity?: number | null, stripePriceId: string, billingProduct: { __typename?: 'BillingLicensedProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } | { __typename?: 'BillingMeteredProduct', name: string, description: string, images?: Array | null, metadata: { __typename?: 'BillingProductMetadata', productKey: BillingProductKey, planKey: BillingPlanKey, priceUsageBased: BillingUsageType } } }> | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: string, status: SubscriptionStatus, metadata: any, phases: Array<{ __typename?: 'BillingSubscriptionSchedulePhase', start_date: number, end_date: number, items: Array<{ __typename?: 'BillingSubscriptionSchedulePhaseItem', price: string, quantity?: number | null }> }> }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings: boolean, canAccessAllTools: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean, canBeAssignedToUsers: boolean, canBeAssignedToAgents: boolean, canBeAssignedToApiKeys: boolean } | null } | null, availableWorkspaces: { __typename?: 'AvailableWorkspaces', availableWorkspacesForSignIn: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }>, availableWorkspacesForSignUp: Array<{ __typename?: 'AvailableWorkspace', id: string, displayName?: string | null, loginToken?: string | null, inviteHash?: string | null, personalInviteToken?: string | null, logo?: string | null, workspaceUrls: { __typename?: 'WorkspaceUrls', subdomainUrl: string, customUrl?: string | null }, sso: Array<{ __typename?: 'SSOConnection', type: IdentityProviderType, id: string, issuer: string, name: string, status: SsoIdentityProviderStatus }> }> } } }; export type ViewFieldFragmentFragment = { __typename?: 'CoreViewField', id: string, fieldMetadataId: string, viewId: string, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string, deletedAt?: string | null }; @@ -7018,7 +6951,8 @@ export const UserQueryFragmentFragmentDoc = gql` defaultRole { ...RoleFragment } - routerModel + fastModel + smartModel isTwoFactorAuthenticationEnforced trashRetentionDays editableProfileFields @@ -7173,37 +7107,6 @@ export function useAssignRoleToAgentMutation(baseOptions?: Apollo.MutationHookOp export type AssignRoleToAgentMutationHookResult = ReturnType; export type AssignRoleToAgentMutationResult = Apollo.MutationResult; export type AssignRoleToAgentMutationOptions = Apollo.BaseMutationOptions; -export const CreateAgentHandoffDocument = gql` - mutation CreateAgentHandoff($input: CreateAgentHandoffInput!) { - createAgentHandoff(input: $input) -} - `; -export type CreateAgentHandoffMutationFn = Apollo.MutationFunction; - -/** - * __useCreateAgentHandoffMutation__ - * - * To run a mutation, you first call `useCreateAgentHandoffMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateAgentHandoffMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createAgentHandoffMutation, { data, loading, error }] = useCreateAgentHandoffMutation({ - * variables: { - * input: // value for 'input' - * }, - * }); - */ -export function useCreateAgentHandoffMutation(baseOptions?: Apollo.MutationHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(CreateAgentHandoffDocument, options); - } -export type CreateAgentHandoffMutationHookResult = ReturnType; -export type CreateAgentHandoffMutationResult = Apollo.MutationResult; -export type CreateAgentHandoffMutationOptions = Apollo.BaseMutationOptions; export const CreateChatThreadDocument = gql` mutation CreateChatThread { createChatThread { @@ -7305,37 +7208,6 @@ export function useDeleteOneAgentMutation(baseOptions?: Apollo.MutationHookOptio export type DeleteOneAgentMutationHookResult = ReturnType; export type DeleteOneAgentMutationResult = Apollo.MutationResult; export type DeleteOneAgentMutationOptions = Apollo.BaseMutationOptions; -export const RemoveAgentHandoffDocument = gql` - mutation RemoveAgentHandoff($input: RemoveAgentHandoffInput!) { - removeAgentHandoff(input: $input) -} - `; -export type RemoveAgentHandoffMutationFn = Apollo.MutationFunction; - -/** - * __useRemoveAgentHandoffMutation__ - * - * To run a mutation, you first call `useRemoveAgentHandoffMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useRemoveAgentHandoffMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [removeAgentHandoffMutation, { data, loading, error }] = useRemoveAgentHandoffMutation({ - * variables: { - * input: // value for 'input' - * }, - * }); - */ -export function useRemoveAgentHandoffMutation(baseOptions?: Apollo.MutationHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(RemoveAgentHandoffDocument, options); - } -export type RemoveAgentHandoffMutationHookResult = ReturnType; -export type RemoveAgentHandoffMutationResult = Apollo.MutationResult; -export type RemoveAgentHandoffMutationOptions = Apollo.BaseMutationOptions; export const RemoveRoleFromAgentDocument = gql` mutation RemoveRoleFromAgent($agentId: UUID!) { removeRoleFromAgent(agentId: $agentId) @@ -7400,98 +7272,6 @@ export function useUpdateOneAgentMutation(baseOptions?: Apollo.MutationHookOptio export type UpdateOneAgentMutationHookResult = ReturnType; export type UpdateOneAgentMutationResult = Apollo.MutationResult; export type UpdateOneAgentMutationOptions = Apollo.BaseMutationOptions; -export const FindAgentHandoffTargetsDocument = gql` - query FindAgentHandoffTargets($input: AgentIdInput!) { - findAgentHandoffTargets(input: $input) { - id - name - label - description - icon - modelId - prompt - isCustom - createdAt - updatedAt - } -} - `; - -/** - * __useFindAgentHandoffTargetsQuery__ - * - * To run a query within a React component, call `useFindAgentHandoffTargetsQuery` and pass it any options that fit your needs. - * When your component renders, `useFindAgentHandoffTargetsQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useFindAgentHandoffTargetsQuery({ - * variables: { - * input: // value for 'input' - * }, - * }); - */ -export function useFindAgentHandoffTargetsQuery(baseOptions: Apollo.QueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(FindAgentHandoffTargetsDocument, options); - } -export function useFindAgentHandoffTargetsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(FindAgentHandoffTargetsDocument, options); - } -export type FindAgentHandoffTargetsQueryHookResult = ReturnType; -export type FindAgentHandoffTargetsLazyQueryHookResult = ReturnType; -export type FindAgentHandoffTargetsQueryResult = Apollo.QueryResult; -export const FindAgentHandoffsDocument = gql` - query FindAgentHandoffs($input: AgentIdInput!) { - findAgentHandoffs(input: $input) { - id - description - toAgent { - id - name - label - description - icon - modelId - prompt - isCustom - createdAt - updatedAt - } - } -} - `; - -/** - * __useFindAgentHandoffsQuery__ - * - * To run a query within a React component, call `useFindAgentHandoffsQuery` and pass it any options that fit your needs. - * When your component renders, `useFindAgentHandoffsQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useFindAgentHandoffsQuery({ - * variables: { - * input: // value for 'input' - * }, - * }); - */ -export function useFindAgentHandoffsQuery(baseOptions: Apollo.QueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(FindAgentHandoffsDocument, options); - } -export function useFindAgentHandoffsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(FindAgentHandoffsDocument, options); - } -export type FindAgentHandoffsQueryHookResult = ReturnType; -export type FindAgentHandoffsLazyQueryHookResult = ReturnType; -export type FindAgentHandoffsQueryResult = Apollo.QueryResult; export const FindManyAgentsDocument = gql` query FindManyAgents { findManyAgents { diff --git a/packages/twenty-front/src/generated/graphql.ts b/packages/twenty-front/src/generated/graphql.ts index 0467daa696..9a23a636d9 100644 --- a/packages/twenty-front/src/generated/graphql.ts +++ b/packages/twenty-front/src/generated/graphql.ts @@ -113,13 +113,6 @@ export type AgentChatThread = { updatedAt: Scalars['DateTime']; }; -export type AgentHandoff = { - __typename?: 'AgentHandoff'; - description?: Maybe; - id: Scalars['UUID']; - toAgent: Agent; -}; - export type AgentIdInput = { /** The id of the agent. */ id: Scalars['UUID']; @@ -755,12 +748,6 @@ export type CoreViewSort = { workspaceId: Scalars['UUID']; }; -export type CreateAgentHandoffInput = { - description?: InputMaybe; - fromAgentId: Scalars['UUID']; - toAgentId: Scalars['UUID']; -}; - export type CreateAgentInput = { description?: InputMaybe; icon?: InputMaybe; @@ -1730,10 +1717,8 @@ export type Mutation = { checkPublicDomainValidRecords?: Maybe; checkoutSession: BillingSessionOutput; computeStepOutputSchema: Scalars['JSON']; - createAgentHandoff: Scalars['Boolean']; createApiKey: ApiKey; createApprovedAccessDomain: ApprovedAccessDomain; - createChatThread: AgentChatThread; createCoreView: CoreView; createCoreViewField: CoreViewField; createCoreViewFilter: CoreViewFilter; @@ -1827,7 +1812,6 @@ export type Mutation = { initiateOTPProvisioning: InitiateTwoFactorAuthenticationProvisioningOutput; initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioningOutput; publishServerlessFunction: ServerlessFunction; - removeAgentHandoff: Scalars['Boolean']; removeRoleFromAgent: Scalars['Boolean']; renewToken: AuthTokens; resendEmailVerificationToken: ResendEmailVerificationTokenOutput; @@ -1950,11 +1934,6 @@ export type MutationComputeStepOutputSchemaArgs = { }; -export type MutationCreateAgentHandoffArgs = { - input: CreateAgentHandoffInput; -}; - - export type MutationCreateApiKeyArgs = { input: CreateApiKeyInput; }; @@ -2410,11 +2389,6 @@ export type MutationPublishServerlessFunctionArgs = { }; -export type MutationRemoveAgentHandoffArgs = { - input: RemoveAgentHandoffInput; -}; - - export type MutationRemoveRoleFromAgentArgs = { agentId: Scalars['UUID']; }; @@ -3132,17 +3106,12 @@ export type Query = { apiKey?: Maybe; apiKeys: Array; billingPortalSession: BillingSessionOutput; - chatMessages: Array; - chatThread: AgentChatThread; - chatThreads: Array; checkUserExists: CheckUserExistOutput; checkWorkspaceInviteHashIsValid: WorkspaceInviteHashValidOutput; currentUser: User; currentWorkspace: Workspace; field: Field; fields: FieldConnection; - findAgentHandoffTargets: Array; - findAgentHandoffs: Array; findManyAgents: Array; findManyApplications: Array; findManyCronTriggers: Array; @@ -3223,16 +3192,6 @@ export type QueryBillingPortalSessionArgs = { }; -export type QueryChatMessagesArgs = { - threadId: Scalars['UUID']; -}; - - -export type QueryChatThreadArgs = { - id: Scalars['UUID']; -}; - - export type QueryCheckUserExistsArgs = { captchaToken?: InputMaybe; email: Scalars['String']; @@ -3244,16 +3203,6 @@ export type QueryCheckWorkspaceInviteHashIsValidArgs = { }; -export type QueryFindAgentHandoffTargetsArgs = { - input: AgentIdInput; -}; - - -export type QueryFindAgentHandoffsArgs = { - input: AgentIdInput; -}; - - export type QueryFindOneAgentArgs = { input: AgentIdInput; }; @@ -3603,11 +3552,6 @@ export enum RemoteTableStatus { SYNCED = 'SYNCED' } -export type RemoveAgentHandoffInput = { - fromAgentId: Scalars['UUID']; - toAgentId: Scalars['UUID']; -}; - export type ResendEmailVerificationTokenOutput = { __typename?: 'ResendEmailVerificationTokenOutput'; success: Scalars['Boolean']; @@ -4324,6 +4268,7 @@ export type UpdateWorkspaceInput = { defaultRoleId?: InputMaybe; displayName?: InputMaybe; editableProfileFields?: InputMaybe>; + fastModel?: InputMaybe; inviteHash?: InputMaybe; isGoogleAuthBypassEnabled?: InputMaybe; isGoogleAuthEnabled?: InputMaybe; @@ -4334,7 +4279,7 @@ export type UpdateWorkspaceInput = { isPublicInviteLinkEnabled?: InputMaybe; isTwoFactorAuthenticationEnforced?: InputMaybe; logo?: InputMaybe; - routerModel?: InputMaybe; + smartModel?: InputMaybe; subdomain?: InputMaybe; trashRetentionDays?: InputMaybe; }; @@ -4661,6 +4606,7 @@ export type Workspace = { deletedAt?: Maybe; displayName?: Maybe; editableProfileFields?: Maybe>; + fastModel: Scalars['String']; featureFlags?: Maybe>; hasValidEnterpriseKey: Scalars['Boolean']; id: Scalars['UUID']; @@ -4677,6 +4623,7 @@ export type Workspace = { logo?: Maybe; metadataVersion: Scalars['Float']; routerModel: Scalars['String']; + smartModel: Scalars['String']; subdomain: Scalars['String']; trashRetentionDays: Scalars['Float']; updatedAt: Scalars['DateTime']; diff --git a/packages/twenty-front/src/modules/ai/components/RoutingDebugDisplay.tsx b/packages/twenty-front/src/modules/ai/components/RoutingDebugDisplay.tsx index 8437a95c71..ca83883741 100644 --- a/packages/twenty-front/src/modules/ai/components/RoutingDebugDisplay.tsx +++ b/packages/twenty-front/src/modules/ai/components/RoutingDebugDisplay.tsx @@ -246,7 +246,8 @@ const DetailsTab = ({ debug, copyToClipboard }: DetailsTabProps) => { id: debug.selectedAgentId, label: debug.selectedAgentLabel, }, - routerModel: debug.routerModel, + fastModel: debug.fastModel, + smartModel: debug.smartModel, agentModel: debug.agentModel, availableAgents: debug.availableAgents, }; diff --git a/packages/twenty-front/src/modules/ai/components/RoutingStatusDisplay.tsx b/packages/twenty-front/src/modules/ai/components/RoutingStatusDisplay.tsx index 6e4a0110df..9661a3d98e 100644 --- a/packages/twenty-front/src/modules/ai/components/RoutingStatusDisplay.tsx +++ b/packages/twenty-front/src/modules/ai/components/RoutingStatusDisplay.tsx @@ -1,47 +1,57 @@ import { RoutingDebugDisplay } from '@/ai/components/RoutingDebugDisplay'; import { ShimmeringText } from '@/ai/components/ShimmeringText'; +import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; +import { useState } from 'react'; import { type DataMessagePart } from 'twenty-shared/ai'; -import { IconCpu, IconSparkles } from 'twenty-ui/display'; +import { IconChevronDown, IconChevronUp, IconCpu } from 'twenty-ui/display'; +import { AnimatedExpandableContainer } from 'twenty-ui/layout'; -const StyledRoutingContainer = styled.div` - align-items: center; - background: ${({ theme }) => theme.background.transparent.lighter}; - border: ${({ theme }) => `1px dashed ${theme.border.color.medium}`}; - border-radius: ${({ theme }) => theme.border.radius.md}; +const StyledContainer = styled.div` display: flex; - font-size: ${({ theme }) => theme.font.size.sm}; + flex-direction: column; gap: ${({ theme }) => theme.spacing(2)}; - margin-bottom: ${({ theme }) => theme.spacing(2)}; - padding: ${({ theme }) => theme.spacing(2, 3)}; - width: fit-content; `; -const StyledIconContainer = styled.div<{ isLoading: boolean }>` +const StyledToggleButton = styled.div<{ isExpandable: boolean }>` align-items: center; - animation: ${({ isLoading }) => - isLoading ? 'pulseAnimation 2s ease-in-out infinite' : 'none'}; - color: ${({ theme }) => theme.color.blue}; + background: none; + border: none; + cursor: ${({ isExpandable }) => (isExpandable ? 'pointer' : 'auto')}; display: flex; + color: ${({ theme }) => theme.font.color.tertiary}; + gap: ${({ theme }) => theme.spacing(1)}; + padding: ${({ theme }) => theme.spacing(1)} 0; + transition: color ${({ theme }) => theme.animation.duration.normal}s; - @keyframes pulseAnimation { - 0%, - 100% { - opacity: 1; - } - 50% { - opacity: 0.5; - } + &:hover { + color: ${({ isExpandable, theme }) => + isExpandable ? theme.font.color.secondary : theme.font.color.tertiary}; } `; -const StyledText = styled.div` +const StyledDisplayMessage = styled.span` color: ${({ theme }) => theme.font.color.tertiary}; + font-size: ${({ theme }) => theme.font.size.md}; + font-weight: ${({ theme }) => theme.font.weight.medium}; `; -const StyledWrapper = styled.div` +const StyledIconTextContainer = styled.div` display: flex; - flex-direction: column; + align-items: center; + gap: ${({ theme }) => theme.spacing(1)}; + + svg { + min-width: ${({ theme }) => theme.icon.size.sm}px; + } +`; + +const StyledContentContainer = styled.div` + background: ${({ theme }) => theme.background.transparent.lighter}; + border: 1px solid ${({ theme }) => theme.border.color.light}; + border-radius: ${({ theme }) => theme.border.radius.sm}; + min-width: 0; + padding: ${({ theme }) => theme.spacing(3)}; `; export const RoutingStatusDisplay = ({ @@ -49,28 +59,54 @@ export const RoutingStatusDisplay = ({ }: { data: DataMessagePart['routing-status']; }) => { + const theme = useTheme(); + const [isExpanded, setIsExpanded] = useState(false); const isLoading = data.state === 'loading'; const isDebugMode = process.env.IS_DEBUG_MODE === 'true'; + const isExpandable = isDebugMode && data.state === 'routed' && data.debug; if (data.state === 'error') { return null; } + if (isLoading) { + return ( + + + + + {data.text} + + + + ); + } + return ( - - - - {isLoading ? : } - - {isLoading ? ( - {data.text} - ) : ( - {data.text} - )} - - {isDebugMode && data.state === 'routed' && data.debug && ( - + + isExpandable && setIsExpanded(!isExpanded)} + isExpandable={!!isExpandable} + > + + + {data.text} + + {isExpandable && + (isExpanded ? ( + + ) : ( + + ))} + + + {isExpandable && ( + + + + + )} - + ); }; diff --git a/packages/twenty-front/src/modules/ai/constants/DefaultFastModel.ts b/packages/twenty-front/src/modules/ai/constants/DefaultFastModel.ts new file mode 100644 index 0000000000..84e98b8308 --- /dev/null +++ b/packages/twenty-front/src/modules/ai/constants/DefaultFastModel.ts @@ -0,0 +1 @@ +export const DEFAULT_FAST_MODEL = 'default-fast-model' as const; diff --git a/packages/twenty-front/src/modules/ai/constants/DefaultSmartModel.ts b/packages/twenty-front/src/modules/ai/constants/DefaultSmartModel.ts new file mode 100644 index 0000000000..f85d6f9719 --- /dev/null +++ b/packages/twenty-front/src/modules/ai/constants/DefaultSmartModel.ts @@ -0,0 +1 @@ +export const DEFAULT_SMART_MODEL = 'default-smart-model' as const; diff --git a/packages/twenty-front/src/modules/ai/graphql/mutations/createAgentHandoff.ts b/packages/twenty-front/src/modules/ai/graphql/mutations/createAgentHandoff.ts deleted file mode 100644 index 31bbbdbde9..0000000000 --- a/packages/twenty-front/src/modules/ai/graphql/mutations/createAgentHandoff.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { gql } from '@apollo/client'; - -export const CREATE_AGENT_HANDOFF = gql` - mutation CreateAgentHandoff($input: CreateAgentHandoffInput!) { - createAgentHandoff(input: $input) - } -`; diff --git a/packages/twenty-front/src/modules/ai/graphql/mutations/removeAgentHandoff.ts b/packages/twenty-front/src/modules/ai/graphql/mutations/removeAgentHandoff.ts deleted file mode 100644 index a317b61940..0000000000 --- a/packages/twenty-front/src/modules/ai/graphql/mutations/removeAgentHandoff.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { gql } from '@apollo/client'; - -export const REMOVE_AGENT_HANDOFF = gql` - mutation RemoveAgentHandoff($input: RemoveAgentHandoffInput!) { - removeAgentHandoff(input: $input) - } -`; diff --git a/packages/twenty-front/src/modules/ai/graphql/queries/findAgentHandoffTargets.ts b/packages/twenty-front/src/modules/ai/graphql/queries/findAgentHandoffTargets.ts deleted file mode 100644 index 1fe34da9a3..0000000000 --- a/packages/twenty-front/src/modules/ai/graphql/queries/findAgentHandoffTargets.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { gql } from '@apollo/client'; - -export const FIND_AGENT_HANDOFF_TARGETS = gql` - query FindAgentHandoffTargets($input: AgentIdInput!) { - findAgentHandoffTargets(input: $input) { - id - name - label - description - icon - modelId - prompt - isCustom - createdAt - updatedAt - } - } -`; diff --git a/packages/twenty-front/src/modules/ai/graphql/queries/findAgentHandoffs.ts b/packages/twenty-front/src/modules/ai/graphql/queries/findAgentHandoffs.ts deleted file mode 100644 index 45565d670d..0000000000 --- a/packages/twenty-front/src/modules/ai/graphql/queries/findAgentHandoffs.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { gql } from '@apollo/client'; - -export const FIND_AGENT_HANDOFFS = gql` - query FindAgentHandoffs($input: AgentIdInput!) { - findAgentHandoffs(input: $input) { - id - description - toAgent { - id - name - label - description - icon - modelId - prompt - isCustom - createdAt - updatedAt - } - } - } -`; diff --git a/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts b/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts index 744cb4ae4b..46ca78ed45 100644 --- a/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts +++ b/packages/twenty-front/src/modules/ai/hooks/useAiModelOptions.ts @@ -2,13 +2,20 @@ import { aiModelsState } from '@/client-config/states/aiModelsState'; import { useRecoilValue } from 'recoil'; import { type SelectOption } from 'twenty-ui/input'; +import { DEFAULT_FAST_MODEL } from '@/ai/constants/DefaultFastModel'; +import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel'; + export const useAiModelOptions = (): SelectOption[] => { const aiModels = useRecoilValue(aiModelsState); return aiModels .map((model) => ({ value: model.modelId, - label: `${model.label} (${model.provider})`, + label: + model.modelId === DEFAULT_FAST_MODEL || + model.modelId === DEFAULT_SMART_MODEL + ? model.label + : `${model.label} (${model.provider})`, })) .sort((a, b) => a.label.localeCompare(b.label)); }; diff --git a/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts b/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts index 16d24d2903..ad49b6f402 100644 --- a/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts +++ b/packages/twenty-front/src/modules/apollo/services/__tests__/apollo.factory.test.ts @@ -1,6 +1,8 @@ import { ApolloError, gql, InMemoryCache } from '@apollo/client'; import fetchMock, { enableFetchMocks } from 'jest-fetch-mock'; +import { DEFAULT_FAST_MODEL } from '@/ai/constants/DefaultFastModel'; +import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel'; import { CUSTOM_WORKSPACE_APPLICATION_MOCK } from '@/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant'; import { WorkspaceActivationStatus } from '~/generated/graphql'; import { ApolloFactory, type Options } from '../apollo.factory'; @@ -62,6 +64,8 @@ const mockWorkspace = { }, isTwoFactorAuthenticationEnforced: false, trashRetentionDays: 14, + fastModel: DEFAULT_FAST_MODEL, + smartModel: DEFAULT_SMART_MODEL, routerModel: 'auto', workspaceCustomApplication: CUSTOM_WORKSPACE_APPLICATION_MOCK, workspaceCustomApplicationId: CUSTOM_WORKSPACE_APPLICATION_MOCK.id, diff --git a/packages/twenty-front/src/modules/auth/states/currentWorkspaceState.ts b/packages/twenty-front/src/modules/auth/states/currentWorkspaceState.ts index 92e9f34910..38c584c982 100644 --- a/packages/twenty-front/src/modules/auth/states/currentWorkspaceState.ts +++ b/packages/twenty-front/src/modules/auth/states/currentWorkspaceState.ts @@ -32,7 +32,8 @@ export type CurrentWorkspace = Pick< | 'metadataVersion' | 'isTwoFactorAuthenticationEnforced' | 'trashRetentionDays' - | 'routerModel' + | 'fastModel' + | 'smartModel' | 'editableProfileFields' > & { defaultRole?: Omit | null; diff --git a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useColumnDefinitionsFromObjectMetadata.test.ts b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useColumnDefinitionsFromObjectMetadata.test.ts index 6a4b87b173..3aed48ae4b 100644 --- a/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useColumnDefinitionsFromObjectMetadata.test.ts +++ b/packages/twenty-front/src/modules/object-metadata/hooks/__tests__/useColumnDefinitionsFromObjectMetadata.test.ts @@ -4,6 +4,8 @@ import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { CUSTOM_WORKSPACE_APPLICATION_MOCK } from '@/object-metadata/hooks/__tests__/constants/CustomWorkspaceApplicationMock.test.constant'; import { useColumnDefinitionsFromObjectMetadata } from '@/object-metadata/hooks/useColumnDefinitionsFromObjectMetadata'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; +import { DEFAULT_FAST_MODEL } from '@/ai/constants/DefaultFastModel'; +import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel'; import { SubscriptionInterval, SubscriptionStatus, @@ -58,7 +60,8 @@ const Wrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper({ ], isTwoFactorAuthenticationEnforced: false, trashRetentionDays: 14, - routerModel: 'auto', + fastModel: DEFAULT_FAST_MODEL, + smartModel: DEFAULT_SMART_MODEL, }); }, }); diff --git a/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts b/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts index 5ef403ab6b..a0ba771ef4 100644 --- a/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts +++ b/packages/twenty-front/src/modules/users/graphql/fragments/userQueryFragment.ts @@ -82,7 +82,8 @@ export const USER_QUERY_FRAGMENT = gql` defaultRole { ...RoleFragment } - routerModel + fastModel + smartModel isTwoFactorAuthenticationEnforced trashRetentionDays editableProfileFields diff --git a/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx b/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx index 321af7e091..be4ae71547 100644 --- a/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx +++ b/packages/twenty-front/src/pages/settings/ai/components/SettingsAIRouterSettings.tsx @@ -2,6 +2,8 @@ import styled from '@emotion/styled'; import { useRecoilState } from 'recoil'; import { useAiModelOptions } from '@/ai/hooks/useAiModelOptions'; +import { DEFAULT_FAST_MODEL } from '@/ai/constants/DefaultFastModel'; +import { DEFAULT_SMART_MODEL } from '@/ai/constants/DefaultSmartModel'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; import { StyledSettingsOptionCardContent, @@ -13,7 +15,7 @@ import { SettingsOptionIconCustomizer } from '@/settings/components/SettingsOpti import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { Select } from '@/ui/input/components/Select'; import { t } from '@lingui/core/macro'; -import { H2Title, IconCpu } from 'twenty-ui/display'; +import { H2Title, IconBolt, IconBrain } from 'twenty-ui/display'; import { Card, Section } from 'twenty-ui/layout'; import { useUpdateWorkspaceMutation } from '~/generated-metadata/graphql'; @@ -39,39 +41,76 @@ export const SettingsAIRouterSettings = () => { const modelOptions = useAiModelOptions(); const noModelsAvailable = modelOptions.length === 0; - const handleModelChange = async (value: string) => { + const handleFastModelChange = async (value: string) => { if (!currentWorkspace?.id) { return; } const newValue = value; - const previousValue = currentWorkspace?.routerModel || 'auto'; + const previousValue = currentWorkspace?.fastModel || DEFAULT_FAST_MODEL; try { setCurrentWorkspace({ ...currentWorkspace, - routerModel: newValue, + fastModel: newValue, }); await updateWorkspace({ variables: { input: { - routerModel: newValue, + fastModel: newValue, }, }, }); enqueueSuccessSnackBar({ - message: t`Router model updated successfully`, + message: t`Fast model updated successfully`, }); } catch { setCurrentWorkspace({ ...currentWorkspace, - routerModel: previousValue, + fastModel: previousValue, }); enqueueErrorSnackBar({ - message: t`Failed to update router model`, + message: t`Failed to update fast model`, + }); + } + }; + + const handleSmartModelChange = async (value: string) => { + if (!currentWorkspace?.id) { + return; + } + + const newValue = value; + const previousValue = currentWorkspace?.smartModel || DEFAULT_SMART_MODEL; + + try { + setCurrentWorkspace({ + ...currentWorkspace, + smartModel: newValue, + }); + + await updateWorkspace({ + variables: { + input: { + smartModel: newValue, + }, + }, + }); + + enqueueSuccessSnackBar({ + message: t`Smart model updated successfully`, + }); + } catch { + setCurrentWorkspace({ + ...currentWorkspace, + smartModel: previousValue, + }); + + enqueueErrorSnackBar({ + message: t`Failed to update smart model`, }); } }; @@ -79,40 +118,67 @@ export const SettingsAIRouterSettings = () => { return (
- - - - - -
- - {t`Router Model`} - - - {t`Fast model to route to the right agent`} - -
- - {noModelsAvailable ? ( - - {t`No models available. Please configure AI models in your workspace settings.`} - - ) : ( + {noModelsAvailable ? ( + + + + {t`No models available. Please configure AI models in your workspace settings.`} + + + + ) : ( + + + + + +
+ + {t`Fast Model`} + + + {t`Quick model for routing decisions`} + +
+ + +
+
+ )}
); }; diff --git a/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentHandoffForm.tsx b/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentHandoffForm.tsx deleted file mode 100644 index ddfad292b0..0000000000 --- a/packages/twenty-front/src/pages/settings/ai/components/SettingsAgentHandoffForm.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import styled from '@emotion/styled'; -import { useLingui } from '@lingui/react/macro'; -import { useState } from 'react'; - -import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; -import { Select } from '@/ui/input/components/Select'; -import { TextArea } from '@/ui/input/components/TextArea'; -import { IconPlus } from 'twenty-ui/display'; -import { Button, type SelectOption } from 'twenty-ui/input'; -import { useCreateAgentHandoffMutation } from '~/generated-metadata/graphql'; - -const StyledAddHandoffForm = styled.div` - background: ${({ theme }) => theme.background.secondary}; - border: 1px solid ${({ theme }) => theme.border.color.medium}; - border-radius: ${({ theme }) => theme.border.radius.md}; - display: flex; - flex-direction: column; - gap: ${({ theme }) => theme.spacing(3)}; - padding: ${({ theme }) => theme.spacing(3)}; - margin-top: ${({ theme }) => theme.spacing(3)}; -`; - -const StyledFormActions = styled.div` - display: flex; - gap: ${({ theme }) => theme.spacing(2)}; - justify-content: flex-end; -`; - -const StyledAddButtonContainer = styled.div` - display: flex; - justify-content: flex-end; - margin-top: ${({ theme }) => theme.spacing(3)}; -`; - -type SettingsAgentHandoffFormProps = { - agentId: string; - availableAgentOptions: SelectOption[]; - agentsLoading: boolean; - onHandoffAdded: () => void; -}; - -export const SettingsAgentHandoffForm = ({ - agentId, - availableAgentOptions, - agentsLoading, - onHandoffAdded, -}: SettingsAgentHandoffFormProps) => { - const { t } = useLingui(); - const { enqueueSuccessSnackBar, enqueueErrorSnackBar } = useSnackBar(); - - const [isAddingHandoff, setIsAddingHandoff] = useState(false); - const [selectedTargetAgentId, setSelectedTargetAgentId] = useState(''); - const [handoffDescription, setHandoffDescription] = useState(''); - - const [createAgentHandoff] = useCreateAgentHandoffMutation(); - - const noAvailableAgents = availableAgentOptions.length === 0; - - const resetHandoffForm = () => { - setIsAddingHandoff(false); - setSelectedTargetAgentId(''); - setHandoffDescription(''); - }; - - const handleAddHandoff = async () => { - try { - await createAgentHandoff({ - variables: { - input: { - fromAgentId: agentId, - toAgentId: selectedTargetAgentId, - description: handoffDescription, - }, - }, - }); - - onHandoffAdded(); - resetHandoffForm(); - enqueueSuccessSnackBar({ - message: t`Handoff created successfully`, - }); - } catch { - enqueueErrorSnackBar({ - message: t`Failed to create handoff`, - }); - } - }; - - return ( - <> - {isAddingHandoff ? ( - -