Commit Graph

3381 Commits

Author SHA1 Message Date
Félix Malfait 1088f7bbab feat: add lingui/no-unlocalized-strings ESLint rule and fix translations (#16610)
## Summary
This PR adds the `lingui/no-unlocalized-strings` ESLint rule to detect
untranslated strings and fixes translation issues across multiple
components.

## Changes

### ESLint Configuration (`eslint.config.react.mjs`)
- Added comprehensive `ignore` patterns for non-translatable strings
(CSS values, HTML attributes, technical identifiers)
- Added `ignoreNames` for props that don't need translation (className,
data-*, aria-*, etc.)
- Added `ignoreFunctions` for console methods, URL APIs, and other
non-user-facing functions
- Disabled rule for debug files, storybook, and test files

### Components Fixed (~19 files)
- Object record components (field inputs, pickers, merge dialogs)
- Settings components (accounts, admin panel)
- Serverless function components
- Record table and title cell components

## Status
🚧 **Work in Progress** - ~124 files remaining to fix

This PR is being submitted as draft to allow progressive fixing of
remaining translation issues.

## Testing
- Run `npx eslint "src/**/*.tsx"` in `packages/twenty-front` to check
remaining issues
2025-12-17 22:08:33 +01:00
Abdullah. c13b955a36 fix: hide GraphQL stack traces and messages in production (#16593)
Resolves [Code Scanning Alert
180](https://github.com/twentyhq/twenty/security/code-scanning/180).

- Normalize unexpected GraphQL errors in convertExceptionToGraphql to a
generic "Internal Server Error" instead of exposing exception.name
directly to clients.
- Only attach stack and response (original error message) in
development, so production responses don’t leak internal class names,
implementation details, or stack traces, while observability is
preserved via `ExceptionHandlerService`/Sentry.
- Keep behavior consistent with `convertHttpExceptionToGraphql`, which
also only exposes detailed response and stack information when `NODE_ENV
=== DEVELOPMENT`.
2025-12-17 18:29:40 +01:00
Bhoomaahamso a560e8ac83 feat: 🎸 added higher resoulution options in the dateTime Filter (#16548)
Title: "feat: Add second, minute & hour resolution options to relative
date Filter action"
---

## Summary

This PR enables support for smaller time units — **Seconds, Minutes, and
Hours** — in the *Relative Date* filter used in workflows, rather than
being limited to days only.

---

## What Changed

This PR extends the relative date filter to include support for the
following units:

✔️ `SECOND`  
✔️ `MINUTE`  
✔️ `HOUR`  
✔️ (Existing: `DAY`, `WEEK`, `MONTH`, etc.)

Changes include:

- Adding `SECOND`, `MINUTE`, and `HOUR` options to the internal relative
date unit enum/constant.
- Updating utility functions and parsers to correctly interpret and
evaluate these new units.
- Enhancing existing tests and adding new tests to cover second, minute,
and hour relative filters.

---

## Testing

New and updated tests include:

- Unit tests for serialization of relative filter values including
seconds, minutes, and hours.
- Workflow filter evaluation tests that verify minute/hour resolution
behaves correctly.

Tests are included in the changeset.

---

## Backward Compatibility

This change is fully backward compatible:

- All existing relative date filters using days or larger units behave
exactly as before.
- Adding finer units does not alter existing stored data or workflow
definitions.

---

##  Issue Reference

Fixes: **twentyhq/twenty#15525**  

<img width="1909" height="896" alt="image"
src="https://github.com/user-attachments/assets/328d03dc-ca0b-4c3f-84e5-58961c178398"
/>

---------

Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: guillim <guigloo@msn.com>
2025-12-17 16:46:11 +00:00
Etienne 59d3a14922 Common API - Add tests on position field validation at creation (#16630)
Co-authored-by: guillim <guigloo@msn.com>
2025-12-17 16:02:37 +00:00
Paul Rastoin 0e6a8c04c4 Async validators and additional cache maps in v2 Builder (#16618)
# Introduction
@bosiraphael has to introduce async validators and feature flag
contextual validator
In this way in this PR we make all entity validators asyncable
Also added an `additionalCacheDataMaps` to the low level args validators
2025-12-17 15:43:25 +01:00
neo773 6de424bc32 handle localization and property parameters in CalDAV iCal parsing (#16519)
Co-authored-by: guillim <guigloo@msn.com>
2025-12-17 11:47:16 +01:00
Marie 0145920d7e e2e tests (#16533)
In this PR, 
- current basic E2E tests are fixed, and some were added, covering some
basic scenarios
- some tests avec been commented out, until we decide whether they are
worth fixing

The next steps are
- evaluate the flakiness of the tests. Once they've proved not to be
flaky, we should add more tests + re-write the current ones not using
aria-label (cf @lucasbordeau indication).
- We will add them back to the development flow
2025-12-17 08:48:17 +01:00
martmull 1cbbd04761 Function trigger updates 2 (#16608)
- Improves route trigger job performances
- expose function params types

## Before

<img width="938" height="271" alt="image"
src="https://github.com/user-attachments/assets/5752ba64-f31d-44ed-974d-536e63458f2c"
/>


## After

<img width="1000" height="559" alt="image"
src="https://github.com/user-attachments/assets/b1f4927a-5f43-49f0-a606-244c72356772"
/>
2025-12-16 18:20:26 +01:00
github-actions[bot] 38a0bba57b i18n - docs translations (#16600)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-16 15:21:59 +01:00
github-actions[bot] a6127c2128 i18n - translations (#16596)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-16 15:04:08 +01:00
Félix Malfait 04c596817a feat(server): enforce userFriendlyMessage on all exceptions (#16589)
## Summary
This PR enforces that all custom exceptions must provide a
`userFriendlyMessage`, ensuring end users always see readable error
messages.

## Changes

### Core Changes
- **`CustomException` simplified**: Removed the `ForceFriendlyMessage`
generic parameter - `userFriendlyMessage` is now always required
- **Type safety**: The constructor now requires `{ userFriendlyMessage:
MessageDescriptor }` (no longer optional)

### Updated Files
- **74+ exception classes** updated to provide default user-friendly
messages using Lingui `msg` macro
- Each exception class has a sensible fallback message (e.g., `msg\`An
authentication error occurred.\``)
- Exception classes that had code-specific message maps retain their
behavior

## Benefits
- **Compile-time enforcement**: Forgetting to add a user-friendly
message now causes a TypeScript error
- **Better UX**: End users always see a localized, human-readable error
message
- **Simpler API**: No more boolean generic parameter to think about

## Testing
- `npx nx run twenty-server:typecheck` passes
- `npx nx run twenty-server:lint` passes

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Enforces `userFriendlyMessage` on `CustomException` and updates all
exception classes to supply localized default messages, with
filters/tests adjusted accordingly.
> 
> - **Core**:
> - Enforce required `userFriendlyMessage` in `CustomException` (remove
optional generic; constructor now requires `{ userFriendlyMessage:
MessageDescriptor }`).
> - **Exceptions**:
> - Update ~70+ exception classes to set default localized messages via
Lingui `msg` maps and pass them in constructors (e.g., `AuthException`,
`ObjectMetadataException`, `FieldMetadataException`, etc.).
> - Add fallback messages where needed (e.g., `INTERNAL_SERVER_ERROR` or
domain-specific defaults).
> - **HTTP/GraphQL Filters**:
> - Ensure fallbacks create `UnknownException` with `msg` for
user-friendly text in REST/GraphQL exception filters.
> - **Tests**:
>   - Adjust unit tests to pass `userFriendlyMessage` to exceptions.
> - Update Jest snapshots to include `extensions.userFriendlyMessage` or
message objects where applicable.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
221004fdfc0d97b7d152a258b347bf571e70f10e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-12-16 14:44:27 +01:00
martmull 3ac72683da Update migration command (#16578)
Avoid pg_ table request
2025-12-16 13:35:03 +00:00
Abdullah. d998e3b92c Display a CTA to view the existing duplicate when adding a duplicate email/domain. (#16483)
Closes [89](https://github.com/twentyhq/core-team-issues/issues/89)

## Problem

When users attempt to create or update a record with a duplicate value
for a unique field (e.g., duplicate email or domain name), they receive
a generic error message: "This record already exists. Please check your
data and try again." This provides no actionable way to locate and view
the existing conflicting record, forcing users to manually search for
it.

## Solution

This PR enhances duplicate key constraint error handling to
automatically detect the conflicting record and display a "View existing
record" link in the error notification. When clicked, users are
navigated directly to the existing record's detail page.

## Backend Changes

### 1. PostgreSQL Error Parsing
(`parse-postgres-constraint-error.util.ts`)
- Extracts structured information from PostgreSQL `QueryFailedError`
messages.

### 2. Conflicting Record Lookup (`find-conflicting-record.util.ts`)
- Queries the database to find the existing record with the conflicting
value

### 3. Error Handling Orchestration
(`handle-duplicate-key-error.util.ts`)
- Parses PostgreSQL error to extract column name and conflicting value
- Attempts to find the conflicting record
- Enriches `TwentyORMException` with `conflictingRecordId` and
`conflictingObjectNameSingular` if found

### 4. Exception Computation Updates (`compute-twenty-orm-exception.ts`)
- Made function `async` and added optional `entityManager` and
`internalContext` parameters
- Needed to support async database queries for conflicting record lookup

### 5. GraphQL Error Handler
(`twenty-orm-graphql-api-exception-handler.util.ts`)
- **Changes**: Enhanced `DUPLICATE_ENTRY_DETECTED` case to include
`conflictingRecordId` and `conflictingObjectNameSingular` in GraphQL
error extensions

## Frontend Changes

### 1. Error Extraction Utility
(`get-conflicting-record-from-apollo-error.util.ts`)
- Accesses GraphQL error extensions
- Validates that both `conflictingRecordId` and
`conflictingObjectNameSingular` exist and are strings
- Returns `null` if validation fails

### 2. SnackBar Enhancement (`useSnackBar.ts`)
- Extracts conflicting record info from Apollo error
- Constructs URL using `getAppPath` utility
- Adds link object to snackbar options with text "View existing record"

<img width="931" height="858" alt="image"
src="https://github.com/user-attachments/assets/28137dc7-18ab-4ffe-b669-1f2d4ec264d1"
/>
2025-12-16 14:27:34 +01:00
Paul Rastoin 75bba5a8ee Standard Agent, Role, Role target (#16499)
# Introduction
In this pullrequest have been migrated to the flat standard entities:
Role, Agent and RoleTargets.

## What happens
- Removed createStandardMorph tool util in favor of dynamic typing of
`createMorphOrRelationStandardField`
- Implemented a command to remove standard agents and their role that
has been removed in https://github.com/twentyhq/twenty/pull/16513 also
added a default role target to data manipulator role to the only
remaining agent
- Implemented an agent deleteMany service handler
2025-12-16 14:17:31 +01:00
Abdul Rahman 289e8bf1d4 fix: ensure unique GraphQL schema caching per API key (#16411)
## Description

This PR fixes an issue where the GraphQL schema was being incorrectly
cached and shared across different API keys within the same workspace.
This resulted in the `createdBy` field (Actor) from the first API key's
request being erroneously attributed to subsequent requests made by
different API keys.

## Changes

- Updated the `@graphql-yoga/nestjs` patch to include the request's
`Authorization` header in the schema cache key generation logic.
- This ensures that every unique authentication token (and thus every
unique API key) generates a distinct cache entry, preventing schema
context collisions.

Closes #15093
2025-12-15 18:23:33 +01:00
Etienne 0ecb60f50b E2B var env fix (#16576) 2025-12-15 18:20:22 +01:00
Marie a0b963ef86 Remove viewGroup.fieldMetadataId (#16571)
Final step of
https://github.com/orgs/twentyhq/projects/1/views/8?pane=issue&itemId=142348748&issue=twentyhq%7Ccore-team-issues%7C1965

Removing viewGroup.fieldMetadataId.
It's already not used in FE anymore
2025-12-15 17:58:45 +01:00
neo773 66d242da24 prevent filtering out messages sent by user when their handle resembes group email (#16508) 2025-12-15 17:58:25 +01:00
martmull e289f3056e 1895 extensibility v1 application tokens 3 (#16504)
- moves applicationRoleId to application entity
- add new `APPLICATION` FieldActorSource and `APPLICATION`
JwtTokenTypeEnum value
- create a new token with applicationId when executing a function
- when applicationId is in token, check for application.defaultRole
permissions
-use twenty-shared types in `twenty-sdk/application`
- create a new import from generate called "Twenty" that you can use
directly without having to set TWENTY_API_KEY AND TWENTY_API_URL (keep
metadata or core parameter only)
- provide to serverless unique one time BEARER TOKEN to run it

Result
<img width="977" height="566" alt="image"
src="https://github.com/user-attachments/assets/e78428a0-5b13-4975-aa13-58ee3b32450c"
/>

<img width="910" height="596" alt="image"
src="https://github.com/user-attachments/assets/6ec72bf5-7655-4093-a45e-ad269595a324"
/>

<img width="741" height="568" alt="image"
src="https://github.com/user-attachments/assets/7683944c-fd79-4417-8fb2-8e4815cc112f"
/>
2025-12-15 17:44:23 +01:00
Weiko 039a3d99a8 Fix APIKey typing (#16541)
Following this https://github.com/twentyhq/twenty/pull/16540
Those were not failing (yet) but were wrongly typed and error prone

---------

Co-authored-by: Guillim <guillim@users.noreply.github.com>
2025-12-15 16:05:28 +00:00
nitin fc74a06f53 [Dashboards] add hide empty category option for pie charts (#16550)
closes
https://discord.com/channels/1130383047699738754/1445403391722520677


https://github.com/user-attachments/assets/980225a8-153e-4b49-89f7-5944227c8fdb


toggle label ie `Hide empty category` -- debatable
2025-12-15 15:40:46 +00:00
Thomas Trompette 95e0793f81 Compute output schema on frontend (#16530)
Fixes https://github.com/twentyhq/core-team-issues/issues/1382

Current issue : all step output schemas are computed and stored on
backend side. Which means that, when the database schema is updated -
like a field creation - steps needs to be deleted an recreated. Which is
invisible to users.

Solution : schema generation is moved on frontend side

1. Coming on the page the first time, the schema is populated for all
steps except a few ones that are handled differently (Code, Webhook,
http node, Agent)

2. A separated state allow to determine if a step needs a recomputation.

3. The user only needs a refresh to see the whole schema re-computed

Follow-up:
- check if remaining backend steps could be moved to runtime
computation. But Code will still require storage.
- Clean backend service that is not used anymore
2025-12-15 16:20:35 +01:00
Félix Malfait 2e104c8e76 feat(ai): add code interpreter for AI data analysis (#16559)
## Summary

- Add code interpreter tool that enables AI to execute Python code for
data analysis, CSV processing, and chart generation
- Support for both local (development) and E2B (sandboxed production)
execution drivers
- Real-time streaming of stdout/stderr and generated files
- Frontend components for displaying code execution results with
expandable sections

## Code Quality Improvements

- Extract `getMimeType` to shared utility to reduce code duplication
between drivers
- Fix security issue: escape single quotes/backslashes in E2B driver env
variable injection
- Add `buildExecutionState` helper to reduce duplicated state object
construction
- Add `DEFAULT_CODE_INTERPRETER_TIMEOUT_MS` constant for consistency
- Fix lingui linting warning and TypeScript theme errors in frontend

## Test Plan

- [ ] Test code interpreter with local driver in development
- [ ] Test code interpreter with E2B driver in production environment
- [ ] Verify streaming output displays correctly in chat UI
- [ ] Verify generated files (charts, CSVs) are uploaded and
downloadable
- [ ] Test file upload flow (CSV, Excel) triggers code interpreter

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Updates generated i18n catalogs for Polish and pseudo-English, adding
strings for code execution/output (code interpreter) and various UI
messages, with minor text adjustments.
> 
> - **Localization**:
> - **Generated catalogs**: Refresh `locales/generated/pl-PL.ts` and
`locales/generated/pseudo-en.ts`.
> - Add strings for code execution/output (e.g., code, copy code/output,
running/waiting states, download files, generated files, Python code
execution).
> - Include new UI texts (errors, prompts, menus) and minor text
corrections.
>   - No changes to `pt-BR`; other files unchanged functionally.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
befc13d02c21e5a6647bc1aa6daa2a89f60b7ef8. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-12-15 16:11:24 +01:00
Etienne 3e55e772d4 Update null command (#16567)
Remove version condition to re-run the command on upgraded workspaces on
which it fails
2025-12-15 13:55:32 +00:00
neo773 a83732d7a6 fix messaging error parsing (#16448) 2025-12-15 13:33:37 +01:00
Abhishek Kumar 042972d7b2 fix(workflow): line break not supported by Send Email Nodes (#16561)
Closes #16557

Tiptap Editor (which the Send Email Node uses) , creates a content json
with type 'hardBreak' for line breaks.

The was no rederer defined for this `hardBreak` node type, so the
`renderNode` function was ignoring that node (returning null).

**Fix :** Added a renderer for  `hardBreak` node type.
2025-12-15 13:24:31 +01:00
Paul Rastoin 8c79353bfb Fix rename index collides with existing v2 index (#16560)
## Introduction
When migrating a v1 index name to v2 it might collide with an existing
v2 index
In this case we remove both the v1 metadata and pg index

In case of a metadata and pg_index desync this might occur too late in
the process that's why we have two fallback
One computing the v1 deletion from the metadata and another one in the
catch block of the v1 to migration transaction commit
2025-12-15 11:06:09 +01:00
Abdullah. cf6fb419e0 fix: ensure deactivated object records do not appear in search (#16532)
Deactivating an object still allowed querying its records in search.

<img width="1512" height="856" alt="image"
src="https://github.com/user-attachments/assets/0a1ba36f-1ecf-44d3-8e97-294bb4e81e4f"
/>

<br />
<br />

This PR introduces a minor improvement to not query records of
deactivated objects.

<img width="1512" height="856" alt="image"
src="https://github.com/user-attachments/assets/f5fd1377-2fda-4653-b3cc-30a59d52e4cf"
/>
2025-12-15 10:42:22 +01:00
Aatif Rashid 1119e3d77e fix(twenty-shared): preserve special characters in URLs (#16312)
# Fix: URL Encoding Bug & Code Refactor

## Issue

**Bug**: URLs with encoded characters (e.g., `%20` for spaces) were
being double-encoded or incorrectly processed in
[lowercaseUrlOriginAndRemoveTrailingSlash](cci:1://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/lowercaseUrlOriginAndRemoveTrailingSlash.ts:4:0-16:2),
causing URL mismatches and potential data integrity issues.

**Build Error**: `TS2307: Cannot find module
'src/modules/messaging/message-import-manager/drivers/imap/utils/safe-decode-uri-component.util'`

## Root Cause Analysis

### 1. Missing URL Decoding
The
[lowercaseUrlOriginAndRemoveTrailingSlash](cci:1://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/lowercaseUrlOriginAndRemoveTrailingSlash.ts:4:0-16:2)
function was processing URLs without properly decoding URI components.
When URLs contained encoded characters like `%20`, `%2F`, etc., they
weren't being normalized correctly.

### 2. Invalid Cross-Package Import
The fix attempted to import
[safeDecodeURIComponent](cci:1://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/safeDecodeURIComponent.ts:0:0-6:2)
from `twenty-server`:

```typescript
import { safeDecodeURIComponent } from 'src/modules/messaging/message-import-manager/drivers/imap/utils/safe-decode-uri-component.util';
```

This failed because:
- The file resides in `twenty-shared`, a separate package
- TypeScript cannot resolve internal paths from another package
- The monorepo uses package exports (`twenty-shared/utils`) for
cross-package imports, not direct file paths

## Solution

### 1. Bug Fix: Added Safe URI Decoding

Updated
[lowercaseUrlOriginAndRemoveTrailingSlash.ts](cci:7://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/lowercaseUrlOriginAndRemoveTrailingSlash.ts:0:0-0:0)
to properly decode URL components:

```typescript
export const lowercaseUrlOriginAndRemoveTrailingSlash = (rawUrl: string) => {
  const url = getURLSafely(rawUrl);

  if (!isDefined(url)) {
    return rawUrl;
  }

  const lowercaseOrigin = url.origin.toLowerCase();
  const path =
    safeDecodeURIComponent(url.pathname) + 
    safeDecodeURIComponent(url.search) + 
    url.hash;

  return (lowercaseOrigin + path).replace(/\/$/, '');
};
```

The
[safeDecodeURIComponent](cci:1://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/safeDecodeURIComponent.ts:0:0-6:2)
wrapper handles malformed URI sequences gracefully by returning the
original string if decoding fails, preventing runtime crashes.

### 2. Refactor: Consolidated Shared Utility

**Before**: Duplicate utility existed in `twenty-server`
```
twenty-server/src/modules/messaging/.../utils/safe-decode-uri-component.util.ts
```

**After**: Single source of truth in `twenty-shared`
```
twenty-shared/src/utils/url/safeDecodeURIComponent.ts
```

This follows the established pattern in the codebase where shared
utilities live in `twenty-shared` and are imported via subpath exports:

```typescript
// In twenty-server
import { safeDecodeURIComponent } from 'twenty-shared/utils';

// In twenty-shared (local import)
import { safeDecodeURIComponent } from './safeDecodeURIComponent';
```

## Files Changed

| File | Action | Description |
|------|--------|-------------|
|
[twenty-shared/src/utils/url/safeDecodeURIComponent.ts](cci:7://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/safeDecodeURIComponent.ts:0:0-0:0)
| **Created** | New shared utility (moved from twenty-server) |
|
[twenty-shared/src/utils/url/index.ts](cci:7://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/index.ts:0:0-0:0)
| **Modified** | Added export for
[safeDecodeURIComponent](cci:1://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/safeDecodeURIComponent.ts:0:0-6:2)
|
|
[twenty-shared/src/utils/url/lowercaseUrlOriginAndRemoveTrailingSlash.ts](cci:7://file:///Users/apple/WebstormProjects/twenty/packages/twenty-shared/src/utils/url/lowercaseUrlOriginAndRemoveTrailingSlash.ts:0:0-0:0)
| **Modified** | Fixed import path, now uses local relative import |
| `twenty-server/.../imap-message-text-extractor.service.ts` |
**Modified** | Updated import to use `twenty-shared/utils` |
| `twenty-server/.../safe-decode-uri-component.util.ts` | **Deleted** |
Removed duplicate utility |

## The Utility

```typescript
// safeDecodeURIComponent.ts
export const safeDecodeURIComponent = (text: string): string => {
  try {
    return decodeURIComponent(text);
  } catch {
    return text;
  }
};
```

This wrapper is necessary because `decodeURIComponent()` throws a
`URIError` on malformed sequences (e.g., `%E0%A4%A`). The safe version
returns the original string instead of crashing.

## Testing

- **342 tests passed** in `twenty-shared`
- `lowercaseUrlOriginAndRemoveTrailingSlash.test.ts` validates URL
normalization behavior
- No regressions in existing functionality

## Impact

- **Bug Fixed**: URLs with encoded characters are now properly
normalized
- **Code Quality**: Eliminated code duplication between packages
- **Maintainability**: Single source of truth for URI decoding utility
- **Build**: Resolved TS2307 compilation error

---------

Co-authored-by: Joker <apple@Apples-MacBook-Pro.local>
2025-12-15 08:41:57 +00:00
Paul Rastoin d189e3f57e Fix rename command error code edge case (#16556) 2025-12-15 08:36:35 +00:00
Etienne d36d0d49d1 Investigate - Slow transformRichTextV2 function (#16535)
Investigate CPU overloading ...

related to https://github.com/twentyhq/twenty/issues/15916
2025-12-12 18:39:01 +01:00
Weiko 62408e7fd3 Fix APIKey in search resolver for get role (#16540)
Fixes https://github.com/twentyhq/twenty/issues/16534

Typing was wrong, apiKey from request object is ApiKeyEntity and not a
string which was then failing when using
```typescript
const roleId = apiKeyRoleMap[apiKeyId];

    if (!isDefined(roleId)) {
      throw new ApiKeyException(
        `API key ${apiKeyId} has no role assigned`,
        ApiKeyExceptionCode.API_KEY_NO_ROLE_ASSIGNED,
      );
    }
```

error
```
API key [object Object] has no role assigned"
```

## Before
<img width="963" height="316" alt="Screenshot 2025-12-12 at 17 37 06"
src="https://github.com/user-attachments/assets/761a75c6-1bac-48d7-b8cd-3356e9a56028"
/>

## After
<img width="905" height="313" alt="Screenshot 2025-12-12 at 17 36 44"
src="https://github.com/user-attachments/assets/475b7106-713c-408e-99d0-1447599f7152"
/>
2025-12-12 17:54:07 +01:00
Paul Rastoin f0af947331 [RenameIndexCommand] Fix orphaned index edge case (#16539)
We've been facing orphaned metadata index that would result in alter
error, now if we encounter one we just delete it
2025-12-12 16:44:00 +00:00
Weiko 0035fc1145 Fix rest metadata version missing (#16536)
## Context

The REST pipeline re-fetches/sets the metadata version later in
RestApiBaseHandler#getObjectMetadata by reading from DB and seeding the
cache if it’s missing. That’s the place that actually needs it and
already handles the “undefined” case.

This also mirror the graphql path that was updated 3 weeks ago
2025-12-12 17:25:57 +01:00
Paul Rastoin 59663ec34e fix(server): non blocking CleanEmptyStringNullInTextFieldsCommand error (#16529)
# Introduction
Getting query timeout on prod upgrade for workspace that has huge
timeline activity table
2025-12-12 16:02:23 +01:00
Félix Malfait 4f91b48470 feat(ai): add context usage display to AI chat (BREAKING: deploy server first) (#16518)
## Summary

- Add a context usage indicator to the AI chat interface inspired by
Vercel's AI SDK Context component
- Display token consumption, context window utilization percentage, and
estimated cost in credits
- Show a circular progress ring with percentage, revealing detailed
breakdown on hover

## Changes

### Backend
- Stream usage metadata (tokens, model config) via `messageMetadata`
callback in `agent-chat-streaming.service.ts`
- Return model config from `chat-execution.service.ts`
- Add usage and model types to `ExtendedUIMessage` metadata

### Frontend
- New `ContextUsageProgressRing` component - circular SVG progress
indicator
- New `AIChatContextUsageButton` component with hover card showing:
  - Progress bar with used/total tokens
  - Input/output token counts with credit costs
  - Total credits consumed
- Track cumulative usage in Recoil state (`agentChatUsageState`)
- Reset usage when creating new chat thread
- Integrate button into `AIChatTab`

## Test plan

- [ ] Open AI chat and send a message
- [ ] Verify the context usage button appears with percentage
- [ ] Hover over the button to see detailed breakdown
- [ ] Verify credits are calculated correctly
- [ ] Create a new chat thread and verify usage resets to 0
2025-12-12 13:42:00 +01:00
Weiko bd8ed03990 Add TTL eviction to local data cache (#16510)
We keep different versions of our cache to avoid race conditions but we
never evict stale data. This PR should fix that
2025-12-12 10:14:46 +01:00
Félix Malfait 5f4f4c0af8 feat(ai): add dashboard tools for AI chat (#16517)
## Summary

- Implements real tools for the dashboard-building skill to create and
manage dashboards through the AI chat interface
- Adds 6 new dashboard tools: `create_complete_dashboard`,
`list_dashboards`, `get_dashboard`, `add_dashboard_widget`,
`update_dashboard_widget`, `delete_dashboard_widget`
- Improves widget configuration robustness with typed Zod schemas and
discriminated unions for graph types

## Key Changes

**New Dashboard Tools:**
- `create_complete_dashboard` - Creates a dashboard with layout, tab,
and widgets in a single call
- `list_dashboards` - Lists all dashboards in the workspace
- `get_dashboard` - Gets full dashboard details including tabs and
widget configurations
- `add_dashboard_widget` - Adds a widget to an existing dashboard tab
- `update_dashboard_widget` - Updates widget properties or configuration
- `delete_dashboard_widget` - Removes a widget from a dashboard

**Widget Configuration Improvements:**
- Typed Zod schemas for each chart type (AGGREGATE, BAR, LINE, PIE)
- Discriminated union validation based on `graphType`
- Widget-level error handling for partial success when creating
dashboards
- Clear documentation about required `objectMetadataId` and field UUIDs

**Skill Documentation Updates:**
- Updated `dashboard-building.skill.ts` with critical guidance about
looking up field metadata first
- Added workflow instructions: use `list_object_metadata_items` before
creating GRAPH widgets
- Practical grid layout recommendations

## Test plan

- [ ] Create a new dashboard via AI chat
- [ ] Verify widgets display data correctly when proper field IDs are
provided
- [ ] Test adding/updating/deleting widgets on existing dashboards
- [ ] Verify error messages are helpful when configuration is incorrect
2025-12-12 07:35:14 +01:00
Félix Malfait 70a78aafe9 feat(ai): replace agent search with skills system (#16513)
## Summary

- Replace the agent search mechanism with a new skills-based system
- Add a `skills` module with predefined skill definitions that the AI
can load on demand
- Remove specialized agents (workflow-builder, data-manipulator,
dashboard-builder, metadata-builder, researcher), keeping only the
helper agent
- Add `recordReferences` to workflow creation tool for chip linking in
the UI

## Changes

### New Skills Module
- `skill-definitions.ts` - Contains 5 skill definitions with detailed
instructions
- `skills.service.ts` - Service to get skills by name
- `load-skill.tool.ts` - Tool for AI to load skills explicitly

### Removed
- `agent-search.tool.ts` - Replaced by skill loading
- Specialized agent definitions (converted to skills)

### Updated
- Chat execution now shows skill catalog in system prompt
- Workflow creation returns `recordReferences` for UI linking

## Test plan
- [ ] Verify AI can load skills using `load_skill` tool
- [ ] Verify skill content is returned correctly
- [ ] Verify workflow creation shows clickable chip in chat
- [ ] Verify helper agent still works
2025-12-12 06:51:25 +01:00
github-actions[bot] 14b2487d25 i18n - translations (#16515)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-12 00:01:10 +01:00
github-actions[bot] aad581a353 i18n - translations (#16514)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-11 23:21:05 +01:00
Félix Malfait a13727335b feat(ai): refresh AI models with deprecation support and multi-provider defaults (BREAKING: deploy server before frontend please) (#16503)
## Summary

- Add latest AI models from OpenAI (GPT-4.1, o3, o4-mini), Anthropic
(Claude 4.5 Opus/Sonnet/Haiku), and xAI (Grok 4.1)
- Mark deprecated models (GPT-4o, GPT-4o-mini, GPT-4-turbo, Claude Opus
4, Claude Sonnet 4) with a `deprecated` flag
- Split AI models into separate files per provider for better
maintainability
- Support comma-separated default model lists for automatic fallback
across providers (works out of the box for self-hosters regardless of
which provider they configure)
- Filter deprecated models from dropdown selection while keeping them
functional for existing agents

## Changes

### New Models Added
| Provider | Models |
|----------|--------|
| OpenAI | gpt-4.1, gpt-4.1-mini, o3, o4-mini |
| Anthropic | claude-opus-4-5, claude-sonnet-4-5, claude-haiku-4-5 |
| xAI | grok-4-1-fast-reasoning |

### Deprecated Models
- gpt-4o, gpt-4o-mini, gpt-4-turbo (OpenAI)
- claude-opus-4-20250514, claude-sonnet-4-20250514 (Anthropic)

### Config Changes
Default model configs now support comma-separated fallback lists:
-
`DEFAULT_AI_SPEED_MODEL_ID=gpt-4.1-mini,claude-haiku-4-5-20251001,grok-3-mini`
-
`DEFAULT_AI_PERFORMANCE_MODEL_ID=gpt-4.1,claude-sonnet-4-5-20250929,grok-4`

## Test plan

- [x] Unit tests pass
- [x] Typecheck passes
- [x] Lint passes
- [ ] Verify deprecated models don't appear in model dropdowns
- [ ] Verify agents with deprecated models still work correctly
- [ ] Verify default model fallback works when only one provider is
configured
2025-12-11 21:47:38 +01:00
Guillim 999bc84b17 fix(server): Favortites, attachments, timeline... (#16509)
fix(server): system objects like Favortites, attachments, timeline...
should be system fields
2025-12-11 18:28:14 +01:00
Weiko 083a038f8a Deprecate workspace datasoure (#16507) 2025-12-11 18:27:49 +01:00
Félix Malfait 3cea19baf4 feat(ai): add view management tools for AI chat (#16495)
## Summary

Adds a new **VIEW** tool category for the AI chat, enabling it to work
with views:

- **get-views**: List views in the workspace, optionally filtered by
object metadata ID
- **get-view-query-parameters**: Convert a view's filters and sorts into
GraphQL query parameters that can be passed to existing `find_*` data
tools
- **create-view**, **update-view**, **delete-view**: CRUD operations for
view management

### Key design decisions

1. **No pagination duplication**: Instead of creating a
`find-records-from-view` tool that would duplicate pagination logic,
`get-view-query-parameters` returns filter/sort parameters that the AI
can pass to existing record-fetching tools.

2. **Permission model**:
- Read tools (get-views, get-view-query-parameters) are available to all
users
   - Write tools require the `VIEW` permission
   - UNLISTED views can only be modified by their creator

3. **Leverages existing utilities**: Uses
`computeRecordGqlOperationFilter` from `twenty-shared` for filter
conversion.

### Files changed

- Added `ViewToolProvider`, `ViewToolsFactory`, and
`ViewQueryParamsService`
- Added `VIEW` to `ToolCategory` enum and tool registry
- Updated `chat-execution.service.ts` to include view tools in the
catalog and pass viewId in browsing context
- Extracted shared `formatValidationErrors` utility to reduce
duplication

## Test plan

- [x] Unit tests for `ViewToolsFactory` 
- [x] Unit tests for `ViewQueryParamsService`
- [x] Lint and typecheck pass
2025-12-11 15:05:42 +01:00
github-actions[bot] 2943125410 i18n - translations (#16500)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-12-11 15:01:58 +01:00
Paul Rastoin f06a5ccacd Remove sync metadata from upgrade (#16491)
# Introduction
Related https://github.com/twentyhq/core-team-issues/issues/1910
From now on the upgrade won't integrate any sync metadata as it's going
to be deprecated very soon
Any updates to about to removes workspace-entity or standard flat entity
will require a dedicated upgrade command, what we've already started
doing during the 1.13 sprint, until we have totally migrated the v2 to
be workspace agnostic
2025-12-11 14:50:56 +01:00
Guillim b83dc3aaff TimelineActivity migration to morph (#15652)
# TimelineActivity migration to morph


- Creates `timelineActivities2` relations on Company, Dashboard, Note,
Opportunity, Person, Task, Workflow, WorkflowRun, and WorkflowVersion
entities with proper metadata and cascade delete behavior.

It was required to create standard fields as well since the
mapObjectMetadataByUniqueIdentifier needs it. otherwise the fields won't
be considered

- Feature Flag `IS_TIMELINE_ACTIVITY_MIGRATED` necessary to have the two
states in parallel. It is used as a stamp once the migration has been
run

- Migration is done using the coreDataSource. Why ?
even though is unsafe to use, the first implementation of the migration
took forever on each workspace. See [this
commit](https://github.com/twentyhq/twenty/pull/15652/commits/477011e8d7d4c580f79ba7ec4a8fb002a3ec86b2)

The plan for this complex migration is as follows :

![plan](https://github.com/user-attachments/assets/51c63ea6-fb0d-40b4-b99d-3e0b35a204e6)
Note: we will need to rename fields in the release 1.12 (there is no
easy way to do all this in one release)
2025-12-11 14:28:26 +01:00
Raphaël Bosi 5af2d37253 [DASHBOARDS] Dashboard duplication (#16291)
## Description

- Created a Dashboard duplication action
- Created a new duplication custom resolver
- Created the service using the v2 of the API
- Created the integration tests following the v2 methodology

## Video QA


https://github.com/user-attachments/assets/e409951a-5946-4da0-91a0-1f7d2ecadb08
2025-12-11 11:15:15 +00:00
Félix Malfait bc57b8ee4e feat(ai): add browsing context and fix tool loading (#16476)
## Summary

- Add `BrowsingContext` type to automatically pass what the user is
currently viewing (recordPage or listView) to the AI chat
- Simplify context architecture: remove toggleable context UI, make it
automatic and invisible to the user
- Fix tool loading: add `unionOf` handling in
`getDatabaseToolsForObject` and fix regex ordering so `find_one_*` tools
are properly registered
- Use plural names for find tools (`find_people` vs `find_one_person`)
for better semantics
- Clean up unused components and states

## Changes

### Frontend
- New `BrowsingContext` type and `useGetBrowsingContext` hook to gather
context from Recoil state
- Simplified `useAgentChat` to use the new browsing context
- Removed toggleable context UI components
(`AgentChatContextRecordPreview`, `SendMessageWithRecordsContextButton`,
etc.)
- Removed `isAgentChatCurrentContextActiveState`

### Backend
- New `BrowsingContextType` for recordPage and listView contexts
- Updated `ChatExecutionService` to build context from browsing context
- Fixed `tool-registry.service.ts`:
  - Added `unionOf` handling in permission config
- Fixed regex ordering (`find_one` before `find`) so tools load
correctly
- Use plural names for search tools (`find_people` instead of
`find_person`)

## Test plan

- [x] Typecheck passes
- [x] Lint passes
- [ ] Test AI chat on record page - should show context in system prompt
- [ ] Test AI chat on list view - should show view name and filters
- [ ] Test `find_one_*` tools now load correctly
- [ ] Test `find_*` tools use plural naming
2025-12-11 10:19:27 +01:00