Adds intelligent routing system that automatically selects the best
agent for user queries based on conversation context.
### Changes:
- Added `routerModel` column to workspace table for configurable router
LLM selection
- Implemented `RouterService` with conversation history analysis and
agent matching logic
- Created router settings UI in AI Settings page with model dropdown
- Removed agent-specific thread associations - threads are now
agent-agnostic
- Added real-time routing status notification in chat UI with shimmer
effect
- Removed automatic default assistant agent creation
- Renamed GraphQL operations from agent-specific to generic (e.g.,
`agentChatThreads` → `chatThreads`)
---------
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Several fixes after discussing with @BOHEUS
- set applicationManifest env key optional
- fix server local serverless function logging (introduces a new env
variable `SERVERLESS_LOGS_ENABLED` defaulting to false)
resolve#13253
This PR enables the use of Google Place Autocomplete and Place Details
APIs in the backend. It allows users to automatically fill in address
fields by typing into the address1 input. The input is debounced, then
the Autocomplete API is called. Once the user selects an address, the
Place Details API is used to parse and fill in the individual address
fields.
https://github.com/user-attachments/assets/e04b8474-25b8-48f5-83d0-2074f8d5fc94
---------
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Implementation is very simple
Established authentication dynamic is intercepted at
getAuthTokensFromLoginToken. If 2FA is required, a pattern similar to
EmailVerification is executed. That is, getAuthTokensFromLoginToken
mutation fails with either of the following errors:
1. TWO_FACTOR_AUTHENTICATION_VERIFICATION_REQUIRED
2. TWO_FACTOR_AUTHENTICATION_PROVISION_REQUIRED
UI knows how to respond accordingly.
2FA provisioning occurs at the 2FA resolver.
2FA verification, currently only OTP, is handled by auth.resolver's
getAuthTokensFromOTP
---------
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Jean-Baptiste Ronssin <65334819+jbronssin@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Instead of initializing model at start time we do it at run time to be
able to swap model provider more easily.
Also introduce a third driver for openai-compatible providers, which
among other allows for local models with Ollama
### Added IMAP integration
This PR adds support for connecting email accounts via IMAP protocol,
allowing users to sync their emails without OAuth.
#### DB Changes:
- Added customConnectionParams and connectionType fields to
ConnectedAccountWorkspaceEntity
#### UI:
- Added settings pages for creating and editing IMAP connections with
proper validation and connection testing.
- Implemented reconnection flows for handling permission issues.
#### Backend:
- Built ImapConnectionModule with corresponding resolver and service for
managing IMAP connections.
- Created MessagingIMAPDriverModule to handle IMAP client operations,
message fetching/parsing, and error handling.
#### Dependencies:
Integrated `imapflow` and `mailparser` libraries with their type
definitions to handle the IMAP protocol communication.
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
## Context
Support button was missing for configuration having support enabled
(FrontApp)
<img width="1253" alt="image"
src="https://github.com/user-attachments/assets/930e3e0c-05a1-4a5b-820b-bb257f19fdde"
/>
## How
Recently, we changed some enums from lowercase to uppercase in graphql
## Problem resolution
supportDriver was typed as a string where we could have used
SupportDriver type. I'm exposing it in the graphql generated files to
re-use in the front so this issue cannot happen anymore
### Primary Changes: Dynamic Driver Configuration
Refactors FileStorageService and EmailSenderService to support dynamic
driver configuration changes at runtime without requiring application
restarts.
**Key Architectural Change**: Instead of conditionally registering
drivers at build time based on configuration, we now **register all
possible drivers eagerly** and select the appropriate one at runtime.
### What Changed:
- **Before**: Modules conditionally registered only the configured
driver (e.g., only S3Driver if STORAGE_TYPE=S3)
- **After**: All drivers (LocalDriver, S3Driver, SmtpDriver,
LoggerDriver) are registered at startup
- **Runtime Selection**: Services dynamically choose and instantiate the
correct driver based on current configuration
### Secondary Fix: Integration Test Log Cleanup
Addresses ConfigStorageService error logs appearing in integration test
output by using injected LoggerService for consistent log handling.
This PR implements a global PostgreSQL connection pool sharing
mechanism.
- Patches pg.Pool to reuse connection pools across the application when
connection parameters match, reducing resource overhead.
- New environment variables allow enabling/disabling sharing and
configuring pool size, idle timeout, and client exit behavior.
WorkspaceDatasourceFactory will now use shared pools if enabled, this
will avoid recreating 10 connections for each pods for each workspace.
---------
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
# Introduction
Added a no-explicit-any rule to the twenty-server, not applicable to
tests and integration tests folder
Related to https://github.com/twentyhq/core-team-issues/issues/975
Discussed with Charles
## In case of conflicts
Until this is approved I won't rebased and handle conflict, just need to
drop two latest commits and re run the scripts etc
## Legacy
We decided not to handle the existing lint error occurrences and
programmatically ignored them through a disable next line rule comment
## Open question
We might wanna activate the
[no-explicit-any](https://typescript-eslint.io/rules/no-explicit-any/)
`ignoreRestArgs` for our use case ?
```
ignoreRestArgs?: boolean;
```
---------
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
Fixes https://github.com/twentyhq/twenty/issues/12040
When fields are deleted but still used in workflows we do not update
create record action settings.
It breaks all following workflow execution and the user cannot update
the settings anymore.
This PR fixes the bug by filtering on existing fields.
Next step will be to clean settings on field deletion. Adding it to fast
follows.
Also lowering throttle limit because some infinite loops are not
catched.
This PR attemps at improving sentry grouping and filtering by
- Using the exceptionCode as the fingerprint when the error is a
customException. For this to work in this PR we are now throwing
customExceptions instead of internalServerError deprived of their code.
They will still be converted to Internal server errors when sent back as
response
- Filtering 4xx issues where it was missing (for emailVerification
because errors were not handled, for invalid captcha and billing errors
because they are httpErrors and not graphqlErrors)
---------
Co-authored-by: Félix Malfait <felix@twenty.com>
- In this PR the default value of IS_CONFIG_VARIABLES_IN_DB_ENABLED has
been changed to true,
- This is my first time writing integration tests, so I’d appreciate a
thorough review. :)
I’ve tried to follow the existing test patterns closely, but there might
be some small mistakes I may have missed.
Also let me know if I have missed any important test cases that should
be tested
UPDATE -
### Config Value Converter Refactoring
- Created a centralized type transformers registry with bidirectional
validation
- Refactored ConfigValueConverterService to support validation in both
directions:
- Maintained existing DB-to-app conversion behavior
- Added validation for app-to-DB conversion
- Added integration tests to verify validation works in both directions
---------
Co-authored-by: Félix Malfait <felix@twenty.com>
No need to audit log workflow runs as it's already a form of audit log.
Add more audit log for other objects
Rename MessagingTelemetry to MessagingMonitoring
Merge Analytics and Audit in one (Audit)
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Let's deprecate Sentry Release and use APP_VERSION instead.
It'll make it more clear in the interface to use named version for bug
analysis, than commit sha
In this PR :
- set billing thresholds after subscription creation (not possible
during billing checkout)
- add specific free trial workflow credit quantities + set them in
subscription item + check them when receiving stripe alert event
closes : https://github.com/twentyhq/core-team-issues/issues/682