From 364c944ca6fe66d8c15fcce9d2d7225e55c61502 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 6 Mar 2026 11:02:26 +0100 Subject: [PATCH] Improve build performance 2x (#18449) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Front Before: image Front After: image Server Before: image Server After: image ### CI Server Pipeline Restructuring - Split monolithic `server-setup` job into three parallel jobs: `server-build`, `server-lint-typecheck`, and `server-validation` - `server-build` only handles build + Nx cache save (~1m vs old 3.5m), unblocking downstream jobs faster - `server-lint-typecheck` runs in parallel with no DB dependency - `server-validation` handles DB setup, migration checks, and GraphQL generation checks in parallel with tests - Make `server-test` (unit tests) fully independent — no longer waits for server-setup, builds its own artifacts - Increase integration test shards from 8 to 10 for better parallelism - Expected critical path reduction: ~10m → ~7m (~30% faster) ### CI Front Pipeline Improvements - Use artifact upload/download for storybook build instead of rebuilding in test shards - Serve pre-built storybook via `http-server` in test jobs, with `STORYBOOK_URL` env var - Update `vitest.config.ts` to use `storybookUrl` when `STORYBOOK_URL` is set - Remove redundant `twenty-shared`, `twenty-ui`, `twenty-sdk` builds from storybook test shards ### Vite Build Optimizations - Conditionally enable `rollup-plugin-visualizer` behind `ANALYZE=true` env var (not loaded by default) - Broaden Istanbul coverage exclusions to skip test files, stories, mocks, and decorators - Remove `@tabler/icons-react` alias from twenty-front and storybook configs - Bundle `@tabler/icons-react` into twenty-ui instead of treating it as an external dependency - Add lazy loading with `React.lazy` + `Suspense` for all page-level route components in `useCreateAppRouter` --- .github/workflows/ci-front.yaml | 26 ++- .github/workflows/ci-server.yaml | 100 ++++++++--- packages/twenty-front/.storybook/main.ts | 5 - .../src/modules/app/components/LazyRoute.tsx | 9 + .../modules/app/hooks/useCreateAppRouter.tsx | 169 +++++++++++++++--- .../__stories__/ExpandableList.stories.tsx | 28 +-- packages/twenty-front/vite.config.ts | 23 ++- packages/twenty-front/vitest.config.ts | 4 +- .../ai-agent-monitor.module.ts | 6 +- packages/twenty-ui/vite.config.ts | 8 +- 10 files changed, 284 insertions(+), 94 deletions(-) create mode 100644 packages/twenty-front/src/modules/app/components/LazyRoute.tsx diff --git a/.github/workflows/ci-front.yaml b/.github/workflows/ci-front.yaml index 3e807ed333b..d2a949c47b5 100644 --- a/.github/workflows/ci-front.yaml +++ b/.github/workflows/ci-front.yaml @@ -62,6 +62,12 @@ jobs: run: npx nx reset:env twenty-front - name: Front / Build storybook run: npx nx storybook:build twenty-front + - name: Upload storybook build + uses: actions/upload-artifact@v4 + with: + name: storybook-static + path: packages/twenty-front/storybook-static + retention-days: 1 - name: Save storybook build cache uses: ./.github/actions/save-cache with: @@ -78,6 +84,7 @@ jobs: env: SHARD_COUNTER: 4 REACT_APP_SERVER_BASE_URL: http://localhost:3000 + STORYBOOK_URL: http://localhost:6006 steps: - name: Fetch local actions uses: actions/checkout@v4 @@ -85,19 +92,33 @@ jobs: fetch-depth: 10 - name: Install dependencies uses: ./.github/actions/yarn-install + - name: Restore storybook build cache + uses: ./.github/actions/restore-cache + with: + key: ${{ env.STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION }} + - name: Clean stale storybook vitest cache + run: rm -rf packages/twenty-front/node_modules/.cache/storybook - name: Build dependencies run: | npx nx build twenty-shared npx nx build twenty-ui npx nx build twenty-sdk + - name: Download storybook build + uses: actions/download-artifact@v4 + with: + name: storybook-static + path: packages/twenty-front/storybook-static - name: Install Playwright run: | cd packages/twenty-front npx playwright install - name: Front / Write .env run: npx nx reset:env twenty-front - - name: Run storybook tests - run: npx nx storybook:test twenty-front --configuration=${{ matrix.storybook_scope }} --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }} + - name: Serve storybook & run tests + run: | + npx http-server packages/twenty-front/storybook-static --port 6006 --silent & + timeout 30 bash -c 'until curl -sf http://localhost:6006 > /dev/null 2>&1; do sleep 1; done' + npx nx storybook:test twenty-front --configuration=${{ matrix.storybook_scope }} --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }} # - name: Rename coverage file # run: | # if [ -f "packages/twenty-front/coverage/storybook/coverage-final.json" ]; then @@ -214,6 +235,7 @@ jobs: runs-on: ubuntu-latest-8-cores env: NODE_OPTIONS: "--max-old-space-size=10240" + ANALYZE: "true" steps: - name: Cancel Previous Runs uses: styfle/cancel-workflow-action@0.11.0 diff --git a/.github/workflows/ci-server.yaml b/.github/workflows/ci-server.yaml index aeae0395ca0..179e8a89f8a 100644 --- a/.github/workflows/ci-server.yaml +++ b/.github/workflows/ci-server.yaml @@ -13,7 +13,7 @@ concurrency: cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} env: - SERVER_SETUP_CACHE_KEY: server-setup + SERVER_BUILD_CACHE_KEY: server-build jobs: changed-files-check: @@ -27,11 +27,59 @@ jobs: packages/twenty-front/src/generated-metadata/** packages/twenty-emails/** packages/twenty-shared/** - server-setup: + + server-build: needs: changed-files-check if: needs.changed-files-check.outputs.any_changed == 'true' timeout-minutes: 30 runs-on: ubuntu-latest-8-cores + steps: + - name: Fetch custom Github Actions and base branch history + uses: actions/checkout@v4 + with: + fetch-depth: 10 + - name: Install dependencies + uses: ./.github/actions/yarn-install + - name: Restore server build cache + id: restore-server-build-cache + uses: ./.github/actions/restore-cache + with: + key: ${{ env.SERVER_BUILD_CACHE_KEY }} + - name: Build twenty-shared + run: npx nx build twenty-shared + - name: Server / Write .env + run: npx nx reset:env twenty-server + - name: Server / Build + run: npx nx build twenty-server + - name: Save server build cache + uses: ./.github/actions/save-cache + with: + key: ${{ steps.restore-server-build-cache.outputs.cache-primary-key }} + + server-lint-typecheck: + needs: changed-files-check + if: needs.changed-files-check.outputs.any_changed == 'true' + timeout-minutes: 30 + runs-on: ubuntu-latest-8-cores + steps: + - name: Fetch custom Github Actions and base branch history + uses: actions/checkout@v4 + with: + fetch-depth: 10 + - name: Install dependencies + uses: ./.github/actions/yarn-install + - name: Build twenty-shared + run: npx nx build twenty-shared + - name: Server / Run lint & typecheck + uses: ./.github/actions/nx-affected + with: + tag: scope:backend + tasks: lint,typecheck + + server-validation: + needs: server-build + timeout-minutes: 30 + runs-on: ubuntu-latest-8-cores services: postgres: image: twentycrm/twenty-postgres-spilo @@ -58,18 +106,12 @@ jobs: fetch-depth: 10 - name: Install dependencies uses: ./.github/actions/yarn-install - - name: Restore server setup - id: restore-server-setup-cache + - name: Restore server build cache uses: ./.github/actions/restore-cache with: - key: ${{ env.SERVER_SETUP_CACHE_KEY }} + key: ${{ env.SERVER_BUILD_CACHE_KEY }} - name: Build twenty-shared run: npx nx build twenty-shared - - name: Server / Run lint & typecheck - uses: ./.github/actions/nx-affected - with: - tag: scope:backend - tasks: lint,typecheck - name: Server / Write .env run: npx nx reset:env twenty-server - name: Server / Build @@ -84,10 +126,8 @@ jobs: run: | timeout 30s npx nx run twenty-server:worker || exit_code=$? if [ $exit_code -eq 124 ]; then - # If timeout was reached (exit code 124), consider it a success exit 0 elif [ $exit_code -ne 0 ]; then - # If worker failed for other reasons, fail the build exit $exit_code fi - name: Server / Start @@ -120,11 +160,9 @@ jobs: fi - name: GraphQL / Check for Pending Generation run: | - # Run GraphQL generation commands npx nx run twenty-front:graphql:generate npx nx run twenty-front:graphql:generate --configuration=metadata - # Check if GraphQL generated files were modified if ! git diff --quiet -- packages/twenty-front/src/generated packages/twenty-front/src/generated-metadata; then echo "::error::GraphQL schema changes detected. Please run 'npx nx run twenty-front:graphql:generate' and 'npx nx run twenty-front:graphql:generate --configuration=metadata' and commit the changes." echo "" @@ -137,14 +175,11 @@ jobs: echo "" exit 1 fi - - name: Save server setup - uses: ./.github/actions/save-cache - with: - key: ${{ steps.restore-server-setup-cache.outputs.cache-primary-key }} + server-test: + needs: server-build timeout-minutes: 30 runs-on: ubuntu-latest-8-cores - needs: server-setup steps: - name: Fetch custom Github Actions and base branch history uses: actions/checkout@v4 @@ -152,10 +187,12 @@ jobs: fetch-depth: 10 - name: Install dependencies uses: ./.github/actions/yarn-install - - name: Restore server setup + - name: Restore server build cache uses: ./.github/actions/restore-cache with: - key: ${{ env.SERVER_SETUP_CACHE_KEY }} + key: ${{ env.SERVER_BUILD_CACHE_KEY }} + - name: Build twenty-shared + run: npx nx build twenty-shared - name: Server / Run Tests uses: ./.github/actions/nx-affected with: @@ -165,11 +202,11 @@ jobs: server-integration-test: timeout-minutes: 30 runs-on: ubuntu-latest-8-cores - needs: server-setup + needs: server-build strategy: fail-fast: false matrix: - shard: [1, 2, 3, 4, 5, 6, 7, 8] + shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] services: postgres: image: twentycrm/twenty-postgres-spilo @@ -207,7 +244,7 @@ jobs: ANALYTICS_ENABLED: true CLICKHOUSE_URL: "http://default:clickhousePassword@localhost:8123/twenty" CLICKHOUSE_PASSWORD: clickhousePassword - SHARD_COUNTER: 8 + SHARD_COUNTER: 10 steps: - name: Fetch custom Github Actions and base branch history uses: actions/checkout@v4 @@ -223,10 +260,10 @@ jobs: echo "BILLING_STRIPE_BASE_PLAN_PRODUCT_ID=test-base-plan-product-id" >> .env.test echo "BILLING_STRIPE_WEBHOOK_SECRET=test-webhook-secret" >> .env.test echo "BILLING_PLAN_REQUIRED_LINK=http://localhost:3001/stripe-redirection" >> .env.test - - name: Restore server setup + - name: Restore server build cache uses: ./.github/actions/restore-cache with: - key: ${{ env.SERVER_SETUP_CACHE_KEY }} + key: ${{ env.SERVER_BUILD_CACHE_KEY }} - name: Server / Build run: npx nx build twenty-server - name: Build dependencies @@ -247,11 +284,20 @@ jobs: tasks: 'test:integration' configuration: 'with-db-reset' args: --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }} + ci-server-status-check: if: always() && !cancelled() timeout-minutes: 5 runs-on: ubuntu-latest - needs: [changed-files-check, server-setup, server-test, server-integration-test] + needs: + [ + changed-files-check, + server-build, + server-lint-typecheck, + server-validation, + server-test, + server-integration-test, + ] steps: - name: Fail job if any needs failed if: contains(needs.*.result, 'failure') diff --git a/packages/twenty-front/.storybook/main.ts b/packages/twenty-front/.storybook/main.ts index 1dbac287368..797f5ef84f6 100644 --- a/packages/twenty-front/.storybook/main.ts +++ b/packages/twenty-front/.storybook/main.ts @@ -58,11 +58,6 @@ const config: StorybookConfig = { return mergeConfig(viteConfig, { logLevel: 'warn', - resolve: { - alias: { - '@tabler/icons-react': '@tabler/icons-react/dist/esm/icons/index.mjs', - }, - }, }); }, diff --git a/packages/twenty-front/src/modules/app/components/LazyRoute.tsx b/packages/twenty-front/src/modules/app/components/LazyRoute.tsx new file mode 100644 index 00000000000..19fea5b4ba8 --- /dev/null +++ b/packages/twenty-front/src/modules/app/components/LazyRoute.tsx @@ -0,0 +1,9 @@ +import { type ReactNode, Suspense } from 'react'; + +type LazyRouteProps = { + children: ReactNode; +}; + +export const LazyRoute = ({ children }: LazyRouteProps) => ( + }>{children} +); diff --git a/packages/twenty-front/src/modules/app/hooks/useCreateAppRouter.tsx b/packages/twenty-front/src/modules/app/hooks/useCreateAppRouter.tsx index f72f153cfac..e10da34e831 100644 --- a/packages/twenty-front/src/modules/app/hooks/useCreateAppRouter.tsx +++ b/packages/twenty-front/src/modules/app/hooks/useCreateAppRouter.tsx @@ -1,4 +1,5 @@ import { AppRouterProviders } from '@/app/components/AppRouterProviders'; +import { LazyRoute } from '@/app/components/LazyRoute'; import { SettingsRoutes } from '@/app/components/SettingsRoutes'; import { VerifyLoginTokenEffect } from '@/auth/components/VerifyLoginTokenEffect'; @@ -8,25 +9,96 @@ import { BlankLayout } from '@/ui/layout/page/components/BlankLayout'; import { DefaultLayout } from '@/ui/layout/page/components/DefaultLayout'; import { AppPath } from 'twenty-shared/types'; +import { lazy } from 'react'; import { createBrowserRouter, createRoutesFromElements, Route, } from 'react-router-dom'; -import { Authorize } from '~/pages/auth/Authorize'; -import { PasswordReset } from '~/pages/auth/PasswordReset'; -import { SignInUp } from '~/pages/auth/SignInUp'; -import { NotFound } from '~/pages/not-found/NotFound'; -import { RecordIndexPage } from '~/pages/object-record/RecordIndexPage'; -import { RecordShowPage } from '~/pages/object-record/RecordShowPage'; -import { BookCall } from '~/pages/onboarding/BookCall'; -import { BookCallDecision } from '~/pages/onboarding/BookCallDecision'; -import { ChooseYourPlan } from '~/pages/onboarding/ChooseYourPlan'; -import { CreateProfile } from '~/pages/onboarding/CreateProfile'; -import { CreateWorkspace } from '~/pages/onboarding/CreateWorkspace'; -import { InviteTeam } from '~/pages/onboarding/InviteTeam'; -import { PaymentSuccess } from '~/pages/onboarding/PaymentSuccess'; -import { SyncEmails } from '~/pages/onboarding/SyncEmails'; + +const RecordIndexPage = lazy(() => + import('~/pages/object-record/RecordIndexPage').then((module) => ({ + default: module.RecordIndexPage, + })), +); + +const RecordShowPage = lazy(() => + import('~/pages/object-record/RecordShowPage').then((module) => ({ + default: module.RecordShowPage, + })), +); + +const SignInUp = lazy(() => + import('~/pages/auth/SignInUp').then((module) => ({ + default: module.SignInUp, + })), +); + +const PasswordReset = lazy(() => + import('~/pages/auth/PasswordReset').then((module) => ({ + default: module.PasswordReset, + })), +); + +const Authorize = lazy(() => + import('~/pages/auth/Authorize').then((module) => ({ + default: module.Authorize, + })), +); + +const CreateWorkspace = lazy(() => + import('~/pages/onboarding/CreateWorkspace').then((module) => ({ + default: module.CreateWorkspace, + })), +); + +const CreateProfile = lazy(() => + import('~/pages/onboarding/CreateProfile').then((module) => ({ + default: module.CreateProfile, + })), +); + +const SyncEmails = lazy(() => + import('~/pages/onboarding/SyncEmails').then((module) => ({ + default: module.SyncEmails, + })), +); + +const InviteTeam = lazy(() => + import('~/pages/onboarding/InviteTeam').then((module) => ({ + default: module.InviteTeam, + })), +); + +const ChooseYourPlan = lazy(() => + import('~/pages/onboarding/ChooseYourPlan').then((module) => ({ + default: module.ChooseYourPlan, + })), +); + +const PaymentSuccess = lazy(() => + import('~/pages/onboarding/PaymentSuccess').then((module) => ({ + default: module.PaymentSuccess, + })), +); + +const BookCallDecision = lazy(() => + import('~/pages/onboarding/BookCallDecision').then((module) => ({ + default: module.BookCallDecision, + })), +); + +const BookCall = lazy(() => + import('~/pages/onboarding/BookCall').then((module) => ({ + default: module.BookCall, + })), +); + +const NotFound = lazy(() => + import('~/pages/not-found/NotFound').then((module) => ({ + default: module.NotFound, + })), +); export const useCreateAppRouter = ( isFunctionSettingsEnabled?: boolean, @@ -43,26 +115,59 @@ export const useCreateAppRouter = ( }> } /> } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> } + element={} /> } + element={} + /> + } /> - } /> } /> - } /> - } /> + } + /> + } + /> } /> - } /> + } + /> }> - } /> + } + /> , ), diff --git a/packages/twenty-front/src/modules/ui/layout/expandable-list/components/__stories__/ExpandableList.stories.tsx b/packages/twenty-front/src/modules/ui/layout/expandable-list/components/__stories__/ExpandableList.stories.tsx index 1be1e90d05a..ec6668a0f30 100644 --- a/packages/twenty-front/src/modules/ui/layout/expandable-list/components/__stories__/ExpandableList.stories.tsx +++ b/packages/twenty-front/src/modules/ui/layout/expandable-list/components/__stories__/ExpandableList.stories.tsx @@ -1,26 +1,19 @@ -import { styled } from '@linaria/react'; import { type Meta, type StoryObj } from '@storybook/react-vite'; import { expect, userEvent, within } from 'storybook/test'; import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList'; -import { isDefined } from 'twenty-shared/utils'; import { Tag } from 'twenty-ui/components'; import { ComponentDecorator } from 'twenty-ui/testing'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; import { MAIN_COLOR_NAMES } from 'twenty-ui/theme'; -const StyledContainer = styled.div` - padding: ${themeCssVariables.spacing[1]}; - width: 300px; -`; const meta: Meta = { title: 'UI/Layout/ExpandableList/ExpandableList', component: ExpandableList, decorators: [ (Story) => ( - +
- +
), ComponentDecorator, ], @@ -50,19 +43,16 @@ export const WithChipCount: Story = { export const WithExpandedList: Story = { ...WithChipCount, - play: async () => { - const root = document.getElementsByTagName('body')[0]; + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); - if (!isDefined(root)) { - throw new Error('Root element not found'); - } - - const rootCanvas = within(root); - - const chipCount = await rootCanvas.findByText(/^\+\d+$/); + const chipCount = await canvas.findByText(/^\+\d+$/); await userEvent.click(chipCount); - expect(await rootCanvas.findByText('Option 7')).toBeDefined(); + const body = canvasElement.ownerDocument.body; + const bodyCanvas = within(body); + + expect(await bodyCanvas.findByText('Option 7')).toBeDefined(); }, }; diff --git a/packages/twenty-front/vite.config.ts b/packages/twenty-front/vite.config.ts index 865e549d647..ab7e3fa18e6 100644 --- a/packages/twenty-front/vite.config.ts +++ b/packages/twenty-front/vite.config.ts @@ -89,8 +89,13 @@ export default defineConfig(({ mode }) => { exclude: [ '**/generated-metadata/**', '**/testing/mock-data/generated/**', + '**/testing/**', '**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}', + '**/*.stories.{ts,tsx}', + '**/__stories__/**', + '**/__tests__/**', + '**/__mocks__/**', '**/types/**', '**/constants/**', '**/states/**', @@ -105,6 +110,7 @@ export default defineConfig(({ mode }) => { '**/mutations/**', '**/fragments/**', '**/graphql/**', + '**/decorators/**', ], babelOptions: { presets: ['@babel/preset-typescript', '@babel/preset-react'], @@ -112,12 +118,16 @@ export default defineConfig(({ mode }) => { }, }), ), - visualizer({ - open: true, - gzipSize: true, - brotliSize: true, - filename: 'dist/stats.html', - }) as PluginOption, // https://github.com/btd/rollup-plugin-visualizer/issues/162#issuecomment-1538265997, + ...(env.ANALYZE === 'true' + ? [ + visualizer({ + open: !process.env.CI, + gzipSize: true, + brotliSize: true, + filename: 'dist/stats.html', + }) as PluginOption, + ] + : []), ], optimizeDeps: { @@ -236,7 +246,6 @@ export default defineConfig(({ mode }) => { resolve: { alias: { path: 'rollup-plugin-node-polyfills/polyfills/path', - '@tabler/icons-react': '@tabler/icons-react/dist/esm/icons/index.mjs', }, }, }; diff --git a/packages/twenty-front/vitest.config.ts b/packages/twenty-front/vitest.config.ts index c0c783b0c09..779dfc1c908 100644 --- a/packages/twenty-front/vitest.config.ts +++ b/packages/twenty-front/vitest.config.ts @@ -24,7 +24,9 @@ export default defineConfig({ plugins: [ storybookTest({ configDir: path.join(dirname, '.storybook'), - storybookScript: 'yarn storybook --no-open', + ...(process.env.STORYBOOK_URL + ? { storybookUrl: process.env.STORYBOOK_URL } + : { storybookScript: 'yarn storybook --no-open' }), }), ], test: { diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/ai-agent-monitor.module.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/ai-agent-monitor.module.ts index f00d52d428c..9bf3ce0f00b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/ai-agent-monitor.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-monitor/ai-agent-monitor.module.ts @@ -2,17 +2,17 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AiAgentExecutionModule } from 'src/engine/metadata-modules/ai/ai-agent-execution/ai-agent-execution.module'; +import { AgentTurnEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-turn.entity'; import { AiAgentModule } from 'src/engine/metadata-modules/ai/ai-agent/ai-agent.module'; import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity'; import { AiChatModule } from 'src/engine/metadata-modules/ai/ai-chat/ai-chat.module'; import { AgentChatThreadEntity } from 'src/engine/metadata-modules/ai/ai-chat/entities/agent-chat-thread.entity'; -import { AgentTurnEntity } from 'src/engine/metadata-modules/ai/ai-agent-execution/entities/agent-turn.entity'; import { AiModelsModule } from 'src/engine/metadata-modules/ai/ai-models/ai-models.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; +import { AgentTurnEvaluationEntity } from './entities/agent-turn-evaluation.entity'; import { EvaluateAgentTurnJob } from './jobs/evaluate-agent-turn.job'; import { RunEvaluationInputJob } from './jobs/run-evaluation-input.job'; -import { AgentTurnEvaluationEntity } from './entities/agent-turn-evaluation.entity'; import { AgentTurnResolver } from './resolvers/agent-turn.resolver'; import { AgentTurnGraderService } from './services/agent-turn-grader.service'; @@ -21,8 +21,8 @@ import { AgentTurnGraderService } from './services/agent-turn-grader.service'; TypeOrmModule.forFeature([ AgentTurnEvaluationEntity, AgentTurnEntity, - AgentEntity, AgentChatThreadEntity, + AgentEntity, ]), AiAgentModule, AiAgentExecutionModule, diff --git a/packages/twenty-ui/vite.config.ts b/packages/twenty-ui/vite.config.ts index f0a37eed3c1..2a0fb882118 100644 --- a/packages/twenty-ui/vite.config.ts +++ b/packages/twenty-ui/vite.config.ts @@ -56,11 +56,15 @@ export default defineConfig(({ command }) => { tsconfigPath: tsConfigPath, }; + const BUNDLED_DEPS = ['@tabler/icons-react']; + return { resolve: { alias: { '@ui/': path.resolve(__dirname, 'src') + '/', '@assets/': path.resolve(__dirname, 'src/assets') + '/', + '@tabler/icons-react': + '@tabler/icons-react/dist/esm/icons/index.mjs', }, }, css: { @@ -122,7 +126,9 @@ export default defineConfig(({ command }) => { name: 'twenty-ui', }, rollupOptions: { - external: Object.keys(packageJson.dependencies || {}), + external: Object.keys(packageJson.dependencies || {}).filter( + (dep) => !BUNDLED_DEPS.includes(dep), + ), output: [ { assetFileNames: 'style.css',