This PR fixes https://github.com/twentyhq/twenty/issues/16165.
The bug was due to a wrong initialization of a record filter, which was
using another object metadata item than the filtered one.
As we can see in the original issue :
```
...
"fieldMetadataId": "f12697bf-1eba-4061-bdd4-3e8a81172b79"
...
"fieldMetadataId": "658c531c-0c2e-43a1-8f70-4d6266c3841f",
...
```
The fix was to update the hook that returned the default field metadata
item to use for a new filter, and force the caller to tell which object
metadata item to use.
# **feat: Add tooltips for truncated names in navigation components**
### **Summary**
Adds hover tooltips across navigation components so users can view full
names when text is truncated due to limited space.
---
# **Changes Made**
### **Sidebar Navigation**
* Added tooltips to navigation drawer items and menu labels.
* Long workspace or company names now show full text on hover.
### **Top Bar**
* Added tooltip support to the View Picker dropdown header.
* Long view names (e.g., *“AuraML, very very long name”*) now reveal
their full value on hover.
---
# **Implementation**
* Integrated `OverflowingTextWithTooltip` from `twenty-ui/display`.
* Wrapped navigation and view labels with the component.
* Updated layout styles to allow accurate overflow detection.
* Tooltip appears **only** when truncation occurs; short names show no
tooltip.
---
# **User Experience**
Users can hover over any truncated workspace, company, navigation, or
view name to see the complete text—improving clarity, accessibility, and
overall navigation usability.
[https://github.com/user-attachments/assets/97f9ea6c-409c-4ec5-a27c-a7b1c5aa5682](https://github.com/user-attachments/assets/97f9ea6c-409c-4ec5-a27c-a7b1c5aa5682)
---
### **Fixes**
Closes **#16412**
---
---------
Co-authored-by: Devessier <baptiste@devessier.fr>
## Context
SyncMetadata for role update was broken when those roles had permission
flags in them.
This PR https://github.com/twentyhq/twenty/issues/16365 introduced a
change in all existing standard roles which probably triggered the
update of faulty roles for the first time. Down the line, some
properties from flat were not omit before querying the DB (in this case
permissionFlagIds does not exist as a column in role table)
The fix is definitely not great, this also probably broke the update of
permissionFlags for existing STANDARD roles but it's not subject to
change (It actually never changed. Again, what has been updated was not
the permission flag but a new boolean introduced 2 days ago which forced
the "UPDATE" path in the sync which was probably never triggered before,
or at least not for roles with permission flags which are "quite" new).
Also we are about to remove this whole code in favor of the new
migration v2
# Introduction
Early returning in `validateBuildAndRun` as the runner even if passed an
empty workspace migration actions array be invalidating dependency
related flat entity maps.
When we will refactor the runner to consume the generic flat entity maps
tools such as
`addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow` we
will be able to remove the dependency cache invalidation
## Summary
This PR significantly simplifies the AI chat architecture by removing
complex routing/planning mechanisms and introduces clickable record
links in AI responses.
## Changes
### AI Chat Architecture Simplification
- **Removed** the entire `ai-chat-router` module (~850 lines) including:
- Strategy decider service
- Plan generator service
- Complex routing logic
- **Removed** agent execution planning services (~700 lines):
- `agent-execution.service.ts`
- `agent-plan-executor.service.ts`
- `agent-tool-generator.service.ts`
- **Added** centralized `ToolRegistryService` for tool management:
- Builds searchable tool index (database, action, workflow tools)
- Provides tool lookup by name
- Supports agent search for loading expertise
- **Added** `ChatExecutionService` as simple replacement:
- Includes full tool catalog in system prompt
- Pre-loads common tools (find/create/update for company, person,
opportunity, task, note)
- Uses `load_tools` mechanism for dynamic tool activation
- Enables native web search by default
### Record References in AI Responses
- Added `recordReferences` field to tool outputs for create, find, and
update operations
- Implemented `[[record:objectName:recordId:displayName]]` syntax for AI
to reference records
- Created `RecordLink` component that renders clickable chips with
object icons
- Integrated record link parsing into the markdown renderer
- Users can now click directly on created/found records in AI responses
### Workflow Agent Fixes
- Fixed cache invalidation issue when creating agents in workflows
- Added default prompt for workflow-created agents to prevent validation
errors
- Relaxed agent validation to only check properties being updated (not
all required properties)
### Code Quality Improvements
- Extracted `getRecordDisplayName` utility that mirrors frontend's
`getLabelIdentifierFieldValue` logic
- Uses object metadata to determine the correct label identifier field
- Handles `FULL_NAME` composite type for person/workspaceMember objects
- Shared across create, find, and update record services
## Net Impact
- **~1,200 lines deleted** (complex routing/planning code)
- **~500 lines added** (simpler tool registry + record links)
- Significantly reduced code complexity
- Better tool discovery through full catalog in system prompt
- Improved UX with clickable record references
## Testing
- Typecheck passes
- Lint passes
- Manual testing of AI chat with record creation and linking
Closes#16432
Multi-Select and Array fields were exported in an incompatible format:
**Before**: {"0":"VALUE1","1":"VALUE2"} (object with numeric keys)
**After**: ["VALUE1","VALUE2"] (JSON array)
This prevented exported CSV files from being re-imported successfully.
### Changes
Modified useExportProcessRecordsForCSV hook to stringify Multi-Select
and Array fields as JSON arrays before CSV generation
---------
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
# Introduction
In this PR we've introduced the type safe generation tooling for
standard view, view fields, view filters and view groups.
Also generated the ids before such as what was done for object and
fields, it's still temporary as will be replaced by universalIdentifier
mapping afterwards
## Task views
In this PR only implemented the `task` views and view groups, filters
and fields in order to battle test all the generation tools
Will create a dedicated PR that will implement all the remaining views.
Log introduced in https://github.com/twentyhq/twenty/pull/16389
However this is a util hence cannot simply inject the logger service.
I'm removing the log for now as adding loggerService as a parameter of a
util might not be the right solution (yet)
```typescript
this.logger.warn(`Field metadata for field "${key}" is missing in object metadata ${flatObjectMetadata.nameSingular} for data: ${JSON.stringify(data)}`);
^
TypeError: Cannot read properties of undefined (reading 'logger')
```
- The issue is that the listener is not triggered if they are no change
to the workspaceMember (which happens when name is already filled
through GoogleSSO)
Fixes https://github.com/twentyhq/twenty/issues/16440
This is a known quirk of many Google APIs, including Gmail. Some error
responses use numeric code fields (e.g., 403), while others may return
them as strings (e.g., "403"). This depends on which internal service
returns the error and the language client you’re using.
Changes:
- as we store date in redis as serialized, let's make all flatEntity
dates as string. This requires changing FlatEntity types and making sure
that entity are converted to flatEntity and flatEntity to dtos
# Introduction
Related https://github.com/twentyhq/core-team-issues/issues/1995
In this PR we're introducing the standard index tools for their
declaration
Also adding a common typing in order to have a simily consistency across
standard builders
Will implement remaining standard index builder in an other PR
Issue : #15794
## Context
As shown in the linked issue, slash menu dropdown for rich text editor
at bottom of notes editor screen extended beyond the page container,
causing main page to scroll.
## Changes Made
Added floating UI's `flip()` middleware to the component in
`CustomSlashMenu.tsx` so that the menu automatically flips upward when
detecting not enough space for dropdown. This prevents overflow beyond
the page container.
Additionally, added offset to menu when flipping up to prevent
overlapping of the current line / caret.
## Results
https://github.com/user-attachments/assets/47a79468-779c-4fd7-8e22-2b496456ea92
---------
Co-authored-by: Hyeonjae Park <hyeonjaep@Hyeonjaes-MacBook-Pro.local>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Fixes
- Fixes https://github.com/twentyhq/twenty/issues/15640 : we have some
viewGroups that were in the past wrongly migrated; eg deleteing an
enum's option did not lead to deleting the associated viewGroup. We have
not cleaned that (we could do a command), but we can identify them and
choose not to display them - otherwise currently they are shown as a
duplicate of "No value" column
- Fixes buggy edge case introduced by
https://github.com/twentyhq/twenty/pull/16382 : after updating a view
from Table/Calendar to Kanban, then visiting another view, when coming
back to the newly updated kanban view the view groups were empty. This
is due to to the view groups being optimistically created with
on-the-fly computed ids when the view is updated, while we call
refreshCoreViewsByObjectMetadataId() after. The view groups we get from
the refresh obviously have different ids. It is not possible to indicate
the ids of the view group through the update of the view as they are a
side effect of the view update.
# Fireflies
Automatically (with cli util : webhook not working and no cron added)
captures meeting notes with AI-generated summaries and insights from
Fireflies.ai into your Twenty CRM.
## Current Status
- Doesn't work with Fireflies webhook yet due to missing headers
forwarding in twenty serverless func
- Meeting ingestion utility script are available for individual meeting
insertion and historical meetings with filters with yarn meeting:all
- You have to push the secrets as application.config.ts values (despite
env variables in .env in docker compose or container I couldn't push the
secrets with the cli)
## Current Platform Limitation (Headers)
- Twenty serverless route triggers currently do **not forward HTTP
headers** to functions. Fireflies signatures sent in headers are
stripped, so header-based verification does not work in production.
- Workaround: the provided test script also includes the signature
inside the payload; the handler falls back to that payload signature.
Use this only for testing until header forwarding is supported.
## Utilities for meeting insertion (workarounds)
- Ingest a specific Fireflies meeting into Twenty:
`yarn meeting:ingest <meetingId>` or `MEETING_ID=... yarn
meeting:ingest`
- Fetch all/historical Fireflies meetings into Twenty:
`yarn meeting:all [--from 2024-01-01] [--to 2024-02-01] [--organizer
a@x.com] [--participant b@x.com] [--channel <channelId>] [--mine]
[--dry-run]`
- Filters (combine as needed):
- `--from` / `--to`: ISO or date string range filter
- `--organizer` / `--participant`: comma-separated emails
- `--channel`: Fireflies channel id
- `--mine`: only meetings for the current Fireflies user
- Controls:
- `--dry-run`: list and transform without writing to Twenty
- `--page-size`: pagination size (default 50)
- `--max-records`: stop after N transcripts (default 500)
I am closing previous #16378 as this one includes it all
Fixes multiple issues with CRON schedule input validation and execution
time display.
### Issues Fixed
1. **UTC label placement** - Added "UTC" suffix to specific times (e.g.,
"at 09:30 UTC") but not to interval descriptions (e.g., "every hour")
2. **Upcoming execution time calculation** - Fixed incorrect execution
times for malformed CRON expressions by implementing auto-correction
### Changes
- Created `normalizeCronExpression` utility to standardize cron
expressions before parsing
- Updated `formatTime` to support optional UTC suffix
- Enhanced `getHoursDescription` to append UTC to specific times
- Added comprehensive test coverage (102 tests passing)
### Before
- `"1 /3 * * *"` showed daily executions at same time (incorrect)
- `"9 * * *"` showed same time repeated 3 times (incorrect)
- No UTC labels on schedule descriptions (confusing)
### After
- All malformed expressions auto-corrected and show correct execution
times
- UTC labels clearly indicate timezone for specific times
- User-friendly error messages for truly invalid patterns
Closes#15870
Fixes https://github.com/twentyhq/twenty/issues/15925
- update field metadata update logic
- uniformize the way index are named
- command to migrate v1-named unique index
- add integration testing
---------
Co-authored-by: prastoin <paul@twenty.com>
Fixes: #15887
The currency fields were expecting values in micros (multiplied by
10^6), but
this requirement was not indicated anywhere in the workflow UI. Users
had to
manually add a code node to multiply amounts by 10^6 before using the
new
currency value.
This change integrates the micros conversion logic directly into
FormCurrencyFieldInput by using convertCurrencyAmountToCurrencyMicros
and
convertCurrencyMicrosToCurrencyAmount utilities. This allows users to
input
human-readable decimal amounts (e.g., 3.21 for $3.21) in the form, which
are
automatically converted to micros internally for storage and processing.
This eliminates the need for users to add separate code nodes for
conversion
and improves the user experience by making the expected input format
clear.