refactor: standardize AI acronym to Ai (PascalCase) across internal identifiers (#19837)

## Summary

The "AI" acronym was rendered inconsistently across the codebase. The
backend AI module had settled on PascalCase `Ai` (`AiAgentModule`,
`AiBillingService`, `AiChatModule`, `AiModelRegistryService`, etc.),
while frontend components, several DTOs, a few types, and shared
identifiers still used all-caps `AI` (`AIChatTab`,
`AISystemPromptPreviewDTO`, `SettingsPath.AIPrompts`, ...). CLAUDE.md
specifies PascalCase for classes; this PR normalizes everything internal
to `Ai`.

**This is a pure internal rename.** The GraphQL schema is untouched —
`@ObjectType` decorator string arguments, resolver method names (which
become Query/Mutation field names), gql template contents, and the
`generated-metadata/graphql.ts` file are preserved verbatim. The only
visible change is TypeScript identifiers and file names.

## Also folded in (adjacent cleanups)

- **`AgentModelConfigService` → `AiModelConfigService`**. Lives in
`ai-models/` and is used by multiple AI code paths, not just the Agent
entity. The "Agent" prefix was misleading.
- **`generate-text-input.dto.ts` → `generate-text.input.ts`**. The
`ai-agent/dtos/` folder already uses `<entity>.input.ts` convention for
Input classes (`create-agent.input.ts` etc.); the old path mixed
`.dto.ts` file extension with a class that has no DTO suffix. File
rename only; class stays `GenerateTextInput`.
- **Removed stale TODO** in `ai-model-config.type.ts` that asked for the
`AiModelConfig` rename that this PR performs.

## Rename methodology

Bulk rename via perl with anchored regex
`(?<!['"])(?<![A-Z.])AI([A-Z])(?=[a-z])/Ai$1/g`:

- **Lookbehind for non-uppercase** skips adjacent acronyms (`MOSAIC`,
`OIDCSSO`) and leaves `AIRBNB_ID` alone.
- **Lookbehind for non-quote** protects most string literals.
- **Lookahead for lowercase** restricts matches to PascalCase
identifiers (`AIChatTab`), leaving SCREAMING_SNAKE constants untouched.

Strict file-scope exclusions: `generated-metadata/**`, `generated/**`,
`locales/**`, `migrations/**`, `illustrations/**`, `halftone/**`, and
the two gql template files (`queries/getAISystemPromptPreview.ts`,
`mutations/uploadAIChatFile.ts`).

Post-rename reverts for identifiers where the regex was too eager:
- Backend resolver method names kept: `getAISystemPromptPreview`,
`uploadAIChatFile` (they are GraphQL field names).
- `@ObjectType('AdminAIModels')` / `('AISystemPromptPreview')` /
`('AISystemPromptSection')` kept as-is.
- Backend classes `ClientAIModelConfig` / `AdminAIModelConfig` kept
as-is (they use `@ObjectType()` with no argument, so the class name IS
the schema name).
- External-library symbols restored: `OpenAIProvider`,
`createOpenAICompatible`, `vercelAIIntegration`.

File renames use a two-step rename to work on macOS case-insensitive
filesystems: `git mv X.tsx X.tsx.tmp && git mv X.tsx.tmp renamed.tsx`.

## Diff audit

- 0 changes to migrations
- 0 changes to locale `.po` / `.ts` files
- 0 changes to `generated-metadata/graphql.ts`
- 0 changes to website illustration files (base64 blobs preserved)
- 0 renames inside user-facing translation strings (`t\`…\``,
`msg\`…\``, `<Trans>…</Trans>`)

## Test plan

- [x] `npx nx typecheck twenty-server` — PASS
- [x] `npx nx typecheck twenty-front` — PASS
- [x] `npx jest ai-model admin agent-role` — 79/79 PASS
- [x] `npx oxlint --type-aware` on 118 changed files — 0 errors
- [x] `npx prettier --check` on 118 changed files — clean
- [ ] CI
This commit is contained in:
Félix Malfait
2026-04-19 13:29:35 +02:00
committed by GitHub
parent 1e27c3b621
commit 6117a1d6c0
126 changed files with 629 additions and 630 deletions
@@ -1743,7 +1743,7 @@ type NativeModelCapabilities {
twitterSearch: Boolean
}
type ClientAIModelConfig {
type ClientAiModelConfig {
modelId: String!
label: String!
modelFamily: ModelFamily
@@ -1769,7 +1769,7 @@ enum ModelFamily {
GROK
}
type AdminAIModelConfig {
type AdminAiModelConfig {
modelId: String!
label: String!
modelFamily: ModelFamily
@@ -1789,8 +1789,8 @@ type AdminAIModelConfig {
dataResidency: String
}
type AdminAIModels {
models: [AdminAIModelConfig!]!
type AdminAiModels {
models: [AdminAiModelConfig!]!
defaultSmartModelId: String
defaultFastModelId: String
}
@@ -1852,7 +1852,7 @@ type ClientConfig {
appVersion: String
authProviders: AuthProviders!
billing: Billing!
aiModels: [ClientAIModelConfig!]!
aiModels: [ClientAiModelConfig!]!
signInPrefilled: Boolean!
isMultiWorkspaceEnabled: Boolean!
isEmailVerificationRequired: Boolean!
@@ -2957,14 +2957,14 @@ type AgentMessage {
createdAt: DateTime!
}
type AISystemPromptSection {
type AiSystemPromptSection {
title: String!
content: String!
estimatedTokenCount: Int!
}
type AISystemPromptPreview {
sections: [AISystemPromptSection!]!
type AiSystemPromptPreview {
sections: [AiSystemPromptSection!]!
estimatedTokenCount: Int!
}
@@ -3319,7 +3319,7 @@ type Query {
chatThread(id: UUID!): AgentChatThread!
chatMessages(threadId: UUID!): [AgentMessage!]!
chatStreamCatchupChunks(threadId: UUID!): ChatStreamCatchupChunks!
getAISystemPromptPreview: AISystemPromptPreview!
getAiSystemPromptPreview: AiSystemPromptPreview!
skills: [Skill!]!
skill(id: UUID!): Skill
chatThreads(
@@ -3364,7 +3364,7 @@ type Query {
getIndicatorHealthStatus(indicatorId: HealthIndicatorId!): AdminPanelHealthServiceData!
getQueueMetrics(queueName: String!, timeRange: QueueMetricsTimeRange = OneHour): QueueMetricsData!
versionInfo: VersionInfo!
getAdminAiModels: AdminAIModels!
getAdminAiModels: AdminAiModels!
getDatabaseConfigVariable(key: String!): ConfigVariable!
getQueueJobs(queueName: String!, state: JobState!, limit: Int = 50, offset: Int = 0): QueueJobsResponse!
findAllApplicationRegistrations: [ApplicationRegistration!]!
@@ -3519,7 +3519,7 @@ type Mutation {
deleteManyNavigationMenuItems(ids: [UUID!]!): [NavigationMenuItem!]!
deleteNavigationMenuItem(id: UUID!): NavigationMenuItem!
uploadEmailAttachmentFile(file: Upload!): FileWithSignedUrl!
uploadAIChatFile(file: Upload!): FileWithSignedUrl!
uploadAiChatFile(file: Upload!): FileWithSignedUrl!
uploadWorkflowFile(file: Upload!): FileWithSignedUrl!
uploadWorkspaceLogo(file: Upload!): FileWithSignedUrl!
uploadWorkspaceMemberProfilePicture(file: Upload!): FileWithSignedUrl!
@@ -1444,7 +1444,7 @@ export interface NativeModelCapabilities {
__typename: 'NativeModelCapabilities'
}
export interface ClientAIModelConfig {
export interface ClientAiModelConfig {
modelId: Scalars['String']
label: Scalars['String']
modelFamily?: ModelFamily
@@ -1460,12 +1460,12 @@ export interface ClientAIModelConfig {
contextWindowTokens?: Scalars['Float']
maxOutputTokens?: Scalars['Float']
dataResidency?: Scalars['String']
__typename: 'ClientAIModelConfig'
__typename: 'ClientAiModelConfig'
}
export type ModelFamily = 'GPT' | 'CLAUDE' | 'GEMINI' | 'MISTRAL' | 'GROK'
export interface AdminAIModelConfig {
export interface AdminAiModelConfig {
modelId: Scalars['String']
label: Scalars['String']
modelFamily?: ModelFamily
@@ -1483,14 +1483,14 @@ export interface AdminAIModelConfig {
providerLabel?: Scalars['String']
name?: Scalars['String']
dataResidency?: Scalars['String']
__typename: 'AdminAIModelConfig'
__typename: 'AdminAiModelConfig'
}
export interface AdminAIModels {
models: AdminAIModelConfig[]
export interface AdminAiModels {
models: AdminAiModelConfig[]
defaultSmartModelId?: Scalars['String']
defaultFastModelId?: Scalars['String']
__typename: 'AdminAIModels'
__typename: 'AdminAiModels'
}
export interface Billing {
@@ -1552,7 +1552,7 @@ export interface ClientConfig {
appVersion?: Scalars['String']
authProviders: AuthProviders
billing: Billing
aiModels: ClientAIModelConfig[]
aiModels: ClientAiModelConfig[]
signInPrefilled: Scalars['Boolean']
isMultiWorkspaceEnabled: Scalars['Boolean']
isEmailVerificationRequired: Scalars['Boolean']
@@ -2628,17 +2628,17 @@ export interface AgentMessage {
__typename: 'AgentMessage'
}
export interface AISystemPromptSection {
export interface AiSystemPromptSection {
title: Scalars['String']
content: Scalars['String']
estimatedTokenCount: Scalars['Int']
__typename: 'AISystemPromptSection'
__typename: 'AiSystemPromptSection'
}
export interface AISystemPromptPreview {
sections: AISystemPromptSection[]
export interface AiSystemPromptPreview {
sections: AiSystemPromptSection[]
estimatedTokenCount: Scalars['Int']
__typename: 'AISystemPromptPreview'
__typename: 'AiSystemPromptPreview'
}
export interface ChatStreamCatchupChunks {
@@ -2891,7 +2891,7 @@ export interface Query {
chatThread: AgentChatThread
chatMessages: AgentMessage[]
chatStreamCatchupChunks: ChatStreamCatchupChunks
getAISystemPromptPreview: AISystemPromptPreview
getAiSystemPromptPreview: AiSystemPromptPreview
skills: Skill[]
skill?: Skill
chatThreads: AgentChatThreadConnection
@@ -2927,7 +2927,7 @@ export interface Query {
getIndicatorHealthStatus: AdminPanelHealthServiceData
getQueueMetrics: QueueMetricsData
versionInfo: VersionInfo
getAdminAiModels: AdminAIModels
getAdminAiModels: AdminAiModels
getDatabaseConfigVariable: ConfigVariable
getQueueJobs: QueueJobsResponse
findAllApplicationRegistrations: ApplicationRegistration[]
@@ -2975,7 +2975,7 @@ export interface Mutation {
deleteManyNavigationMenuItems: NavigationMenuItem[]
deleteNavigationMenuItem: NavigationMenuItem
uploadEmailAttachmentFile: FileWithSignedUrl
uploadAIChatFile: FileWithSignedUrl
uploadAiChatFile: FileWithSignedUrl
uploadWorkflowFile: FileWithSignedUrl
uploadWorkspaceLogo: FileWithSignedUrl
uploadWorkspaceMemberProfilePicture: FileWithSignedUrl
@@ -4706,7 +4706,7 @@ export interface NativeModelCapabilitiesGenqlSelection{
__scalar?: boolean | number
}
export interface ClientAIModelConfigGenqlSelection{
export interface ClientAiModelConfigGenqlSelection{
modelId?: boolean | number
label?: boolean | number
modelFamily?: boolean | number
@@ -4726,7 +4726,7 @@ export interface ClientAIModelConfigGenqlSelection{
__scalar?: boolean | number
}
export interface AdminAIModelConfigGenqlSelection{
export interface AdminAiModelConfigGenqlSelection{
modelId?: boolean | number
label?: boolean | number
modelFamily?: boolean | number
@@ -4748,8 +4748,8 @@ export interface AdminAIModelConfigGenqlSelection{
__scalar?: boolean | number
}
export interface AdminAIModelsGenqlSelection{
models?: AdminAIModelConfigGenqlSelection
export interface AdminAiModelsGenqlSelection{
models?: AdminAiModelConfigGenqlSelection
defaultSmartModelId?: boolean | number
defaultFastModelId?: boolean | number
__typename?: boolean | number
@@ -4819,7 +4819,7 @@ export interface ClientConfigGenqlSelection{
appVersion?: boolean | number
authProviders?: AuthProvidersGenqlSelection
billing?: BillingGenqlSelection
aiModels?: ClientAIModelConfigGenqlSelection
aiModels?: ClientAiModelConfigGenqlSelection
signInPrefilled?: boolean | number
isMultiWorkspaceEnabled?: boolean | number
isEmailVerificationRequired?: boolean | number
@@ -5993,7 +5993,7 @@ export interface AgentMessageGenqlSelection{
__scalar?: boolean | number
}
export interface AISystemPromptSectionGenqlSelection{
export interface AiSystemPromptSectionGenqlSelection{
title?: boolean | number
content?: boolean | number
estimatedTokenCount?: boolean | number
@@ -6001,8 +6001,8 @@ export interface AISystemPromptSectionGenqlSelection{
__scalar?: boolean | number
}
export interface AISystemPromptPreviewGenqlSelection{
sections?: AISystemPromptSectionGenqlSelection
export interface AiSystemPromptPreviewGenqlSelection{
sections?: AiSystemPromptSectionGenqlSelection
estimatedTokenCount?: boolean | number
__typename?: boolean | number
__scalar?: boolean | number
@@ -6265,7 +6265,7 @@ export interface QueryGenqlSelection{
chatThread?: (AgentChatThreadGenqlSelection & { __args: {id: Scalars['UUID']} })
chatMessages?: (AgentMessageGenqlSelection & { __args: {threadId: Scalars['UUID']} })
chatStreamCatchupChunks?: (ChatStreamCatchupChunksGenqlSelection & { __args: {threadId: Scalars['UUID']} })
getAISystemPromptPreview?: AISystemPromptPreviewGenqlSelection
getAiSystemPromptPreview?: AiSystemPromptPreviewGenqlSelection
skills?: SkillGenqlSelection
skill?: (SkillGenqlSelection & { __args: {id: Scalars['UUID']} })
chatThreads?: (AgentChatThreadConnectionGenqlSelection & { __args: {
@@ -6307,7 +6307,7 @@ export interface QueryGenqlSelection{
getIndicatorHealthStatus?: (AdminPanelHealthServiceDataGenqlSelection & { __args: {indicatorId: HealthIndicatorId} })
getQueueMetrics?: (QueueMetricsDataGenqlSelection & { __args: {queueName: Scalars['String'], timeRange?: (QueueMetricsTimeRange | null)} })
versionInfo?: VersionInfoGenqlSelection
getAdminAiModels?: AdminAIModelsGenqlSelection
getAdminAiModels?: AdminAiModelsGenqlSelection
getDatabaseConfigVariable?: (ConfigVariableGenqlSelection & { __args: {key: Scalars['String']} })
getQueueJobs?: (QueueJobsResponseGenqlSelection & { __args: {queueName: Scalars['String'], state: JobState, limit?: (Scalars['Int'] | null), offset?: (Scalars['Int'] | null)} })
findAllApplicationRegistrations?: ApplicationRegistrationGenqlSelection
@@ -6374,7 +6374,7 @@ export interface MutationGenqlSelection{
deleteManyNavigationMenuItems?: (NavigationMenuItemGenqlSelection & { __args: {ids: Scalars['UUID'][]} })
deleteNavigationMenuItem?: (NavigationMenuItemGenqlSelection & { __args: {id: Scalars['UUID']} })
uploadEmailAttachmentFile?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload']} })
uploadAIChatFile?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload']} })
uploadAiChatFile?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload']} })
uploadWorkflowFile?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload']} })
uploadWorkspaceLogo?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload']} })
uploadWorkspaceMemberProfilePicture?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload']} })
@@ -7887,26 +7887,26 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
const ClientAIModelConfig_possibleTypes: string[] = ['ClientAIModelConfig']
export const isClientAIModelConfig = (obj?: { __typename?: any } | null): obj is ClientAIModelConfig => {
if (!obj?.__typename) throw new Error('__typename is missing in "isClientAIModelConfig"')
return ClientAIModelConfig_possibleTypes.includes(obj.__typename)
const ClientAiModelConfig_possibleTypes: string[] = ['ClientAiModelConfig']
export const isClientAiModelConfig = (obj?: { __typename?: any } | null): obj is ClientAiModelConfig => {
if (!obj?.__typename) throw new Error('__typename is missing in "isClientAiModelConfig"')
return ClientAiModelConfig_possibleTypes.includes(obj.__typename)
}
const AdminAIModelConfig_possibleTypes: string[] = ['AdminAIModelConfig']
export const isAdminAIModelConfig = (obj?: { __typename?: any } | null): obj is AdminAIModelConfig => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAdminAIModelConfig"')
return AdminAIModelConfig_possibleTypes.includes(obj.__typename)
const AdminAiModelConfig_possibleTypes: string[] = ['AdminAiModelConfig']
export const isAdminAiModelConfig = (obj?: { __typename?: any } | null): obj is AdminAiModelConfig => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAdminAiModelConfig"')
return AdminAiModelConfig_possibleTypes.includes(obj.__typename)
}
const AdminAIModels_possibleTypes: string[] = ['AdminAIModels']
export const isAdminAIModels = (obj?: { __typename?: any } | null): obj is AdminAIModels => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAdminAIModels"')
return AdminAIModels_possibleTypes.includes(obj.__typename)
const AdminAiModels_possibleTypes: string[] = ['AdminAiModels']
export const isAdminAiModels = (obj?: { __typename?: any } | null): obj is AdminAiModels => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAdminAiModels"')
return AdminAiModels_possibleTypes.includes(obj.__typename)
}
@@ -8975,18 +8975,18 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
const AISystemPromptSection_possibleTypes: string[] = ['AISystemPromptSection']
export const isAISystemPromptSection = (obj?: { __typename?: any } | null): obj is AISystemPromptSection => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAISystemPromptSection"')
return AISystemPromptSection_possibleTypes.includes(obj.__typename)
const AiSystemPromptSection_possibleTypes: string[] = ['AiSystemPromptSection']
export const isAiSystemPromptSection = (obj?: { __typename?: any } | null): obj is AiSystemPromptSection => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAiSystemPromptSection"')
return AiSystemPromptSection_possibleTypes.includes(obj.__typename)
}
const AISystemPromptPreview_possibleTypes: string[] = ['AISystemPromptPreview']
export const isAISystemPromptPreview = (obj?: { __typename?: any } | null): obj is AISystemPromptPreview => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAISystemPromptPreview"')
return AISystemPromptPreview_possibleTypes.includes(obj.__typename)
const AiSystemPromptPreview_possibleTypes: string[] = ['AiSystemPromptPreview']
export const isAiSystemPromptPreview = (obj?: { __typename?: any } | null): obj is AiSystemPromptPreview => {
if (!obj?.__typename) throw new Error('__typename is missing in "isAiSystemPromptPreview"')
return AiSystemPromptPreview_possibleTypes.includes(obj.__typename)
}
@@ -3506,7 +3506,7 @@ export default {
1
]
},
"ClientAIModelConfig": {
"ClientAiModelConfig": {
"modelId": [
1
],
@@ -3557,7 +3557,7 @@ export default {
]
},
"ModelFamily": {},
"AdminAIModelConfig": {
"AdminAiModelConfig": {
"modelId": [
1
],
@@ -3613,7 +3613,7 @@ export default {
1
]
},
"AdminAIModels": {
"AdminAiModels": {
"models": [
181
],
@@ -5936,7 +5936,7 @@ export default {
1
]
},
"AISystemPromptSection": {
"AiSystemPromptSection": {
"title": [
1
],
@@ -5950,7 +5950,7 @@ export default {
1
]
},
"AISystemPromptPreview": {
"AiSystemPromptPreview": {
"sections": [
331
],
@@ -6810,7 +6810,7 @@ export default {
]
}
],
"getAISystemPromptPreview": [
"getAiSystemPromptPreview": [
332
],
"skills": [
@@ -7544,7 +7544,7 @@ export default {
]
}
],
"uploadAIChatFile": [
"uploadAiChatFile": [
118,
{
"file": [
@@ -19,19 +19,6 @@ export type Scalars = {
Upload: any;
};
export type AiSystemPromptPreview = {
__typename?: 'AISystemPromptPreview';
estimatedTokenCount: Scalars['Int'];
sections: Array<AiSystemPromptSection>;
};
export type AiSystemPromptSection = {
__typename?: 'AISystemPromptSection';
content: Scalars['String'];
estimatedTokenCount: Scalars['Int'];
title: Scalars['String'];
};
export type ActivateWorkspaceInput = {
displayName?: InputMaybe<Scalars['String']>;
};
@@ -43,7 +30,7 @@ export type AddQuerySubscriptionInput = {
};
export type AdminAiModelConfig = {
__typename?: 'AdminAIModelConfig';
__typename?: 'AdminAiModelConfig';
contextWindowTokens?: Maybe<Scalars['Float']>;
dataResidency?: Maybe<Scalars['String']>;
inputCostPerMillionTokens?: Maybe<Scalars['Float']>;
@@ -64,7 +51,7 @@ export type AdminAiModelConfig = {
};
export type AdminAiModels = {
__typename?: 'AdminAIModels';
__typename?: 'AdminAiModels';
defaultFastModelId?: Maybe<Scalars['String']>;
defaultSmartModelId?: Maybe<Scalars['String']>;
models: Array<AdminAiModelConfig>;
@@ -328,6 +315,19 @@ export enum AiModelRole {
SMART = 'SMART'
}
export type AiSystemPromptPreview = {
__typename?: 'AiSystemPromptPreview';
estimatedTokenCount: Scalars['Int'];
sections: Array<AiSystemPromptSection>;
};
export type AiSystemPromptSection = {
__typename?: 'AiSystemPromptSection';
content: Scalars['String'];
estimatedTokenCount: Scalars['Int'];
title: Scalars['String'];
};
export enum AllMetadataName {
agent = 'agent',
commandMenuItem = 'commandMenuItem',
@@ -924,7 +924,7 @@ export type CheckUserExist = {
};
export type ClientAiModelConfig = {
__typename?: 'ClientAIModelConfig';
__typename?: 'ClientAiModelConfig';
contextWindowTokens?: Maybe<Scalars['Float']>;
dataResidency?: Maybe<Scalars['String']>;
inputCostPerMillionTokens?: Maybe<Scalars['Float']>;
@@ -2792,7 +2792,7 @@ export type Mutation = {
updateWorkspaceMemberRole: WorkspaceMember;
updateWorkspaceMemberSettings: Scalars['Boolean'];
upgradeApplication: Scalars['Boolean'];
uploadAIChatFile: FileWithSignedUrl;
uploadAiChatFile: FileWithSignedUrl;
uploadAppTarball: ApplicationRegistration;
uploadApplicationFile: File;
uploadEmailAttachmentFile: FileWithSignedUrl;
@@ -4441,13 +4441,13 @@ export type Query = {
findWorkspaceInvitations: Array<WorkspaceInvitation>;
frontComponent?: Maybe<FrontComponent>;
frontComponents: Array<FrontComponent>;
getAISystemPromptPreview: AiSystemPromptPreview;
getAddressDetails: PlaceDetailsResult;
getAdminAiModels: AdminAiModels;
getAdminAiUsageByWorkspace: Array<UsageBreakdownItem>;
getAdminChatThreadMessages: AdminChatThreadMessages;
getAdminWorkspaceChatThreads: Array<AdminWorkspaceChatThread>;
getAiProviders: Scalars['JSON'];
getAiSystemPromptPreview: AiSystemPromptPreview;
getApprovedAccessDomains: Array<ApprovedAccessDomain>;
getAutoCompleteAddress: Array<AutocompleteResult>;
getAvailablePackages: Scalars['JSON'];
@@ -6636,7 +6636,7 @@ export type UploadAiChatFileMutationVariables = Exact<{
}>;
export type UploadAiChatFileMutation = { __typename?: 'Mutation', uploadAIChatFile: { __typename?: 'FileWithSignedUrl', id: string, path: string, size: number, createdAt: string, url: string } };
export type UploadAiChatFileMutation = { __typename?: 'Mutation', uploadAiChatFile: { __typename?: 'FileWithSignedUrl', id: string, path: string, size: number, createdAt: string, url: string } };
export type FindManyAgentsQueryVariables = Exact<{ [key: string]: never; }>;
@@ -7462,7 +7462,7 @@ export type SetAdminDefaultAiModelMutation = { __typename?: 'Mutation', setAdmin
export type GetAdminAiModelsQueryVariables = Exact<{ [key: string]: never; }>;
export type GetAdminAiModelsQuery = { __typename?: 'Query', getAdminAiModels: { __typename?: 'AdminAIModels', defaultSmartModelId?: string | null, defaultFastModelId?: string | null, models: Array<{ __typename?: 'AdminAIModelConfig', modelId: string, label: string, modelFamily?: ModelFamily | null, sdkPackage?: string | null, isAvailable: boolean, isAdminEnabled: boolean, isDeprecated?: boolean | null, isRecommended?: boolean | null, contextWindowTokens?: number | null, maxOutputTokens?: number | null, inputCostPerMillionTokens?: number | null, outputCostPerMillionTokens?: number | null, providerName?: string | null, providerLabel?: string | null, name?: string | null, dataResidency?: string | null }> } };
export type GetAdminAiModelsQuery = { __typename?: 'Query', getAdminAiModels: { __typename?: 'AdminAiModels', defaultSmartModelId?: string | null, defaultFastModelId?: string | null, models: Array<{ __typename?: 'AdminAiModelConfig', modelId: string, label: string, modelFamily?: ModelFamily | null, sdkPackage?: string | null, isAvailable: boolean, isAdminEnabled: boolean, isDeprecated?: boolean | null, isRecommended?: boolean | null, contextWindowTokens?: number | null, maxOutputTokens?: number | null, inputCostPerMillionTokens?: number | null, outputCostPerMillionTokens?: number | null, providerName?: string | null, providerLabel?: string | null, name?: string | null, dataResidency?: string | null }> } };
export type GetAdminAiUsageByWorkspaceQueryVariables = Exact<{
periodStart?: InputMaybe<Scalars['DateTime']>;
@@ -8589,7 +8589,7 @@ export type CheckCustomDomainValidRecordsMutation = { __typename?: 'Mutation', c
export type GetAiSystemPromptPreviewQueryVariables = Exact<{ [key: string]: never; }>;
export type GetAiSystemPromptPreviewQuery = { __typename?: 'Query', getAISystemPromptPreview: { __typename?: 'AISystemPromptPreview', estimatedTokenCount: number, sections: Array<{ __typename?: 'AISystemPromptSection', title: string, content: string, estimatedTokenCount: number }> } };
export type GetAiSystemPromptPreviewQuery = { __typename?: 'Query', getAiSystemPromptPreview: { __typename?: 'AiSystemPromptPreview', estimatedTokenCount: number, sections: Array<{ __typename?: 'AiSystemPromptSection', title: string, content: string, estimatedTokenCount: number }> } };
export type GetPublicWorkspaceDataByIdQueryVariables = Exact<{
id: Scalars['UUID'];
@@ -8670,7 +8670,7 @@ export const SendChatMessageDocument = {"kind":"Document","definitions":[{"kind"
export const StopAgentChatStreamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"StopAgentChatStream"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"threadId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"stopAgentChatStream"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"threadId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"threadId"}}}]}]}}]} as unknown as DocumentNode<StopAgentChatStreamMutation, StopAgentChatStreamMutationVariables>;
export const UpdateOneAgentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateOneAgent"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateAgentInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateOneAgent"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AgentFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AgentFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Agent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"prompt"}},{"kind":"Field","name":{"kind":"Name","value":"modelId"}},{"kind":"Field","name":{"kind":"Name","value":"responseFormat"}},{"kind":"Field","name":{"kind":"Name","value":"roleId"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"modelConfiguration"}},{"kind":"Field","name":{"kind":"Name","value":"evaluationInputs"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<UpdateOneAgentMutation, UpdateOneAgentMutationVariables>;
export const UpdateSkillDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateSkill"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateSkillInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateSkill"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SkillFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SkillFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Skill"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<UpdateSkillMutation, UpdateSkillMutationVariables>;
export const UploadAiChatFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"uploadAIChatFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"file"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Upload"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uploadAIChatFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"file"},"value":{"kind":"Variable","name":{"kind":"Name","value":"file"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]} as unknown as DocumentNode<UploadAiChatFileMutation, UploadAiChatFileMutationVariables>;
export const UploadAiChatFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"uploadAiChatFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"file"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Upload"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uploadAiChatFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"file"},"value":{"kind":"Variable","name":{"kind":"Name","value":"file"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]} as unknown as DocumentNode<UploadAiChatFileMutation, UploadAiChatFileMutationVariables>;
export const FindManyAgentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyAgents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findManyAgents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AgentFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AgentFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Agent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"prompt"}},{"kind":"Field","name":{"kind":"Name","value":"modelId"}},{"kind":"Field","name":{"kind":"Name","value":"responseFormat"}},{"kind":"Field","name":{"kind":"Name","value":"roleId"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"modelConfiguration"}},{"kind":"Field","name":{"kind":"Name","value":"evaluationInputs"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<FindManyAgentsQuery, FindManyAgentsQueryVariables>;
export const FindManySkillsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManySkills"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"skills"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SkillFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SkillFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Skill"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<FindManySkillsQuery, FindManySkillsQueryVariables>;
export const FindOneAgentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindOneAgent"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findOneAgent"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AgentFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AgentFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Agent"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"prompt"}},{"kind":"Field","name":{"kind":"Name","value":"modelId"}},{"kind":"Field","name":{"kind":"Name","value":"responseFormat"}},{"kind":"Field","name":{"kind":"Name","value":"roleId"}},{"kind":"Field","name":{"kind":"Name","value":"isCustom"}},{"kind":"Field","name":{"kind":"Name","value":"modelConfiguration"}},{"kind":"Field","name":{"kind":"Name","value":"evaluationInputs"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<FindOneAgentQuery, FindOneAgentQueryVariables>;
@@ -8939,6 +8939,6 @@ export const DeleteCurrentWorkspaceDocument = {"kind":"Document","definitions":[
export const UpdateWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateWorkspaceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateWorkspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"customDomain"}},{"kind":"Field","name":{"kind":"Name","value":"subdomain"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"allowImpersonation"}},{"kind":"Field","name":{"kind":"Name","value":"isPublicInviteLinkEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isGoogleAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isMicrosoftAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isPasswordAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isTwoFactorAuthenticationEnforced"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRole"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"RoleFragment"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RoleFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Role"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllSettings"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessAllTools"}},{"kind":"Field","name":{"kind":"Name","value":"isEditable"}},{"kind":"Field","name":{"kind":"Name","value":"canReadAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToUsers"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToAgents"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToApiKeys"}}]}}]} as unknown as DocumentNode<UpdateWorkspaceMutation, UpdateWorkspaceMutationVariables>;
export const UploadWorkspaceLogoDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UploadWorkspaceLogo"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"file"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Upload"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uploadWorkspaceLogo"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"file"},"value":{"kind":"Variable","name":{"kind":"Name","value":"file"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]} as unknown as DocumentNode<UploadWorkspaceLogoMutation, UploadWorkspaceLogoMutationVariables>;
export const CheckCustomDomainValidRecordsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CheckCustomDomainValidRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"checkCustomDomainValidRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"validationType"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]} as unknown as DocumentNode<CheckCustomDomainValidRecordsMutation, CheckCustomDomainValidRecordsMutationVariables>;
export const GetAiSystemPromptPreviewDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAISystemPromptPreview"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAISystemPromptPreview"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"estimatedTokenCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"estimatedTokenCount"}}]}}]}}]} as unknown as DocumentNode<GetAiSystemPromptPreviewQuery, GetAiSystemPromptPreviewQueryVariables>;
export const GetAiSystemPromptPreviewDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAiSystemPromptPreview"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAiSystemPromptPreview"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"estimatedTokenCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"estimatedTokenCount"}}]}}]}}]} as unknown as DocumentNode<GetAiSystemPromptPreviewQuery, GetAiSystemPromptPreviewQueryVariables>;
export const GetPublicWorkspaceDataByIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetPublicWorkspaceDataById"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getPublicWorkspaceDataById"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}}]}}]}}]} as unknown as DocumentNode<GetPublicWorkspaceDataByIdQuery, GetPublicWorkspaceDataByIdQueryVariables>;
export const GetWorkspaceFromInviteHashDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceFromInviteHash"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"inviteHash"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findWorkspaceFromInviteHash"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"inviteHash"},"value":{"kind":"Variable","name":{"kind":"Name","value":"inviteHash"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"allowImpersonation"}}]}}]}}]} as unknown as DocumentNode<GetWorkspaceFromInviteHashQuery, GetWorkspaceFromInviteHashQueryVariables>;
@@ -1,22 +0,0 @@
import { AIChatApiKeyNotConfiguredMessage } from '@/ai/components/AIChatApiKeyNotConfiguredMessage';
import { AIChatCreditsExhaustedMessage } from '@/ai/components/AIChatCreditsExhaustedMessage';
import { AIChatErrorMessage } from '@/ai/components/AIChatErrorMessage';
import { type AIChatError } from '@/ai/types/AIChatError';
import { AIChatErrorCode } from '@/ai/utils/aiChatErrorCode';
import { isGraphqlErrorOfType } from '~/utils/is-graphql-error-of-type.util';
type AIChatErrorRendererProps = {
error: AIChatError;
};
export const AIChatErrorRenderer = ({ error }: AIChatErrorRendererProps) => {
if (isGraphqlErrorOfType(error, AIChatErrorCode.BILLING_CREDITS_EXHAUSTED)) {
return <AIChatCreditsExhaustedMessage />;
}
if (isGraphqlErrorOfType(error, AIChatErrorCode.API_KEY_NOT_CONFIGURED)) {
return <AIChatApiKeyNotConfiguredMessage />;
}
return <AIChatErrorMessage error={error} />;
};
@@ -10,7 +10,7 @@ import { AGENT_CHAT_NEW_THREAD_DRAFT_KEY } from '@/ai/states/agentChatDraftsByTh
import { agentChatFetchedMessagesComponentFamilyState } from '@/ai/states/agentChatFetchedMessagesComponentFamilyState';
import { agentChatMessagesLoadingState } from '@/ai/states/agentChatMessagesLoadingState';
import { agentChatQueuedMessagesComponentFamilyState } from '@/ai/states/agentChatQueuedMessagesComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { skipMessagesSkeletonUntilLoadedState } from '@/ai/states/skipMessagesSkeletonUntilLoadedState';
import { mapDBMessagesToUIMessages } from '@/ai/utils/mapDBMessagesToUIMessages';
import { useQueryWithCallbacks } from '@/apollo/hooks/useQueryWithCallbacks';
@@ -26,13 +26,13 @@ import {
export const AgentChatMessagesFetchEffect = () => {
const store = useStore();
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const isNewThread = useMemo(
() =>
currentAIChatThread === null ||
currentAIChatThread === AGENT_CHAT_NEW_THREAD_DRAFT_KEY,
[currentAIChatThread],
currentAiChatThread === null ||
currentAiChatThread === AGENT_CHAT_NEW_THREAD_DRAFT_KEY,
[currentAiChatThread],
);
const setAgentChatMessagesLoading = useSetAtomState(
@@ -45,12 +45,12 @@ export const AgentChatMessagesFetchEffect = () => {
const setAgentChatFetchedMessages = useSetAtomComponentFamilyState(
agentChatFetchedMessagesComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const setAgentChatQueuedMessages = useSetAtomComponentFamilyState(
agentChatQueuedMessagesComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const handleEventCallbackFamilyCallback =
@@ -84,7 +84,7 @@ export const AgentChatMessagesFetchEffect = () => {
return;
}
const threadId = store.get(currentAIChatThreadState.atom);
const threadId = store.get(currentAiChatThreadState.atom);
if (!isDefined(threadId)) {
return;
@@ -135,8 +135,8 @@ export const AgentChatMessagesFetchEffect = () => {
const { refetch: refetchAgentChatMessages } = useQueryWithCallbacks(
GetChatMessagesDocument,
{
variables: { threadId: currentAIChatThread ?? '' },
skip: !isDefined(currentAIChatThread) || isNewThread,
variables: { threadId: currentAiChatThread ?? '' },
skip: !isDefined(currentAiChatThread) || isNewThread,
onFirstLoad: handleFirstLoad,
onDataLoaded: handleDataLoaded,
onLoadingChange: handleLoadingChange,
@@ -1,6 +1,6 @@
import { AI_CHAT_SCROLL_WRAPPER_ID } from '@/ai/constants/AiChatScrollWrapperId';
import { agentChatIsInitialScrollPendingOnThreadChangeState } from '@/ai/states/agentChatIsInitialScrollPendingOnThreadChangeState';
import { scrollAIChatToBottom } from '@/ai/utils/scrollAIChatToBottom';
import { scrollAiChatToBottom } from '@/ai/utils/scrollAiChatToBottom';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { useEffect } from 'react';
@@ -37,10 +37,10 @@ export const AgentChatScrollToBottomOnDisplayedThreadChangeLayoutEffect =
clearTimeout(settleTimeoutId);
}
scrollAIChatToBottom();
scrollAiChatToBottom();
settleTimeoutId = setTimeout(() => {
scrollAIChatToBottom();
scrollAiChatToBottom();
setAgentChatIsInitialScrollPendingOnThreadChange(false);
mutationObserver.disconnect();
}, SCROLL_SETTLE_DELAY_MS);
@@ -15,7 +15,7 @@ import { agentChatIsStreamingComponentFamilyState } from '@/ai/states/agentChatI
import { agentChatMessagesComponentFamilyState } from '@/ai/states/agentChatMessagesComponentFamilyState';
import { agentChatMessagesLoadingState } from '@/ai/states/agentChatMessagesLoadingState';
import { agentChatThreadsLoadingState } from '@/ai/states/agentChatThreadsLoadingState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { useListenToBrowserEvent } from '@/browser-event/hooks/useListenToBrowserEvent';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -23,7 +23,7 @@ import { useSetAtomComponentFamilyState } from '@/ui/utilities/state/jotai/hooks
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
export const AgentChatStreamSubscriptionEffect = () => {
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const { createChatThread } = useCreateAgentChatThread();
@@ -41,25 +41,25 @@ export const AgentChatStreamSubscriptionEffect = () => {
useAgentChat(ensureThreadIdForSend);
const subscriptionThreadId =
currentAIChatThread !== null && isValidUuid(currentAIChatThread)
? currentAIChatThread
currentAiChatThread !== null && isValidUuid(currentAiChatThread)
? currentAiChatThread
: null;
useAgentChatSubscription(subscriptionThreadId);
const agentChatFetchedMessages = useAtomComponentFamilyStateValue(
agentChatFetchedMessagesComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const setAgentChatMessages = useSetAtomComponentFamilyState(
agentChatMessagesComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const agentChatIsStreaming = useAtomComponentFamilyStateValue(
agentChatIsStreamingComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const agentChatDisplayedThread = useAtomStateValue(
@@ -81,17 +81,17 @@ export const AgentChatStreamSubscriptionEffect = () => {
setAgentChatMessages(agentChatFetchedMessages);
if (currentAIChatThread !== agentChatDisplayedThread) {
if (currentAiChatThread !== agentChatDisplayedThread) {
if (agentChatFetchedMessages.length > 0) {
setAgentChatIsInitialScrollPendingOnThreadChange(true);
}
setAgentChatDisplayedThread(currentAIChatThread);
setAgentChatDisplayedThread(currentAiChatThread);
}
}, [
agentChatFetchedMessages,
agentChatIsStreaming,
setAgentChatMessages,
currentAIChatThread,
currentAiChatThread,
agentChatDisplayedThread,
setAgentChatDisplayedThread,
setAgentChatIsInitialScrollPendingOnThreadChange,
@@ -1,17 +1,17 @@
import { agentChatIsScrolledToBottomSelector } from '@/ai/states/agentChatIsScrolledToBottomSelector';
import { agentChatMessagesComponentFamilyState } from '@/ai/states/agentChatMessagesComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { scrollAIChatToBottom } from '@/ai/utils/scrollAIChatToBottom';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { scrollAiChatToBottom } from '@/ai/utils/scrollAiChatToBottom';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useEffect } from 'react';
export const AgentChatStreamingAutoScrollEffect = () => {
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const agentChatMessages = useAtomComponentFamilyStateValue(
agentChatMessagesComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const agentChatIsScrolledToBottom = useAtomStateValue(
@@ -24,7 +24,7 @@ export const AgentChatStreamingAutoScrollEffect = () => {
}
if (agentChatIsScrolledToBottom) {
scrollAIChatToBottom();
scrollAiChatToBottom();
}
}, [agentChatMessages, agentChatIsScrolledToBottom]);
@@ -1,18 +1,18 @@
import { useUpdateStreamingPartsWithDiff } from '@/ai/hooks/useUpdateStreamingPartsWithDiff';
import { agentChatLastDiffSyncedThreadState } from '@/ai/states/agentChatLastDiffSyncedThreadState';
import { agentChatMessagesComponentFamilyState } from '@/ai/states/agentChatMessagesComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { useEffect } from 'react';
export const AgentChatStreamingPartsDiffSyncEffect = () => {
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const agentChatMessages = useAtomComponentFamilyStateValue(
agentChatMessagesComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const { updateStreamingPartsWithDiff } = useUpdateStreamingPartsWithDiff();
@@ -27,11 +27,11 @@ export const AgentChatStreamingPartsDiffSyncEffect = () => {
}
updateStreamingPartsWithDiff(agentChatMessages);
setAgentChatLastDiffSyncedThread(currentAIChatThread);
setAgentChatLastDiffSyncedThread(currentAiChatThread);
}, [
agentChatMessages,
updateStreamingPartsWithDiff,
currentAIChatThread,
currentAiChatThread,
setAgentChatLastDiffSyncedThread,
]);
@@ -10,8 +10,8 @@ import { agentChatInputState } from '@/ai/states/agentChatInputState';
import { agentChatThreadsLoadingState } from '@/ai/states/agentChatThreadsLoadingState';
import { agentChatThreadsSelector } from '@/ai/states/agentChatThreadsSelector';
import { agentChatUsageComponentFamilyState } from '@/ai/states/agentChatUsageComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAIChatThreadTitleComponentFamilyState } from '@/ai/states/currentAIChatThreadTitleComponentFamilyState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { currentAiChatThreadTitleComponentFamilyState } from '@/ai/states/currentAiChatThreadTitleComponentFamilyState';
import { hasInitializedAgentChatThreadsState } from '@/ai/states/hasInitializedAgentChatThreadsState';
import { hasTriggeredCreateForDraftState } from '@/ai/states/hasTriggeredCreateForDraftState';
import { useUpdateMetadataStoreDraft } from '@/metadata-store/hooks/useUpdateMetadataStoreDraft';
@@ -35,14 +35,14 @@ export const AgentChatThreadInitializationEffect = () => {
PermissionFlagType.AI_SETTINGS,
);
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const setCurrentAIChatThread = useSetAtomState(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const setCurrentAiChatThread = useSetAtomState(currentAiChatThreadState);
const setAgentChatInput = useSetAtomState(agentChatInputState);
const setAgentChatThreadsLoading = useSetAtomState(
agentChatThreadsLoadingState,
);
const threadTitleFamilyCallback = useAtomComponentFamilyStateCallbackState(
currentAIChatThreadTitleComponentFamilyState,
currentAiChatThreadTitleComponentFamilyState,
);
const agentChatUsageFamilyCallback = useAtomComponentFamilyStateCallbackState(
agentChatUsageComponentFamilyState,
@@ -93,7 +93,7 @@ export const AgentChatThreadInitializationEffect = () => {
useEffect(() => {
if (
hasInitializedAgentChatThreads ||
(currentAIChatThread !== null && isValidUuid(currentAIChatThread))
(currentAiChatThread !== null && isValidUuid(currentAiChatThread))
) {
return;
}
@@ -114,7 +114,7 @@ export const AgentChatThreadInitializationEffect = () => {
const draftForThread =
store.get(agentChatDraftsByThreadIdState.atom)[firstThread.id] ?? '';
setCurrentAIChatThread(firstThread.id);
setCurrentAiChatThread(firstThread.id);
setAgentChatInput(draftForThread);
const firstThreadFamilyKey = { threadId: firstThread.id };
@@ -144,7 +144,7 @@ export const AgentChatThreadInitializationEffect = () => {
);
} else {
store.set(hasTriggeredCreateForDraftState.atom, false);
setCurrentAIChatThread(AGENT_CHAT_NEW_THREAD_DRAFT_KEY);
setCurrentAiChatThread(AGENT_CHAT_NEW_THREAD_DRAFT_KEY);
setAgentChatInput(
store.get(agentChatDraftsByThreadIdState.atom)[
AGENT_CHAT_NEW_THREAD_DRAFT_KEY
@@ -153,12 +153,12 @@ export const AgentChatThreadInitializationEffect = () => {
}
}, [
agentChatThreads,
currentAIChatThread,
currentAiChatThread,
hasAiSettingsPermission,
hasInitializedAgentChatThreads,
setHasInitializedAgentChatThreads,
storeEntry.status,
setCurrentAIChatThread,
setCurrentAiChatThread,
setAgentChatInput,
store,
threadTitleFamilyCallback,
@@ -1,17 +1,17 @@
import { AIChatBanner } from '@/ai/components/AIChatBanner';
import { AiChatBanner } from '@/ai/components/AiChatBanner';
import { t } from '@lingui/core/macro';
import { IconExternalLink } from 'twenty-ui/display';
const DOCS_URL =
'https://twenty.com/developers/section/self-hosting/self-hosting-var#ai-features';
export const AIChatApiKeyNotConfiguredMessage = () => {
export const AiChatApiKeyNotConfiguredMessage = () => {
const handleDocsClick = () => {
window.open(DOCS_URL, '_blank', 'noopener,noreferrer');
};
return (
<AIChatBanner
<AiChatBanner
message={t`AI not configured. Set OPENAI_API_KEY, ANTHROPIC_API_KEY, or XAI_API_KEY in your environment.`}
variant="warning"
buttonTitle={t`View Docs`}
@@ -1,4 +1,4 @@
import { AIChatCompactionIndicator } from '@/ai/components/AIChatCompactionIndicator';
import { AiChatCompactionIndicator } from '@/ai/components/AiChatCompactionIndicator';
import { CodeExecutionDisplay } from '@/ai/components/CodeExecutionDisplay';
import { RoutingStatusDisplay } from '@/ai/components/RoutingStatusDisplay';
import { ThinkingStepsDisplay } from '@/ai/components/ThinkingStepsDisplay';
@@ -60,7 +60,7 @@ const MessagePartRenderer = ({
case 'data-routing-status':
return <RoutingStatusDisplay data={part.data} />;
case 'data-compaction':
return <AIChatCompactionIndicator />;
return <AiChatCompactionIndicator />;
case 'data-code-execution':
return (
<CodeExecutionDisplay
@@ -87,7 +87,7 @@ const MessagePartRenderer = ({
}
};
export const AIChatAssistantMessageRenderer = ({
export const AiChatAssistantMessageRenderer = ({
messageParts,
isLastMessageStreaming,
hasError,
@@ -9,9 +9,9 @@ import {
import { Button } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type AIChatBannerVariant = 'default' | 'warning';
type AiChatBannerVariant = 'default' | 'warning';
const StyledBanner = styled.div<{ variant: AIChatBannerVariant }>`
const StyledBanner = styled.div<{ variant: AiChatBannerVariant }>`
align-items: center;
background-color: ${({ variant }) =>
variant === 'warning'
@@ -25,7 +25,7 @@ const StyledBanner = styled.div<{ variant: AIChatBannerVariant }>`
width: 100%;
`;
const StyledIconContainer = styled.div<{ variant: AIChatBannerVariant }>`
const StyledIconContainer = styled.div<{ variant: AiChatBannerVariant }>`
align-items: center;
color: ${({ variant }) =>
variant === 'warning'
@@ -38,7 +38,7 @@ const StyledIconContainer = styled.div<{ variant: AIChatBannerVariant }>`
width: 16px;
`;
const StyledMessage = styled.p<{ variant: AIChatBannerVariant }>`
const StyledMessage = styled.p<{ variant: AiChatBannerVariant }>`
color: ${({ variant }) =>
variant === 'warning'
? themeCssVariables.color.orange
@@ -53,9 +53,9 @@ const StyledMessage = styled.p<{ variant: AIChatBannerVariant }>`
min-width: 0;
`;
export type AIChatBannerProps = {
export type AiChatBannerProps = {
message: string;
variant?: AIChatBannerVariant;
variant?: AiChatBannerVariant;
tooltipMessage?: string;
buttonTitle?: string;
buttonIcon?: IconComponent;
@@ -64,7 +64,7 @@ export type AIChatBannerProps = {
isButtonLoading?: boolean;
};
export const AIChatBanner = ({
export const AiChatBanner = ({
message,
variant = 'default',
tooltipMessage,
@@ -73,7 +73,7 @@ export const AIChatBanner = ({
buttonOnClick,
isButtonDisabled = false,
isButtonLoading = false,
}: AIChatBannerProps) => {
}: AiChatBannerProps) => {
const tooltipId = 'ai-chat-banner-tooltip';
return (
@@ -16,7 +16,7 @@ const StyledIconTextContainer = styled.div`
gap: ${themeCssVariables.spacing[1]};
`;
export const AIChatCompactionIndicator = () => {
export const AiChatCompactionIndicator = () => {
const { theme } = useContext(ThemeContext);
return (
@@ -1,4 +1,4 @@
import { AIChatBanner } from '@/ai/components/AIChatBanner';
import { AiChatBanner } from '@/ai/components/AiChatBanner';
import { usePermissionFlagMap } from '@/settings/roles/hooks/usePermissionFlagMap';
import { useSubscriptionStatus } from '@/workspace/hooks/useSubscriptionStatus';
import { t } from '@lingui/core/macro';
@@ -10,7 +10,7 @@ import {
} from '~/generated-metadata/graphql';
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
export const AIChatCreditsExhaustedMessage = () => {
export const AiChatCreditsExhaustedMessage = () => {
const navigateSettings = useNavigateSettings();
const subscriptionStatus = useSubscriptionStatus();
@@ -32,7 +32,7 @@ export const AIChatCreditsExhaustedMessage = () => {
const buttonTitle = isTrialing ? t`Subscribe Now` : t`Upgrade Plan`;
return (
<AIChatBanner
<AiChatBanner
message={message}
variant="warning"
buttonTitle={hasPermissionToManageBilling ? buttonTitle : undefined}
@@ -2,15 +2,15 @@ import { styled } from '@linaria/react';
import { EditorContent } from '@tiptap/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { AIChatEmptyState } from '@/ai/components/AIChatEmptyState';
import { AIChatStandaloneError } from '@/ai/components/AIChatStandaloneError';
import { AiChatEmptyState } from '@/ai/components/AiChatEmptyState';
import { AiChatStandaloneError } from '@/ai/components/AiChatStandaloneError';
import { AgentChatContextPreview } from '@/ai/components/internal/AgentChatContextPreview';
import { AgentChatFileUploadButton } from '@/ai/components/internal/AgentChatFileUploadButton';
import { AIChatContextUsageButton } from '@/ai/components/internal/AIChatContextUsageButton';
import { AIChatEditorFocusEffect } from '@/ai/components/internal/AIChatEditorFocusEffect';
import { AIChatSkeletonLoader } from '@/ai/components/internal/AIChatSkeletonLoader';
import { AiChatContextUsageButton } from '@/ai/components/internal/AiChatContextUsageButton';
import { AiChatEditorFocusEffect } from '@/ai/components/internal/AiChatEditorFocusEffect';
import { AiChatSkeletonLoader } from '@/ai/components/internal/AiChatSkeletonLoader';
import { SendMessageButton } from '@/ai/components/internal/SendMessageButton';
import { useAIChatEditor } from '@/ai/hooks/useAIChatEditor';
import { useAiChatEditor } from '@/ai/hooks/useAiChatEditor';
import { useAiModelOptions } from '@/ai/hooks/useAiModelOptions';
import { useAgentChatModelId } from '@/ai/hooks/useAgentChatModelId';
import { agentChatUserSelectedModelState } from '@/ai/states/agentChatUserSelectedModelState';
@@ -104,7 +104,7 @@ const StyledRightButtonsContainer = styled.div`
gap: ${themeCssVariables.spacing[1]};
`;
export const AIChatEditorSection = () => {
export const AiChatEditorSection = () => {
const isMobile = useIsMobile();
const { options, pinnedOption } = useAiModelOptions({
variant: 'pinned-default',
@@ -123,14 +123,14 @@ export const AIChatEditorSection = () => {
);
const { selectedModelId } = useAgentChatModelId();
const { editor, handleSendAndClear } = useAIChatEditor();
const { editor, handleSendAndClear } = useAiChatEditor();
return (
<>
<AIChatEditorFocusEffect editor={editor} />
<AIChatEmptyState editor={editor} />
<AIChatStandaloneError />
<AIChatSkeletonLoader />
<AiChatEditorFocusEffect editor={editor} />
<AiChatEmptyState editor={editor} />
<AiChatStandaloneError />
<AiChatSkeletonLoader />
<StyledInputArea isMobile={isMobile}>
<AgentChatContextPreview />
@@ -141,7 +141,7 @@ export const AIChatEditorSection = () => {
<StyledButtonsContainer>
<StyledLeftButtonsContainer>
<AgentChatFileUploadButton />
<AIChatContextUsageButton />
<AiChatContextUsageButton />
</StyledLeftButtonsContainer>
<StyledRightButtonsContainer>
<Select
@@ -2,13 +2,13 @@ import { styled } from '@linaria/react';
import { type Editor } from '@tiptap/react';
import { isDefined } from 'twenty-shared/utils';
import { AIChatSuggestedPrompts } from '@/ai/components/suggested-prompts/AIChatSuggestedPrompts';
import { AiChatSuggestedPrompts } from '@/ai/components/suggested-prompts/AiChatSuggestedPrompts';
import { AGENT_CHAT_NEW_THREAD_DRAFT_KEY } from '@/ai/states/agentChatDraftsByThreadIdState';
import { agentChatErrorComponentFamilyState } from '@/ai/states/agentChatErrorComponentFamilyState';
import { agentChatHasMessageComponentSelector } from '@/ai/states/agentChatHasMessageComponentSelector';
import { agentChatMessagesLoadingState } from '@/ai/states/agentChatMessagesLoadingState';
import { agentChatThreadsLoadingState } from '@/ai/states/agentChatThreadsLoadingState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { skipMessagesSkeletonUntilLoadedState } from '@/ai/states/skipMessagesSkeletonUntilLoadedState';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
@@ -22,15 +22,15 @@ const StyledEmptyState = styled.div`
justify-content: flex-end;
`;
type AIChatEmptyStateProps = {
type AiChatEmptyStateProps = {
editor: Editor | null;
};
export const AIChatEmptyState = ({ editor }: AIChatEmptyStateProps) => {
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
export const AiChatEmptyState = ({ editor }: AiChatEmptyStateProps) => {
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const agentChatError = useAtomComponentFamilyStateValue(
agentChatErrorComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const agentChatThreadsLoading = useAtomStateValue(
agentChatThreadsLoadingState,
@@ -47,7 +47,7 @@ export const AIChatEmptyState = ({ editor }: AIChatEmptyStateProps) => {
);
const isOnNewChatSlot =
currentAIChatThread === AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
currentAiChatThread === AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const skeletonShowing =
(agentChatThreadsLoading && isOnNewChatSlot) ||
(agentChatMessagesLoading && !skipMessagesSkeletonUntilLoaded);
@@ -60,7 +60,7 @@ export const AIChatEmptyState = ({ editor }: AIChatEmptyStateProps) => {
return (
<StyledEmptyState>
<AIChatSuggestedPrompts editor={editor} />
<AiChatSuggestedPrompts editor={editor} />
</StyledEmptyState>
);
};
@@ -4,7 +4,7 @@ import { t } from '@lingui/core/macro';
import { IconAlertCircle } from 'twenty-ui/display';
import { useContext } from 'react';
import { type AIChatError } from '@/ai/types/AIChatError';
import { type AiChatError } from '@/ai/types/AiChatError';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { getErrorMessageFromApolloError } from '~/utils/get-error-message-from-apollo-error.util';
@@ -43,11 +43,11 @@ const StyledErrorMessage = styled.div`
word-break: break-word;
`;
type AIChatErrorMessageProps = {
error: AIChatError;
type AiChatErrorMessageProps = {
error: AiChatError;
};
export const AIChatErrorMessage = ({ error }: AIChatErrorMessageProps) => {
export const AiChatErrorMessage = ({ error }: AiChatErrorMessageProps) => {
const { theme } = useContext(ThemeContext);
const errorMessage = CombinedGraphQLErrors.is(error)
? getErrorMessageFromApolloError(error)
@@ -0,0 +1,22 @@
import { AiChatApiKeyNotConfiguredMessage } from '@/ai/components/AiChatApiKeyNotConfiguredMessage';
import { AiChatCreditsExhaustedMessage } from '@/ai/components/AiChatCreditsExhaustedMessage';
import { AiChatErrorMessage } from '@/ai/components/AiChatErrorMessage';
import { type AiChatError } from '@/ai/types/AiChatError';
import { AiChatErrorCode } from '@/ai/utils/aiChatErrorCode';
import { isGraphqlErrorOfType } from '~/utils/is-graphql-error-of-type.util';
type AiChatErrorRendererProps = {
error: AiChatError;
};
export const AiChatErrorRenderer = ({ error }: AiChatErrorRendererProps) => {
if (isGraphqlErrorOfType(error, AiChatErrorCode.BILLING_CREDITS_EXHAUSTED)) {
return <AiChatCreditsExhaustedMessage />;
}
if (isGraphqlErrorOfType(error, AiChatErrorCode.API_KEY_NOT_CONFIGURED)) {
return <AiChatApiKeyNotConfiguredMessage />;
}
return <AiChatErrorMessage error={error} />;
};
@@ -1,4 +1,4 @@
import { AIChatErrorRenderer } from '@/ai/components/AIChatErrorRenderer';
import { AiChatErrorRenderer } from '@/ai/components/AiChatErrorRenderer';
import { AgentMessageRole } from '@/ai/constants/AgentMessageRole';
import { agentChatDisplayedThreadState } from '@/ai/states/agentChatDisplayedThreadState';
import { agentChatErrorComponentFamilyState } from '@/ai/states/agentChatErrorComponentFamilyState';
@@ -16,7 +16,7 @@ const StyledErrorWrapper = styled.div`
padding-top: ${themeCssVariables.spacing[3]};
`;
export const AIChatErrorUnderMessageList = () => {
export const AiChatErrorUnderMessageList = () => {
const agentChatDisplayedThread = useAtomStateValue(
agentChatDisplayedThreadState,
);
@@ -50,7 +50,7 @@ export const AIChatErrorUnderMessageList = () => {
return (
<StyledErrorWrapper>
<AIChatErrorRenderer error={agentChatError} />
<AiChatErrorRenderer error={agentChatError} />
</StyledErrorWrapper>
);
};
@@ -1,4 +1,4 @@
import { AIChatMessage } from '@/ai/components/AIChatMessage';
import { AiChatMessage } from '@/ai/components/AiChatMessage';
import { agentChatDisplayedThreadState } from '@/ai/states/agentChatDisplayedThreadState';
import { agentChatErrorComponentFamilyState } from '@/ai/states/agentChatErrorComponentFamilyState';
import { agentChatIsStreamingComponentFamilyState } from '@/ai/states/agentChatIsStreamingComponentFamilyState';
@@ -8,7 +8,7 @@ import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { isDefined } from 'twenty-shared/utils';
export const AIChatLastMessageWithStreamingState = () => {
export const AiChatLastMessageWithStreamingState = () => {
const lastMessageId = useAtomComponentSelectorValue(
agentChatLastMessageIdComponentSelector,
);
@@ -30,7 +30,7 @@ export const AIChatLastMessageWithStreamingState = () => {
}
return (
<AIChatMessage
<AiChatMessage
messageId={lastMessageId}
isLastMessageStreaming={agentChatIsStreaming}
error={agentChatError ?? undefined}
@@ -3,10 +3,10 @@ import { styled } from '@linaria/react';
import { AgentChatFilePreview } from '@/ai/components/internal/AgentChatFilePreview';
import { AgentMessageRole } from '@/ai/constants/AgentMessageRole';
import { AIChatAssistantMessageRenderer } from '@/ai/components/AIChatAssistantMessageRenderer';
import { AIChatErrorRenderer } from '@/ai/components/AIChatErrorRenderer';
import { AiChatAssistantMessageRenderer } from '@/ai/components/AiChatAssistantMessageRenderer';
import { AiChatErrorRenderer } from '@/ai/components/AiChatErrorRenderer';
import { agentChatMessageComponentFamilySelector } from '@/ai/states/agentChatMessageComponentFamilySelector';
import { type AIChatError } from '@/ai/types/AIChatError';
import { type AiChatError } from '@/ai/types/AiChatError';
import { LightCopyIconButton } from '@/object-record/record-field/ui/components/LightCopyIconButton';
import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -140,17 +140,17 @@ const StyledFilesContainer = styled.div`
margin-top: ${themeCssVariables.spacing[2]};
`;
type AIChatMessageProps = {
type AiChatMessageProps = {
messageId: string;
isLastMessageStreaming?: boolean;
error?: AIChatError | undefined;
error?: AiChatError | undefined;
};
export const AIChatMessage = ({
export const AiChatMessage = ({
messageId,
isLastMessageStreaming = false,
error,
}: AIChatMessageProps) => {
}: AiChatMessageProps) => {
const agentChatMessage = useAtomComponentFamilySelectorValue(
agentChatMessageComponentFamilySelector,
{ messageId },
@@ -173,7 +173,7 @@ export const AIChatMessage = ({
<StyledMessageBubble isUser={isUser}>
<StyledMessageContainer isUser={isUser}>
<StyledMessageText isUser={isUser}>
<AIChatAssistantMessageRenderer
<AiChatAssistantMessageRenderer
isLastMessageStreaming={isLastMessageStreaming}
messageParts={agentChatMessage.parts}
hasError={shouldShowError}
@@ -187,7 +187,7 @@ export const AIChatMessage = ({
</StyledFilesContainer>
)}
{shouldShowError && isDefined(error) && (
<AIChatErrorRenderer error={error} />
<AiChatErrorRenderer error={error} />
)}
</StyledMessageContainer>
{agentChatMessage.parts.length > 0 && (
@@ -1,13 +1,13 @@
import { AIChatMessage } from '@/ai/components/AIChatMessage';
import { AiChatMessage } from '@/ai/components/AiChatMessage';
import { agentChatNonLastMessageIdsComponentSelector } from '@/ai/states/agentChatNonLastMessageIdsComponentSelector';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
export const AIChatNonLastMessageIdsList = () => {
export const AiChatNonLastMessageIdsList = () => {
const agentChatNonLastMessageIds = useAtomComponentSelectorValue(
agentChatNonLastMessageIdsComponentSelector,
);
return agentChatNonLastMessageIds.map((messageId) => (
<AIChatMessage key={messageId} messageId={messageId} />
<AiChatMessage key={messageId} messageId={messageId} />
));
};
@@ -1,7 +1,7 @@
import { styled } from '@linaria/react';
import { agentChatQueuedMessagesComponentFamilyState } from '@/ai/states/agentChatQueuedMessagesComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { useDeleteQueuedMessage } from '@/ai/hooks/useDeleteQueuedMessage';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -41,15 +41,15 @@ const StyledQueuedText = styled.span`
white-space: nowrap;
`;
export const AIChatQueuedMessages = () => {
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
export const AiChatQueuedMessages = () => {
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const agentChatQueuedMessages = useAtomComponentFamilyStateValue(
agentChatQueuedMessagesComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const { deleteQueuedMessage } = useDeleteQueuedMessage();
if (!isDefined(currentAIChatThread) || agentChatQueuedMessages.length === 0) {
if (!isDefined(currentAiChatThread) || agentChatQueuedMessages.length === 0) {
return null;
}
@@ -1,5 +1,5 @@
import { agentChatIsScrolledToBottomSelector } from '@/ai/states/agentChatIsScrolledToBottomSelector';
import { scrollAIChatToBottom } from '@/ai/utils/scrollAIChatToBottom';
import { scrollAiChatToBottom } from '@/ai/utils/scrollAiChatToBottom';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { styled } from '@linaria/react';
import { IconArrowDown } from 'twenty-ui/display';
@@ -33,7 +33,7 @@ const StyledScrollToBottomButton = styled.button<{ isVisible: boolean }>`
}
`;
export const AIChatScrollToBottomButton = () => {
export const AiChatScrollToBottomButton = () => {
const agentChatIsScrolledToBottom = useAtomStateValue(
agentChatIsScrolledToBottomSelector,
);
@@ -41,7 +41,7 @@ export const AIChatScrollToBottomButton = () => {
return (
<StyledScrollToBottomButton
isVisible={!agentChatIsScrolledToBottom}
onClick={scrollAIChatToBottom}
onClick={scrollAiChatToBottom}
>
<IconArrowDown size={16} />
</StyledScrollToBottomButton>
@@ -1,11 +1,11 @@
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { AIChatErrorRenderer } from '@/ai/components/AIChatErrorRenderer';
import { AiChatErrorRenderer } from '@/ai/components/AiChatErrorRenderer';
import { agentChatErrorComponentFamilyState } from '@/ai/states/agentChatErrorComponentFamilyState';
import { agentChatHasMessageComponentSelector } from '@/ai/states/agentChatHasMessageComponentSelector';
import { agentChatIsLoadingState } from '@/ai/states/agentChatIsLoadingState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -20,13 +20,13 @@ const StyledErrorContainer = styled.div`
width: 100%;
`;
export const AIChatStandaloneError = () => {
export const AiChatStandaloneError = () => {
const agentChatIsLoading = useAtomStateValue(agentChatIsLoadingState);
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const agentChatError = useAtomComponentFamilyStateValue(
agentChatErrorComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const hasMessages = useAtomComponentSelectorValue(
@@ -42,7 +42,7 @@ export const AIChatStandaloneError = () => {
return (
<StyledErrorContainer>
<AIChatErrorRenderer error={agentChatError} />
<AiChatErrorRenderer error={agentChatError} />
</StyledErrorContainer>
);
};
@@ -3,15 +3,15 @@ import { useState } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { DropZone } from '@/activities/files/components/DropZone';
import { AIChatEditorSection } from '@/ai/components/AIChatEditorSection';
import { useAIChatFileUpload } from '@/ai/hooks/useAIChatFileUpload';
import { AiChatEditorSection } from '@/ai/components/AiChatEditorSection';
import { useAiChatFileUpload } from '@/ai/hooks/useAiChatFileUpload';
import { AGENT_CHAT_NEW_THREAD_DRAFT_KEY } from '@/ai/states/agentChatDraftsByThreadIdState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { threadIdCreatedFromDraftState } from '@/ai/states/threadIdCreatedFromDraftState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { AIChatQueuedMessages } from '@/ai/components/AIChatQueuedMessages';
import { AIChatTabMessageList } from '@/ai/components/AIChatTabMessageList';
import { AiChatQueuedMessages } from '@/ai/components/AiChatQueuedMessages';
import { AiChatTabMessageList } from '@/ai/components/AiChatTabMessageList';
const StyledContainer = styled.div<{ isDraggingFile: boolean }>`
background: ${themeCssVariables.background.primary};
@@ -23,20 +23,20 @@ const StyledContainer = styled.div<{ isDraggingFile: boolean }>`
isDraggingFile ? themeCssVariables.spacing[3] : '0'};
`;
export const AIChatTab = () => {
export const AiChatTab = () => {
const [isDraggingFile, setIsDraggingFile] = useState(false);
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const threadIdCreatedFromDraft = useAtomStateValue(
threadIdCreatedFromDraftState,
);
const draftKey = currentAIChatThread ?? AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const draftKey = currentAiChatThread ?? AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const editorSectionKey =
draftKey !== AGENT_CHAT_NEW_THREAD_DRAFT_KEY &&
draftKey === threadIdCreatedFromDraft
? AGENT_CHAT_NEW_THREAD_DRAFT_KEY
: draftKey;
const { uploadFiles } = useAIChatFileUpload();
const { uploadFiles } = useAiChatFileUpload();
return (
<StyledContainer
@@ -52,9 +52,9 @@ export const AIChatTab = () => {
)}
{!isDraggingFile && (
<>
<AIChatTabMessageList />
<AIChatQueuedMessages />
<AIChatEditorSection key={editorSectionKey} />
<AiChatTabMessageList />
<AiChatQueuedMessages />
<AiChatEditorSection key={editorSectionKey} />
</>
)}
</StyledContainer>
@@ -1,7 +1,7 @@
import { AIChatErrorUnderMessageList } from '@/ai/components/AIChatErrorUnderMessageList';
import { AIChatLastMessageWithStreamingState } from '@/ai/components/AIChatLastMessageWithStreamingState';
import { AIChatNonLastMessageIdsList } from '@/ai/components/AIChatNonLastMessageIdsList';
import { AIChatScrollToBottomButton } from '@/ai/components/AIChatScrollToBottomButton';
import { AiChatErrorUnderMessageList } from '@/ai/components/AiChatErrorUnderMessageList';
import { AiChatLastMessageWithStreamingState } from '@/ai/components/AiChatLastMessageWithStreamingState';
import { AiChatNonLastMessageIdsList } from '@/ai/components/AiChatNonLastMessageIdsList';
import { AiChatScrollToBottomButton } from '@/ai/components/AiChatScrollToBottomButton';
import { AgentChatScrollToBottomOnDisplayedThreadChangeLayoutEffect } from '@/ai/components/AgentChatScrollToBottomOnDisplayedThreadChangeLayoutEffect';
import { AI_CHAT_SCROLL_WRAPPER_ID } from '@/ai/constants/AiChatScrollWrapperId';
import { agentChatHasMessageComponentSelector } from '@/ai/states/agentChatHasMessageComponentSelector';
@@ -23,7 +23,7 @@ const StyledScrollWrapperContainer = styled.div`
width: calc(100% - 24px);
`;
export const AIChatTabMessageList = () => {
export const AiChatTabMessageList = () => {
const agentChatHasMessage = useAtomComponentSelectorValue(
agentChatHasMessageComponentSelector,
);
@@ -45,12 +45,12 @@ export const AIChatTabMessageList = () => {
}}
>
<ScrollWrapper componentInstanceId={AI_CHAT_SCROLL_WRAPPER_ID}>
<AIChatNonLastMessageIdsList />
<AIChatLastMessageWithStreamingState />
<AIChatErrorUnderMessageList />
<AiChatNonLastMessageIdsList />
<AiChatLastMessageWithStreamingState />
<AiChatErrorUnderMessageList />
<AgentChatScrollToBottomOnDisplayedThreadChangeLayoutEffect />
</ScrollWrapper>
<AIChatScrollToBottomButton />
<AiChatScrollToBottomButton />
</StyledScrollWrapperContainer>
);
};
@@ -1,4 +1,4 @@
import { useAIChatThreadClick } from '@/ai/hooks/useAIChatThreadClick';
import { useAiChatThreadClick } from '@/ai/hooks/useAiChatThreadClick';
import { styled } from '@linaria/react';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
@@ -65,7 +65,7 @@ const StyledThreadTitle = styled.div`
white-space: nowrap;
`;
export const AIChatThreadGroup = ({
export const AiChatThreadGroup = ({
threads,
title,
}: {
@@ -74,7 +74,7 @@ export const AIChatThreadGroup = ({
}) => {
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { handleThreadClick } = useAIChatThreadClick();
const { handleThreadClick } = useAiChatThreadClick();
if (threads.length === 0) {
return null;
@@ -1,10 +1,10 @@
import { styled } from '@linaria/react';
import { AIChatThreadGroup } from '@/ai/components/AIChatThreadGroup';
import { AIChatThreadsListFocusEffect } from '@/ai/components/AIChatThreadsListFocusEffect';
import { AIChatSkeletonLoader } from '@/ai/components/internal/AIChatSkeletonLoader';
import { AiChatThreadGroup } from '@/ai/components/AiChatThreadGroup';
import { AiChatThreadsListFocusEffect } from '@/ai/components/AiChatThreadsListFocusEffect';
import { AiChatSkeletonLoader } from '@/ai/components/internal/AiChatSkeletonLoader';
import { useChatThreads } from '@/ai/hooks/useChatThreads';
import { useSwitchToNewAIChat } from '@/ai/hooks/useSwitchToNewAIChat';
import { useSwitchToNewAiChat } from '@/ai/hooks/useSwitchToNewAiChat';
import { groupThreadsByDate } from '@/ai/utils/groupThreadsByDate';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { t } from '@lingui/core/macro';
@@ -35,8 +35,8 @@ const StyledButtonsContainer = styled.div`
padding: ${themeCssVariables.spacing[2]} 10px;
`;
export const AIChatThreadsList = () => {
const { switchToNewChat } = useSwitchToNewAIChat();
export const AiChatThreadsList = () => {
const { switchToNewChat } = useSwitchToNewAiChat();
const focusId = 'threads-list';
@@ -52,16 +52,16 @@ export const AIChatThreadsList = () => {
const groupedThreads = groupThreadsByDate(threads);
if (loading && threads.length === 0) {
return <AIChatSkeletonLoader />;
return <AiChatSkeletonLoader />;
}
return (
<>
<AIChatThreadsListFocusEffect focusId={focusId} />
<AiChatThreadsListFocusEffect focusId={focusId} />
<StyledContainer>
<StyledThreadsContainer>
{Object.entries(groupedThreads).map(([title, threadsInGroup]) => (
<AIChatThreadGroup
<AiChatThreadGroup
key={title}
title={capitalize(title)}
threads={threadsInGroup}
@@ -3,7 +3,7 @@ import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useEffect } from 'react';
export const AIChatThreadsListFocusEffect = ({
export const AiChatThreadsListFocusEffect = ({
focusId,
}: {
focusId: string;
@@ -2,11 +2,11 @@ import { styled } from '@linaria/react';
import { useLingui } from '@lingui/react/macro';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { AIChatSkeletonLoader } from '@/ai/components/internal/AIChatSkeletonLoader';
import { NavigationDrawerAIChatThreadDateSection } from '@/ai/components/NavigationDrawerAIChatThreadDateSection';
import { useAIChatThreadClick } from '@/ai/hooks/useAIChatThreadClick';
import { AiChatSkeletonLoader } from '@/ai/components/internal/AiChatSkeletonLoader';
import { NavigationDrawerAiChatThreadDateSection } from '@/ai/components/NavigationDrawerAiChatThreadDateSection';
import { useAiChatThreadClick } from '@/ai/hooks/useAiChatThreadClick';
import { useChatThreads } from '@/ai/hooks/useChatThreads';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { type DateGroupKey } from '@/ai/utils/dateGroupKey';
import { DATE_GROUP_KEYS } from '@/ai/utils/dateGroupKeys';
import { getDateGroupTitle } from '@/ai/utils/getDateGroupTitle';
@@ -42,11 +42,11 @@ const StyledFetchMoreTrigger = styled.div`
width: 100%;
`;
export const NavigationDrawerAIChatContent = () => {
export const NavigationDrawerAiChatContent = () => {
const { t } = useLingui();
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const { handleThreadClick } = useAIChatThreadClick({
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const { handleThreadClick } = useAiChatThreadClick({
resetNavigationStack: true,
});
@@ -57,7 +57,7 @@ export const NavigationDrawerAIChatContent = () => {
if (loading && threads.length === 0) {
return (
<StyledContainer>
<AIChatSkeletonLoader />
<AiChatSkeletonLoader />
</StyledContainer>
);
}
@@ -78,11 +78,11 @@ export const NavigationDrawerAIChatContent = () => {
if (threadsInGroup.length === 0) return null;
return (
<NavigationDrawerAIChatThreadDateSection
<NavigationDrawerAiChatThreadDateSection
key={key}
title={getDateGroupTitle(key)}
threads={threadsInGroup}
currentThreadId={currentAIChatThread}
currentThreadId={currentAiChatThread}
onThreadClick={handleThreadClick}
/>
);
@@ -32,19 +32,19 @@ const StyledThreadTimestamp = styled.span`
padding-right: ${themeCssVariables.spacing['0.5']};
`;
export type NavigationDrawerAIChatThreadDateSectionProps = {
export type NavigationDrawerAiChatThreadDateSectionProps = {
title: string;
threads: AgentChatThread[];
currentThreadId: string | null;
onThreadClick: (thread: AgentChatThread) => void;
};
export const NavigationDrawerAIChatThreadDateSection = ({
export const NavigationDrawerAiChatThreadDateSection = ({
title,
threads,
currentThreadId,
onThreadClick,
}: NavigationDrawerAIChatThreadDateSectionProps) => {
}: NavigationDrawerAiChatThreadDateSectionProps) => {
const { t } = useLingui();
return (
@@ -8,13 +8,13 @@ import { userEvent, within } from 'storybook/test';
import { type ExtendedUIMessage } from 'twenty-shared/ai';
import { ComponentDecorator } from 'twenty-ui/testing';
import { AIChatMessage } from '@/ai/components/AIChatMessage';
import { AiChatMessage } from '@/ai/components/AiChatMessage';
import { AgentChatComponentInstanceContext } from '@/ai/states/AgentChatComponentInstanceContext';
import { agentChatDisplayedThreadState } from '@/ai/states/agentChatDisplayedThreadState';
import { agentChatMessageComponentFamilyState } from '@/ai/states/agentChatMessageComponentFamilyState';
import { agentChatMessagesComponentFamilyState } from '@/ai/states/agentChatMessagesComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { styled } from '@linaria/react';
import { useStore } from 'jotai';
@@ -258,7 +258,7 @@ const AgentChatMessagesSetterEffect = ({
const store = useStore();
useEffect(() => {
const currentThreadId = store.get(currentAIChatThreadState.atom);
const currentThreadId = store.get(currentAiChatThreadState.atom);
store.set(agentChatDisplayedThreadState.atom, currentThreadId);
@@ -293,9 +293,9 @@ const AgentChatInstanceDecorator: Decorator = (Story) => (
</AgentChatComponentInstanceContext.Provider>
);
const meta: Meta<typeof AIChatMessage> = {
title: 'Modules/AI/AIChatMessage',
component: AIChatMessage,
const meta: Meta<typeof AiChatMessage> = {
title: 'Modules/AI/AiChatMessage',
component: AiChatMessage,
decorators: [
ComponentDecorator,
RootDecorator,
@@ -308,48 +308,48 @@ const meta: Meta<typeof AIChatMessage> = {
};
export default meta;
type Story = StoryObj<typeof AIChatMessage>;
type Story = StoryObj<typeof AiChatMessage>;
// Conversation showcase - demonstrates a full AI chat flow
export const ConversationWithCodeExecution: Story = {
render: () => (
<StyledConversationContainer>
<AIChatMessage messageId={mockUserMessage.id} />
<AIChatMessage messageId={mockAssistantWithCodeExecution.id} />
<AiChatMessage messageId={mockUserMessage.id} />
<AiChatMessage messageId={mockAssistantWithCodeExecution.id} />
</StyledConversationContainer>
),
};
export const UserMessage: Story = {
render: () => <AIChatMessage messageId={mockUserMessage.id} />,
render: () => <AiChatMessage messageId={mockUserMessage.id} />,
};
export const AssistantTextResponse: Story = {
render: () => <AIChatMessage messageId={mockSimpleTextResponse.id} />,
render: () => <AiChatMessage messageId={mockSimpleTextResponse.id} />,
};
export const AssistantStreaming: Story = {
render: () => <AIChatMessage messageId={mockStreamingMessage.id} />,
render: () => <AiChatMessage messageId={mockStreamingMessage.id} />,
};
export const CodeExecutionRunning: Story = {
render: () => <AIChatMessage messageId={mockCodeExecutionRunning.id} />,
render: () => <AiChatMessage messageId={mockCodeExecutionRunning.id} />,
};
export const CodeExecutionWithError: Story = {
render: () => <AIChatMessage messageId={mockCodeExecutionError.id} />,
render: () => <AiChatMessage messageId={mockCodeExecutionError.id} />,
};
export const ThinkingStepsThinkingState: Story = {
render: () => <AIChatMessage messageId={mockThinkingStepsStreaming.id} />,
render: () => <AiChatMessage messageId={mockThinkingStepsStreaming.id} />,
};
export const ThinkingStepsDoneCollapsed: Story = {
render: () => <AIChatMessage messageId={mockThinkingStepsDone.id} />,
render: () => <AiChatMessage messageId={mockThinkingStepsDone.id} />,
};
export const ThinkingStepsDoneExpanded: Story = {
render: () => <AIChatMessage messageId={mockThinkingStepsDone.id} />,
render: () => <AiChatMessage messageId={mockThinkingStepsDone.id} />,
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const summaryButton = await canvas.findByRole('button', {
@@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
import { ThemeProvider } from 'twenty-ui/theme-constants';
import { type ExtendedUIMessagePart } from 'twenty-shared/ai';
import { AIChatAssistantMessageRenderer } from '@/ai/components/AIChatAssistantMessageRenderer';
import { AiChatAssistantMessageRenderer } from '@/ai/components/AiChatAssistantMessageRenderer';
jest.mock('@/ai/components/ThinkingStepsDisplay', () => ({
ThinkingStepsDisplay: ({
@@ -43,7 +43,7 @@ jest.mock('@/ai/components/CodeExecutionDisplay', () => ({
const renderAssistantRenderer = (messageParts: ExtendedUIMessagePart[]) => {
return render(
<ThemeProvider colorScheme="light">
<AIChatAssistantMessageRenderer
<AiChatAssistantMessageRenderer
messageParts={messageParts}
isLastMessageStreaming={false}
/>
@@ -51,7 +51,7 @@ const renderAssistantRenderer = (messageParts: ExtendedUIMessagePart[]) => {
);
};
describe('AIChatAssistantMessageRenderer', () => {
describe('AiChatAssistantMessageRenderer', () => {
it('should group reasoning and tool steps into ThinkingStepsDisplay', () => {
const messageParts = [
{
@@ -1,4 +1,4 @@
import { useAIChatFileUpload } from '@/ai/hooks/useAIChatFileUpload';
import { useAiChatFileUpload } from '@/ai/hooks/useAiChatFileUpload';
import { agentChatSelectedFilesState } from '@/ai/states/agentChatSelectedFilesState';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { styled } from '@linaria/react';
@@ -23,7 +23,7 @@ export const AgentChatFileUploadButton = () => {
agentChatSelectedFilesState,
);
const fileInputRef = useRef<HTMLInputElement>(null);
const { uploadFiles } = useAIChatFileUpload();
const { uploadFiles } = useAiChatFileUpload();
const handleFileInputChange = (
event: React.ChangeEvent<HTMLInputElement>,
@@ -13,7 +13,7 @@ import {
agentChatUsageComponentFamilyState,
type AgentChatLastMessageUsage,
} from '@/ai/states/agentChatUsageComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { SettingsBillingLabelValueItem } from '@/settings/billing/components/internal/SettingsBillingLabelValueItem';
import { billingState } from '@/client-config/states/billingState';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
@@ -93,13 +93,13 @@ const getCachedLabel = (lastMessage: AgentChatLastMessageUsage): string => {
return ` (${t`${cachedPercent}% cached`})`;
};
export const AIChatContextUsageButton = () => {
export const AiChatContextUsageButton = () => {
const { t } = useLingui();
const [isHovered, setIsHovered] = useState(false);
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const agentChatUsage = useAtomComponentFamilyStateValue(
agentChatUsageComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const billing = useAtomStateValue(billingState);
const isBillingEnabled = billing?.isBillingEnabled ?? false;
@@ -4,13 +4,13 @@ import { useEffect } from 'react';
import { shouldFocusChatEditorState } from '@/ai/states/shouldFocusChatEditorState';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
type AIChatEditorFocusEffectProps = {
type AiChatEditorFocusEffectProps = {
editor: Editor | null;
};
export const AIChatEditorFocusEffect = ({
export const AiChatEditorFocusEffect = ({
editor,
}: AIChatEditorFocusEffectProps) => {
}: AiChatEditorFocusEffectProps) => {
const [shouldFocusChatEditor, setShouldFocusChatEditor] = useAtomState(
shouldFocusChatEditorState,
);
@@ -7,7 +7,7 @@ import { AGENT_CHAT_NEW_THREAD_DRAFT_KEY } from '@/ai/states/agentChatDraftsByTh
import { agentChatMessagesLoadingState } from '@/ai/states/agentChatMessagesLoadingState';
import { agentChatThreadsLoadingState } from '@/ai/states/agentChatThreadsLoadingState';
import { agentChatHasMessageComponentSelector } from '@/ai/states/agentChatHasMessageComponentSelector';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { skipMessagesSkeletonUntilLoadedState } from '@/ai/states/skipMessagesSkeletonUntilLoadedState';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -32,7 +32,7 @@ const StyledMessageSkeleton = styled.div`
const NUMBER_OF_SKELETONS = 6;
export const AIChatSkeletonLoader = () => {
export const AiChatSkeletonLoader = () => {
const { theme } = useContext(ThemeContext);
const agentChatThreadsLoading = useAtomStateValue(
agentChatThreadsLoadingState,
@@ -43,14 +43,14 @@ export const AIChatSkeletonLoader = () => {
const skipMessagesSkeletonUntilLoaded = useAtomStateValue(
skipMessagesSkeletonUntilLoadedState,
);
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const hasMessages = useAtomComponentSelectorValue(
agentChatHasMessageComponentSelector,
);
const isOnNewChatSlot =
currentAIChatThread === AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
currentAiChatThread === AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const showForMessagesLoading =
agentChatMessagesLoading && !skipMessagesSkeletonUntilLoaded;
const shouldRender =
@@ -2,7 +2,7 @@ import { AGENT_CHAT_STOP_EVENT_NAME } from '@/ai/constants/AgentChatStopEventNam
import { agentChatInputIsEmptySelector } from '@/ai/states/agentChatInputIsEmptySelector';
import { agentChatIsLoadingState } from '@/ai/states/agentChatIsLoadingState';
import { agentChatIsStreamingComponentFamilyState } from '@/ai/states/agentChatIsStreamingComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { dispatchBrowserEvent } from '@/browser-event/utils/dispatchBrowserEvent';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -20,10 +20,10 @@ export const SendMessageButton = ({ onSend }: SendMessageButtonProps) => {
const agentChatIsLoading = useAtomStateValue(agentChatIsLoadingState);
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const agentChatIsStreaming = useAtomComponentFamilyStateValue(
agentChatIsStreamingComponentFamilyState,
{ threadId: currentAIChatThread },
{ threadId: currentAiChatThread },
);
const handleStopClick = () => {
@@ -36,13 +36,13 @@ const StyledSuggestedPromptButtonContainer = styled.div`
const pickRandom = <T,>(items: T[]): T =>
items[Math.floor(Math.random() * items.length)];
type AIChatSuggestedPromptsProps = {
type AiChatSuggestedPromptsProps = {
editor: Editor | null;
};
export const AIChatSuggestedPrompts = ({
export const AiChatSuggestedPrompts = ({
editor,
}: AIChatSuggestedPromptsProps) => {
}: AiChatSuggestedPromptsProps) => {
const { t: resolveMessage } = useLingui();
const setAgentChatInput = useSetAtomState(agentChatInputState);
@@ -1,8 +1,8 @@
import { gql } from '@apollo/client';
export const UPLOAD_AI_CHAT_FILE = gql`
mutation uploadAIChatFile($file: Upload!) {
uploadAIChatFile(file: $file) {
mutation uploadAiChatFile($file: Upload!) {
uploadAiChatFile(file: $file) {
id
path
size
@@ -22,7 +22,7 @@ import { agentChatInputState } from '@/ai/states/agentChatInputState';
import { agentChatSelectedFilesState } from '@/ai/states/agentChatSelectedFilesState';
import { agentChatUploadedFilesState } from '@/ai/states/agentChatUploadedFilesState';
import { agentChatMessagesComponentFamilyState } from '@/ai/states/agentChatMessagesComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { useGetBrowsingContext } from '@/ai/hooks/useBrowsingContext';
import { useAgentChatModelId } from '@/ai/hooks/useAgentChatModelId';
import { useListenToBrowserEvent } from '@/browser-event/hooks/useListenToBrowserEvent';
@@ -37,7 +37,7 @@ export const useAgentChat = (
const { modelIdForRequest } = useAgentChatModelId();
const { getBrowsingContext } = useGetBrowsingContext();
const apolloClient = useApolloClient();
const setCurrentAIChatThread = useSetAtomState(currentAIChatThreadState);
const setCurrentAiChatThread = useSetAtomState(currentAiChatThreadState);
const store = useStore();
const agentChatSelectedFiles = useAtomStateValue(agentChatSelectedFilesState);
@@ -55,7 +55,7 @@ export const useAgentChat = (
const handleSendMessage = useCallback(async () => {
const draftKey =
store.get(currentAIChatThreadState.atom) ??
store.get(currentAiChatThreadState.atom) ??
AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const contentToSend =
draftKey === AGENT_CHAT_NEW_THREAD_DRAFT_KEY
@@ -158,7 +158,7 @@ export const useAgentChat = (
setPendingThreadIdAfterFirstSend((pendingId) => {
if (isDefined(pendingId)) {
setCurrentAIChatThread(pendingId);
setCurrentAiChatThread(pendingId);
}
return null;
@@ -195,7 +195,7 @@ export const useAgentChat = (
});
if (draftKey === AGENT_CHAT_NEW_THREAD_DRAFT_KEY) {
setCurrentAIChatThread(threadId);
setCurrentAiChatThread(threadId);
}
setPendingThreadIdAfterFirstSend(null);
@@ -211,7 +211,7 @@ export const useAgentChat = (
setAgentChatUploadedFiles,
setAgentChatDraftsByThreadId,
modelIdForRequest,
setCurrentAIChatThread,
setCurrentAiChatThread,
apolloClient,
]);
@@ -221,7 +221,7 @@ export const useAgentChat = (
});
const handleStop = useCallback(async () => {
const threadId = store.get(currentAIChatThreadState.atom);
const threadId = store.get(currentAiChatThreadState.atom);
if (!isDefined(threadId) || !isValidUuid(threadId)) {
return;
@@ -18,7 +18,7 @@ import { agentChatHandleEventCallbackComponentFamilyState } from '@/ai/states/ag
import { agentChatIsStreamingComponentFamilyState } from '@/ai/states/agentChatIsStreamingComponentFamilyState';
import { agentChatMessagesComponentFamilyState } from '@/ai/states/agentChatMessagesComponentFamilyState';
import { agentChatUsageComponentFamilyState } from '@/ai/states/agentChatUsageComponentFamilyState';
import { currentAIChatThreadTitleComponentFamilyState } from '@/ai/states/currentAIChatThreadTitleComponentFamilyState';
import { currentAiChatThreadTitleComponentFamilyState } from '@/ai/states/currentAiChatThreadTitleComponentFamilyState';
import { dispatchBrowserEvent } from '@/browser-event/utils/dispatchBrowserEvent';
import { useAtomComponentFamilyStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateCallbackState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -116,7 +116,7 @@ export const useAgentChatSubscription = (threadId: string | null) => {
agentChatUsageComponentFamilyState,
);
const threadTitleFamilyCallback = useAtomComponentFamilyStateCallbackState(
currentAIChatThreadTitleComponentFamilyState,
currentAiChatThreadTitleComponentFamilyState,
);
useEffect(() => {
@@ -15,7 +15,7 @@ import {
agentChatDraftsByThreadIdState,
} from '@/ai/states/agentChatDraftsByThreadIdState';
import { agentChatInputState } from '@/ai/states/agentChatInputState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { dispatchAgentChatEnsureThreadForDraftEvent } from '@/ai/utils/dispatchAgentChatEnsureThreadForDraftEvent';
import { dispatchAgentChatSendMessageEvent } from '@/ai/utils/dispatchAgentChatSendMessageEvent';
import { MENTION_SUGGESTION_PLUGIN_KEY } from '@/mention/constants/MentionSuggestionPluginKey';
@@ -41,9 +41,9 @@ const textToTiptapContent = (text: string) => ({
],
});
export const useAIChatEditor = () => {
export const useAiChatEditor = () => {
const setAgentChatInput = useSetAtomState(agentChatInputState);
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const [agentChatDraftsByThreadId, setAgentChatDraftsByThreadId] =
useAtomState(agentChatDraftsByThreadIdState);
const { searchMentionRecords } = useMentionSearch();
@@ -51,7 +51,7 @@ export const useAIChatEditor = () => {
const { removeFocusItemFromFocusStackById } =
useRemoveFocusItemFromFocusStackById();
const draftKey = currentAIChatThread ?? AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const draftKey = currentAiChatThread ?? AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const initialDraft = agentChatDraftsByThreadId[draftKey] ?? '';
const initialContent = textToTiptapContent(initialDraft);
@@ -9,7 +9,7 @@ import { isDefined } from 'twenty-shared/utils';
import { type AgentChatFileUIPart } from '@/ai/types/agent-chat-file-ui-part.type';
import { UploadAiChatFileDocument } from '~/generated-metadata/graphql';
export const useAIChatFileUpload = () => {
export const useAiChatFileUpload = () => {
const apolloClient = useApolloClient();
const [uploadAiChatFile] = useMutation(UploadAiChatFileDocument, {
client: apolloClient,
@@ -31,7 +31,7 @@ export const useAIChatFileUpload = () => {
},
});
const response = result?.data?.uploadAIChatFile;
const response = result?.data?.uploadAiChatFile;
if (!isDefined(response)) {
throw new Error(t`Couldn't upload the file.`);
@@ -1,10 +1,10 @@
import { agentChatDraftsByThreadIdState } from '@/ai/states/agentChatDraftsByThreadIdState';
import { agentChatInputState } from '@/ai/states/agentChatInputState';
import { agentChatUsageComponentFamilyState } from '@/ai/states/agentChatUsageComponentFamilyState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAIChatThreadTitleComponentFamilyState } from '@/ai/states/currentAIChatThreadTitleComponentFamilyState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { currentAiChatThreadTitleComponentFamilyState } from '@/ai/states/currentAiChatThreadTitleComponentFamilyState';
import { threadIdCreatedFromDraftState } from '@/ai/states/threadIdCreatedFromDraftState';
import { useOpenAskAIPageInSidePanel } from '@/side-panel/hooks/useOpenAskAIPageInSidePanel';
import { useOpenAskAiPageInSidePanel } from '@/side-panel/hooks/useOpenAskAiPageInSidePanel';
import { useAtomComponentFamilyStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateCallbackState';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
@@ -12,44 +12,44 @@ import { useStore } from 'jotai';
import { isDefined } from 'twenty-shared/utils';
import { type AgentChatThread } from '~/generated-metadata/graphql';
export type UseAIChatThreadClickOptions = {
export type UseAiChatThreadClickOptions = {
resetNavigationStack?: boolean;
};
export const useAIChatThreadClick = (
options: UseAIChatThreadClickOptions = {},
export const useAiChatThreadClick = (
options: UseAiChatThreadClickOptions = {},
) => {
const { resetNavigationStack = false } = options;
const setThreadIdCreatedFromDraft = useSetAtomState(
threadIdCreatedFromDraftState,
);
const [currentAIChatThread, setCurrentAIChatThread] = useAtomState(
currentAIChatThreadState,
const [currentAiChatThread, setCurrentAiChatThread] = useAtomState(
currentAiChatThreadState,
);
const setAgentChatInput = useSetAtomState(agentChatInputState);
const setAgentChatDraftsByThreadId = useSetAtomState(
agentChatDraftsByThreadIdState,
);
const threadTitleFamilyCallback = useAtomComponentFamilyStateCallbackState(
currentAIChatThreadTitleComponentFamilyState,
currentAiChatThreadTitleComponentFamilyState,
);
const agentChatUsageFamilyCallback = useAtomComponentFamilyStateCallbackState(
agentChatUsageComponentFamilyState,
);
const store = useStore();
const { openAskAIPage } = useOpenAskAIPageInSidePanel();
const { openAskAiPage } = useOpenAskAiPageInSidePanel();
const handleThreadClick = (thread: AgentChatThread) => {
setThreadIdCreatedFromDraft(null);
const isSameThread = thread.id === currentAIChatThread;
const isSameThread = thread.id === currentAiChatThread;
if (currentAIChatThread !== null) {
if (currentAiChatThread !== null) {
setAgentChatDraftsByThreadId((prev) => ({
...prev,
[currentAIChatThread]: store.get(agentChatInputState.atom),
[currentAiChatThread]: store.get(agentChatInputState.atom),
}));
}
setCurrentAIChatThread(thread.id);
setCurrentAiChatThread(thread.id);
if (!isSameThread) {
const newDraft =
@@ -82,7 +82,7 @@ export const useAIChatThreadClick = (
: null,
);
openAskAIPage({
openAskAiPage({
resetNavigationStack,
});
};
@@ -5,7 +5,7 @@ import {
agentChatDraftsByThreadIdState,
} from '@/ai/states/agentChatDraftsByThreadIdState';
import { agentChatInputState } from '@/ai/states/agentChatInputState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { shouldFocusChatEditorState } from '@/ai/states/shouldFocusChatEditorState';
import { hasTriggeredCreateForDraftState } from '@/ai/states/hasTriggeredCreateForDraftState';
import { isCreatingChatThreadState } from '@/ai/states/isCreatingChatThreadState';
@@ -20,7 +20,7 @@ import { useMutation } from '@apollo/client/react';
import { CreateChatThreadDocument } from '~/generated-metadata/graphql';
export const useCreateAgentChatThread = () => {
const setCurrentAIChatThread = useSetAtomState(currentAIChatThreadState);
const setCurrentAiChatThread = useSetAtomState(currentAiChatThreadState);
const setAgentChatInput = useSetAtomState(agentChatInputState);
const setIsCreatingChatThread = useSetAtomState(isCreatingChatThreadState);
const setAgentChatDraftsByThreadId = useSetAtomState(
@@ -55,7 +55,7 @@ export const useCreateAgentChatThread = () => {
const newThreadId = data.createChatThread.id;
const previousDraftKey =
store.get(currentAIChatThreadState.atom) ??
store.get(currentAiChatThreadState.atom) ??
AGENT_CHAT_NEW_THREAD_DRAFT_KEY;
const draftsSnapshot = store.get(agentChatDraftsByThreadIdState.atom);
const newDraft = draftsSnapshot[AGENT_CHAT_NEW_THREAD_DRAFT_KEY] ?? '';
@@ -79,7 +79,7 @@ export const useCreateAgentChatThread = () => {
}));
}
setCurrentAIChatThread(newThreadId);
setCurrentAiChatThread(newThreadId);
setAgentChatInput(newDraft);
},
onError: () => {
@@ -5,7 +5,7 @@ import {
AGENT_CHAT_NEW_THREAD_DRAFT_KEY,
agentChatDraftsByThreadIdState,
} from '@/ai/states/agentChatDraftsByThreadIdState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { hasTriggeredCreateForDraftState } from '@/ai/states/hasTriggeredCreateForDraftState';
import { isCreatingChatThreadState } from '@/ai/states/isCreatingChatThreadState';
import { pendingCreateFromDraftPromiseState } from '@/ai/states/pendingCreateFromDraftPromiseState';
@@ -21,7 +21,7 @@ export const useEnsureAgentChatThreadExistsForDraft = (
const store = useStore();
const ensureThreadExistsForDraft = useCallback(() => {
const currentThreadId = store.get(currentAIChatThreadState.atom);
const currentThreadId = store.get(currentAiChatThreadState.atom);
if (currentThreadId !== AGENT_CHAT_NEW_THREAD_DRAFT_KEY) {
return;
@@ -3,7 +3,7 @@ import { useCallback } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { AGENT_CHAT_NEW_THREAD_DRAFT_KEY } from '@/ai/states/agentChatDraftsByThreadIdState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { isCreatingChatThreadState } from '@/ai/states/isCreatingChatThreadState';
import { isCreatingForFirstSendState } from '@/ai/states/isCreatingForFirstSendState';
import { pendingCreateFromDraftPromiseState } from '@/ai/states/pendingCreateFromDraftPromiseState';
@@ -18,7 +18,7 @@ export const useEnsureAgentChatThreadIdForSend = (
const ensureThreadIdForSend = useCallback(async (): Promise<
string | null
> => {
const currentThreadId = store.get(currentAIChatThreadState.atom);
const currentThreadId = store.get(currentAiChatThreadState.atom);
if (
currentThreadId !== null &&
@@ -5,27 +5,27 @@ import {
agentChatDraftsByThreadIdState,
} from '@/ai/states/agentChatDraftsByThreadIdState';
import { agentChatInputState } from '@/ai/states/agentChatInputState';
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { shouldFocusChatEditorState } from '@/ai/states/shouldFocusChatEditorState';
import { hasTriggeredCreateForDraftState } from '@/ai/states/hasTriggeredCreateForDraftState';
import { threadIdCreatedFromDraftState } from '@/ai/states/threadIdCreatedFromDraftState';
import { useOpenAskAIPageInSidePanel } from '@/side-panel/hooks/useOpenAskAIPageInSidePanel';
import { useOpenAskAiPageInSidePanel } from '@/side-panel/hooks/useOpenAskAiPageInSidePanel';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
export const useSwitchToNewAIChat = () => {
export const useSwitchToNewAiChat = () => {
const setThreadIdCreatedFromDraft = useSetAtomState(
threadIdCreatedFromDraftState,
);
const [currentAIChatThread, setCurrentAIChatThread] = useAtomState(
currentAIChatThreadState,
const [currentAiChatThread, setCurrentAiChatThread] = useAtomState(
currentAiChatThreadState,
);
const setAgentChatInput = useSetAtomState(agentChatInputState);
const setAgentChatDraftsByThreadId = useSetAtomState(
agentChatDraftsByThreadIdState,
);
const store = useStore();
const { openAskAIPage } = useOpenAskAIPageInSidePanel();
const { openAskAiPage } = useOpenAskAiPageInSidePanel();
const switchToNewChat = () => {
setThreadIdCreatedFromDraft(null);
@@ -33,16 +33,16 @@ export const useSwitchToNewAIChat = () => {
store.get(agentChatDraftsByThreadIdState.atom)[
AGENT_CHAT_NEW_THREAD_DRAFT_KEY
] ?? '';
if (currentAIChatThread !== null) {
if (currentAiChatThread !== null) {
setAgentChatDraftsByThreadId((prev) => ({
...prev,
[currentAIChatThread]: store.get(agentChatInputState.atom),
[currentAiChatThread]: store.get(agentChatInputState.atom),
}));
}
store.set(hasTriggeredCreateForDraftState.atom, false);
setCurrentAIChatThread(AGENT_CHAT_NEW_THREAD_DRAFT_KEY);
setCurrentAiChatThread(AGENT_CHAT_NEW_THREAD_DRAFT_KEY);
setAgentChatInput(newChatDraft);
openAskAIPage();
openAskAiPage();
store.set(shouldFocusChatEditorState.atom, true);
};
@@ -1,10 +1,10 @@
import { AgentChatComponentInstanceContext } from '@/ai/states/AgentChatComponentInstanceContext';
import { type AIChatError } from '@/ai/types/AIChatError';
import { type AiChatError } from '@/ai/types/AiChatError';
import { createAtomComponentFamilyState } from '@/ui/utilities/state/jotai/utils/createAtomComponentFamilyState';
export const agentChatErrorComponentFamilyState =
createAtomComponentFamilyState<
AIChatError | null,
AiChatError | null,
{ threadId: string | null }
>({
key: 'agentChatErrorComponentFamilyState',
@@ -1,6 +1,6 @@
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
export const currentAIChatThreadState = createAtomState<string | null>({
key: 'ai/currentAIChatThreadState',
export const currentAiChatThreadState = createAtomState<string | null>({
key: 'ai/currentAiChatThreadState',
defaultValue: null,
});
@@ -1,9 +1,9 @@
import { AgentChatComponentInstanceContext } from '@/ai/states/AgentChatComponentInstanceContext';
import { createAtomComponentFamilyState } from '@/ui/utilities/state/jotai/utils/createAtomComponentFamilyState';
export const currentAIChatThreadTitleComponentFamilyState =
export const currentAiChatThreadTitleComponentFamilyState =
createAtomComponentFamilyState<string | null, { threadId: string | null }>({
key: 'currentAIChatThreadTitleComponentFamilyState',
key: 'currentAiChatThreadTitleComponentFamilyState',
defaultValue: null,
componentInstanceContext: AgentChatComponentInstanceContext,
});
@@ -1,3 +1,3 @@
import { type CombinedGraphQLErrors } from '@apollo/client/errors';
export type AIChatError = Error | CombinedGraphQLErrors;
export type AiChatError = Error | CombinedGraphQLErrors;
@@ -1,5 +1,5 @@
// Error codes matching backend AgentExceptionCode and BillingExceptionCode
export const AIChatErrorCode = {
export const AiChatErrorCode = {
BILLING_CREDITS_EXHAUSTED: 'BILLING_CREDITS_EXHAUSTED',
API_KEY_NOT_CONFIGURED: 'API_KEY_NOT_CONFIGURED',
} as const;
@@ -1,6 +1,6 @@
import { AI_CHAT_SCROLL_WRAPPER_ID } from '@/ai/constants/AiChatScrollWrapperId';
export const scrollAIChatToBottom = () => {
export const scrollAiChatToBottom = () => {
const scrollWrapperElement = document.getElementById(
`scroll-wrapper-${AI_CHAT_SCROLL_WRAPPER_ID}`,
);
@@ -152,9 +152,9 @@ const SettingsAI = lazy(() =>
})),
);
const SettingsAIUsageUserDetail = lazy(() =>
import('~/pages/settings/ai/SettingsAIUsageUserDetail').then((module) => ({
default: module.SettingsAIUsageUserDetail,
const SettingsAiUsageUserDetail = lazy(() =>
import('~/pages/settings/ai/SettingsAiUsageUserDetail').then((module) => ({
default: module.SettingsAiUsageUserDetail,
})),
);
@@ -230,9 +230,9 @@ const SettingsSkillForm = lazy(() =>
})),
);
const SettingsAIPrompts = lazy(() =>
import('~/pages/settings/ai/SettingsAIPrompts').then((module) => ({
default: module.SettingsAIPrompts,
const SettingsAiPrompts = lazy(() =>
import('~/pages/settings/ai/SettingsAiPrompts').then((module) => ({
default: module.SettingsAiPrompts,
})),
);
@@ -564,33 +564,33 @@ export const SettingsRoutes = ({ isAdminPageEnabled }: SettingsRoutesProps) => (
element={<SettingsApiWebhooks />}
/>
<Route path={SettingsPath.AI} element={<SettingsAI />} />
<Route path={SettingsPath.AIPrompts} element={<SettingsAIPrompts />} />
<Route path={SettingsPath.AiPrompts} element={<SettingsAiPrompts />} />
<Route
path={SettingsPath.AINewAgent}
path={SettingsPath.AiNewAgent}
element={<SettingsAgentForm mode="create" />}
/>
<Route
path={SettingsPath.AIAgentDetail}
path={SettingsPath.AiAgentDetail}
element={<SettingsAgentForm mode="edit" />}
/>
<Route
path={SettingsPath.AIAgentTurnDetail}
path={SettingsPath.AiAgentTurnDetail}
element={<SettingsAgentTurnDetail />}
/>
<Route
path={SettingsPath.AINewSkill}
path={SettingsPath.AiNewSkill}
element={<SettingsSkillForm mode="create" />}
/>
<Route
path={SettingsPath.AISkillDetail}
path={SettingsPath.AiSkillDetail}
element={<SettingsSkillForm mode="edit" />}
/>
<Route
path={SettingsPath.AIUsageUserDetail}
element={<SettingsAIUsageUserDetail />}
path={SettingsPath.AiUsageUserDetail}
element={<SettingsAiUsageUserDetail />}
/>
<Route
path={SettingsPath.AIToolDetail}
path={SettingsPath.AiToolDetail}
element={<SettingsToolDetail />}
/>
<Route
@@ -208,7 +208,7 @@ export const ENGINE_COMPONENT_KEY_COMPONENT_MAP: Record<
),
[EngineComponentKey.VIEW_PREVIOUS_AI_CHATS]: (
<HeadlessOpenSidePanelPageEngineCommand
page={SidePanelPages.ViewPreviousAIChats}
page={SidePanelPages.ViewPreviousAiChats}
pageTitle={msg`View Previous AI Chats`}
pageIcon={IconHistory}
/>
@@ -1,6 +1,6 @@
import { useKeyboardShortcutMenu } from '@/keyboard-shortcut-menu/hooks/useKeyboardShortcutMenu';
import { SIDE_PANEL_FOCUS_ID } from '@/side-panel/constants/SidePanelFocusId';
import { useOpenAskAIPageInSidePanel } from '@/side-panel/hooks/useOpenAskAIPageInSidePanel';
import { useOpenAskAiPageInSidePanel } from '@/side-panel/hooks/useOpenAskAiPageInSidePanel';
import { useOpenRecordsSearchPageInSidePanel } from '@/side-panel/hooks/useOpenRecordsSearchPageInSidePanel';
import { useSidePanelHistory } from '@/side-panel/hooks/useSidePanelHistory';
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
@@ -20,7 +20,7 @@ export const useCommandMenuHotKeys = () => {
const { openRecordsSearchPage } = useOpenRecordsSearchPageInSidePanel();
const { openAskAIPage } = useOpenAskAIPageInSidePanel();
const { openAskAiPage } = useOpenAskAiPageInSidePanel();
const { goBackFromSidePanel, goBackOneSubPageOrMainPage } =
useSidePanelHistory();
@@ -59,11 +59,11 @@ export const useCommandMenuHotKeys = () => {
keys: ['@'],
callback: () => {
if (isAiEnabled) {
openAskAIPage({ resetNavigationStack: true });
openAskAiPage({ resetNavigationStack: true });
}
},
containsModifier: false,
dependencies: [openAskAIPage, isAiEnabled],
dependencies: [openAskAiPage, isAiEnabled],
options: {
ignoreModifiers: true,
},
@@ -1,5 +1,5 @@
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { NavigationDrawerAIChatContent } from '@/ai/components/NavigationDrawerAIChatContent';
import { NavigationDrawerAiChatContent } from '@/ai/components/NavigationDrawerAiChatContent';
import { MainNavigationDrawerNavigationContent } from '@/navigation/components/MainNavigationDrawerNavigationContent';
import { MainNavigationDrawerTabsRow } from '@/navigation/components/MainNavigationDrawerTabsRow';
import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
@@ -27,7 +27,7 @@ export const MainNavigationDrawer = ({ className }: { className?: string }) => {
<NavigationDrawerScrollableContent>
{navigationDrawerActiveTab ===
NAVIGATION_DRAWER_TABS.AI_CHAT_HISTORY ? (
<NavigationDrawerAIChatContent />
<NavigationDrawerAiChatContent />
) : (
<MainNavigationDrawerNavigationContent />
)}
@@ -11,7 +11,7 @@ import { useIsMobile } from 'twenty-ui/utilities';
import { useContext } from 'react';
import { useSwitchToNewAIChat } from '@/ai/hooks/useSwitchToNewAIChat';
import { useSwitchToNewAiChat } from '@/ai/hooks/useSwitchToNewAiChat';
import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { navigationDrawerActiveTabState } from '@/ui/navigation/states/navigationDrawerActiveTabState';
@@ -140,7 +140,7 @@ export const MainNavigationDrawerTabsRow = () => {
);
const [navigationDrawerActiveTab, setNavigationDrawerActiveTab] =
useAtomState(navigationDrawerActiveTabState);
const { switchToNewChat } = useSwitchToNewAIChat();
const { switchToNewChat } = useSwitchToNewAiChat();
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const setIsNavigationDrawerExpanded = useSetAtomState(
isNavigationDrawerExpandedState,
@@ -1,4 +1,4 @@
import { useSwitchToNewAIChat } from '@/ai/hooks/useSwitchToNewAIChat';
import { useSwitchToNewAiChat } from '@/ai/hooks/useSwitchToNewAiChat';
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
import { useDefaultHomePagePath } from '@/navigation/hooks/useDefaultHomePagePath';
@@ -23,7 +23,7 @@ import {
import { NavigationBar } from 'twenty-ui/navigation';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
type NavigationBarItemName = 'main' | 'search' | 'newAIChat';
type NavigationBarItemName = 'main' | 'search' | 'newAiChat';
export const MobileNavigationBar = () => {
const navigate = useNavigate();
@@ -36,7 +36,7 @@ export const MobileNavigationBar = () => {
useAtomState(isNavigationDrawerExpandedState);
const [currentMobileNavigationDrawer, setCurrentMobileNavigationDrawer] =
useAtomState(currentMobileNavigationDrawerState);
const { switchToNewChat } = useSwitchToNewAIChat();
const { switchToNewChat } = useSwitchToNewAiChat();
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const { alphaSortedActiveNonSystemObjectMetadataItems } =
useFilteredObjectMetadataItems();
@@ -95,7 +95,7 @@ export const MobileNavigationBar = () => {
...(isAiEnabled
? [
{
name: 'newAIChat' as const,
name: 'newAiChat' as const,
Icon: IconMessageCirclePlus,
onClick: () => {
setIsNavigationDrawerExpanded(false);
@@ -74,7 +74,7 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
const isAdminEnabled =
(currentUser?.canImpersonate || currentUser?.canAccessFullAdminPanel) ??
false;
const isAIEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const isSupportChatConfigured =
supportChat?.supportDriver === 'FRONT' &&
isNonEmptyString(supportChat.supportFrontChatId);
@@ -183,7 +183,7 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
path: SettingsPath.AI,
Icon: IconSparkles,
isHidden:
!isAIEnabled || !permissionMap[PermissionFlagType.WORKSPACE],
!isAiEnabled || !permissionMap[PermissionFlagType.WORKSPACE],
modifier: 'new',
},
{
@@ -82,7 +82,7 @@ export const SettingsRolePermissionsObjectLevelObjectForm = ({
},
{
children: agent.label,
href: getSettingsPath(SettingsPath.AIAgentDetail, {
href: getSettingsPath(SettingsPath.AiAgentDetail, {
agentId: agent.id,
}),
},
@@ -112,7 +112,7 @@ export const SettingsRolePermissionsObjectLevelObjectForm = ({
const finishButtonPath =
fromAgentId && isDefined(agent)
? getSettingsPath(SettingsPath.AIAgentDetail, { agentId: agent.id })
? getSettingsPath(SettingsPath.AiAgentDetail, { agentId: agent.id })
: getSettingsPath(SettingsPath.RoleDetail, { roleId });
const objectPredicates =
@@ -30,7 +30,7 @@ type UseActionRolePermissionFlagConfigParams = {
export const useActionRolePermissionFlagConfig = ({
assignmentCapabilities,
}: UseActionRolePermissionFlagConfigParams = {}): SettingsRolePermissionsSettingPermission[] => {
const isAIEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const {
canBeAssignedToAgents = false,
@@ -154,7 +154,7 @@ export const useActionRolePermissionFlagConfig = ({
canBeAssignedToUsers && !canBeAssignedToAgents && !canBeAssignedToApiKeys;
return allPermissions.filter((permission) => {
if (permission.key === PermissionFlagType.AI && !isAIEnabled) {
if (permission.key === PermissionFlagType.AI && !isAiEnabled) {
return false;
}
@@ -179,6 +179,6 @@ export const useActionRolePermissionFlagConfig = ({
canBeAssignedToAgents,
canBeAssignedToUsers,
canBeAssignedToApiKeys,
isAIEnabled,
isAiEnabled,
]);
};
@@ -33,7 +33,7 @@ type UseSettingsRolePermissionFlagConfigParams = {
export const useSettingsRolePermissionFlagConfig = ({
assignmentCapabilities,
}: UseSettingsRolePermissionFlagConfigParams = {}): SettingsRolePermissionsSettingPermission[] => {
const isAIEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const {
canBeAssignedToAgents = false,
@@ -174,7 +174,7 @@ export const useSettingsRolePermissionFlagConfig = ({
canBeAssignedToUsers && !canBeAssignedToAgents && !canBeAssignedToApiKeys;
return allPermissions.filter((permission) => {
if (permission.key === PermissionFlagType.AI_SETTINGS && !isAIEnabled) {
if (permission.key === PermissionFlagType.AI_SETTINGS && !isAiEnabled) {
return false;
}
if (hasAssignmentCapabilities) {
@@ -198,6 +198,6 @@ export const useSettingsRolePermissionFlagConfig = ({
canBeAssignedToAgents,
canBeAssignedToUsers,
canBeAssignedToApiKeys,
isAIEnabled,
isAiEnabled,
]);
};
@@ -1,5 +1,5 @@
import { currentAIChatThreadState } from '@/ai/states/currentAIChatThreadState';
import { currentAIChatThreadTitleComponentFamilyState } from '@/ai/states/currentAIChatThreadTitleComponentFamilyState';
import { currentAiChatThreadState } from '@/ai/states/currentAiChatThreadState';
import { currentAiChatThreadTitleComponentFamilyState } from '@/ai/states/currentAiChatThreadTitleComponentFamilyState';
import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { styled } from '@linaria/react';
@@ -13,17 +13,17 @@ const StyledPageTitle = styled.div`
font-weight: ${themeCssVariables.font.weight.semiBold};
`;
export const SidePanelAskAIInfo = () => {
const currentAIChatThread = useAtomStateValue(currentAIChatThreadState);
const currentAIChatThreadTitle = useAtomComponentFamilyStateValue(
currentAIChatThreadTitleComponentFamilyState,
{ threadId: currentAIChatThread },
export const SidePanelAskAiInfo = () => {
const currentAiChatThread = useAtomStateValue(currentAiChatThreadState);
const currentAiChatThreadTitle = useAtomComponentFamilyStateValue(
currentAiChatThreadTitleComponentFamilyState,
{ threadId: currentAiChatThread },
);
return (
<StyledPageTitle>
<OverflowingTextWithTooltip
text={currentAIChatThreadTitle ?? t`Ask AI`}
text={currentAiChatThreadTitle ?? t`Ask AI`}
/>
</StyledPageTitle>
);
@@ -7,7 +7,7 @@ import {
import { selectedNavigationMenuItemIdInEditModeState } from '@/navigation-menu-item/common/states/selectedNavigationMenuItemIdInEditModeState';
import { useNavigationMenuItemSectionItems } from '@/navigation-menu-item/display/hooks/useNavigationMenuItemSectionItems';
import { SidePanelAskAIInfo } from '@/side-panel/components/SidePanelAskAIInfo';
import { SidePanelAskAiInfo } from '@/side-panel/components/SidePanelAskAiInfo';
import { SidePanelFolderInfo } from '@/side-panel/components/SidePanelFolderInfo';
import { SidePanelLinkInfo } from '@/side-panel/components/SidePanelLinkInfo';
import { SidePanelMultipleRecordsInfo } from '@/side-panel/components/SidePanelMultipleRecordsInfo';
@@ -114,10 +114,10 @@ export const SidePanelPageInfo = ({ pageChip }: SidePanelPageInfoProps) => {
);
}
const isAskAIPage = pageChip.page?.page === SidePanelPages.AskAI;
const isAskAiPage = pageChip.page?.page === SidePanelPages.AskAI;
if (isAskAIPage) {
return <SidePanelAskAIInfo />;
if (isAskAiPage) {
return <SidePanelAskAiInfo />;
}
if (pageChip.page?.page === SidePanelPages.NavigationMenuAddItem) {
@@ -1,4 +1,4 @@
import { useSwitchToNewAIChat } from '@/ai/hooks/useSwitchToNewAIChat';
import { useSwitchToNewAiChat } from '@/ai/hooks/useSwitchToNewAiChat';
import { SidePanelObjectFilterDropdown } from '@/side-panel/components/SidePanelObjectFilterDropdown';
import { sidePanelPageState } from '@/side-panel/states/sidePanelPageState';
import { sidePanelSearchObjectFilterState } from '@/side-panel/states/sidePanelSearchObjectFilterState';
@@ -22,7 +22,7 @@ export const SidePanelTopBarRightCornerIcon = () => {
const isMobile = useIsMobile();
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
const sidePanelPage = useAtomStateValue(sidePanelPageState);
const { switchToNewChat } = useSwitchToNewAIChat();
const { switchToNewChat } = useSwitchToNewAiChat();
const [sidePanelSearchObjectFilter, setSidePanelSearchObjectFilter] =
useAtomState(sidePanelSearchObjectFilterState);
@@ -37,12 +37,12 @@ export const SidePanelTopBarRightCornerIcon = () => {
);
}
const isOnAskAIPage = [
const isOnAskAiPage = [
SidePanelPages.AskAI,
SidePanelPages.ViewPreviousAIChats,
SidePanelPages.ViewPreviousAiChats,
].includes(sidePanelPage);
if (isMobile || !isAiEnabled || !isOnAskAIPage) {
if (isMobile || !isAiEnabled || !isOnAskAiPage) {
return null;
}
@@ -2,8 +2,8 @@ import { SidePanelCommandMenuItemDisplayPage } from '@/command-menu-item/display
import { SidePanelCommandMenuItemEditPage } from '@/command-menu-item/edit/components/SidePanelCommandMenuItemEditPage';
import { SidePanelNavigationMenuItemEditPage } from '@/navigation-menu-item/edit/side-panel/components/SidePanelNavigationMenuItemEditPage';
import { SidePanelNewSidebarItemPage } from '@/navigation-menu-item/edit/side-panel/components/SidePanelNewSidebarItemPage';
import { SidePanelAIChatThreadsPage } from '@/side-panel/pages/ai-chat-threads/components/SidePanelAIChatThreadsPage';
import { SidePanelAskAIPage } from '@/side-panel/pages/ask-ai/components/SidePanelAskAIPage';
import { SidePanelAiChatThreadsPage } from '@/side-panel/pages/ai-chat-threads/components/SidePanelAiChatThreadsPage';
import { SidePanelAskAiPage } from '@/side-panel/pages/ask-ai/components/SidePanelAskAiPage';
import { SidePanelCalendarEventPage } from '@/side-panel/pages/calendar-event/components/SidePanelCalendarEventPage';
import { SidePanelComposeEmailPage } from '@/side-panel/pages/compose-email/components/SidePanelComposeEmailPage';
import { SidePanelFrontComponentPage } from '@/side-panel/pages/front-component/components/SidePanelFrontComponentPage';
@@ -49,8 +49,8 @@ export const SIDE_PANEL_PAGES_CONFIG = new Map<SidePanelPages, React.ReactNode>(
[SidePanelPages.WorkflowStepView, <SidePanelWorkflowViewStep />],
[SidePanelPages.WorkflowRunStepView, <SidePanelWorkflowRunViewStep />],
[SidePanelPages.SearchRecords, <SidePanelSearchRecordsPage />],
[SidePanelPages.AskAI, <SidePanelAskAIPage />],
[SidePanelPages.ViewPreviousAIChats, <SidePanelAIChatThreadsPage />],
[SidePanelPages.AskAI, <SidePanelAskAiPage />],
[SidePanelPages.ViewPreviousAiChats, <SidePanelAiChatThreadsPage />],
[
SidePanelPages.PageLayoutDashboardWidgetTypeSelect,
<SidePanelPageLayoutDashboardWidgetTypeSelect />,
@@ -2,7 +2,7 @@ import { act, renderHook } from '@testing-library/react';
import { Provider as JotaiProvider } from 'jotai';
import { type ReactNode } from 'react';
import { useOpenAskAIPageInSidePanel } from '@/side-panel/hooks/useOpenAskAIPageInSidePanel';
import { useOpenAskAiPageInSidePanel } from '@/side-panel/hooks/useOpenAskAiPageInSidePanel';
import { isSidePanelOpenedState } from '@/side-panel/states/isSidePanelOpenedState';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { SidePanelPages } from 'twenty-shared/types';
@@ -23,19 +23,19 @@ const Wrapper = ({ children }: { children: ReactNode }) => (
<JotaiProvider store={jotaiStore}>{children}</JotaiProvider>
);
describe('useOpenAskAIPageInSidePanel', () => {
describe('useOpenAskAiPageInSidePanel', () => {
beforeEach(() => {
jest.clearAllMocks();
jotaiStore.set(isSidePanelOpenedState.atom, false);
});
it('should navigate to AskAI page with correct defaults', () => {
const { result } = renderHook(() => useOpenAskAIPageInSidePanel(), {
const { result } = renderHook(() => useOpenAskAiPageInSidePanel(), {
wrapper: Wrapper,
});
act(() => {
result.current.openAskAIPage();
result.current.openAskAiPage();
});
expect(navigateSidePanelMenuMock).toHaveBeenCalledWith(
@@ -50,12 +50,12 @@ describe('useOpenAskAIPageInSidePanel', () => {
it('should use resetNavigationStack from argument when provided', () => {
jotaiStore.set(isSidePanelOpenedState.atom, true);
const { result } = renderHook(() => useOpenAskAIPageInSidePanel(), {
const { result } = renderHook(() => useOpenAskAiPageInSidePanel(), {
wrapper: Wrapper,
});
act(() => {
result.current.openAskAIPage({ resetNavigationStack: false });
result.current.openAskAiPage({ resetNavigationStack: false });
});
expect(navigateSidePanelMenuMock).toHaveBeenCalledWith(
@@ -68,12 +68,12 @@ describe('useOpenAskAIPageInSidePanel', () => {
it('should default resetNavigationStack to isSidePanelOpened', () => {
jotaiStore.set(isSidePanelOpenedState.atom, true);
const { result } = renderHook(() => useOpenAskAIPageInSidePanel(), {
const { result } = renderHook(() => useOpenAskAiPageInSidePanel(), {
wrapper: Wrapper,
});
act(() => {
result.current.openAskAIPage();
result.current.openAskAiPage();
});
expect(navigateSidePanelMenuMock).toHaveBeenCalledWith(
@@ -7,11 +7,11 @@ import { SidePanelPages } from 'twenty-shared/types';
import { IconSparkles } from 'twenty-ui/display';
import { v4 } from 'uuid';
export const useOpenAskAIPageInSidePanel = () => {
export const useOpenAskAiPageInSidePanel = () => {
const { navigateSidePanelMenu } = useSidePanelMenu();
const isSidePanelOpened = useAtomStateValue(isSidePanelOpenedState);
const openAskAIPage = useCallback(
const openAskAiPage = useCallback(
({
resetNavigationStack,
}: {
@@ -34,6 +34,6 @@ export const useOpenAskAIPageInSidePanel = () => {
);
return {
openAskAIPage,
openAskAiPage,
};
};
@@ -1,4 +1,4 @@
import { AIChatThreadsList } from '@/ai/components/AIChatThreadsList';
import { AiChatThreadsList } from '@/ai/components/AiChatThreadsList';
import { styled } from '@linaria/react';
const StyledContainer = styled.div`
@@ -6,10 +6,10 @@ const StyledContainer = styled.div`
width: 100%;
`;
export const SidePanelAIChatThreadsPage = () => {
export const SidePanelAiChatThreadsPage = () => {
return (
<StyledContainer>
<AIChatThreadsList />
<AiChatThreadsList />
</StyledContainer>
);
};
@@ -1,15 +1,15 @@
import { styled } from '@linaria/react';
import { AIChatTab } from '@/ai/components/AIChatTab';
import { AiChatTab } from '@/ai/components/AiChatTab';
const StyledContainer = styled.div`
height: 100%;
width: 100%;
`;
export const SidePanelAskAIPage = () => {
export const SidePanelAskAiPage = () => {
return (
<StyledContainer>
<AIChatTab />
<AiChatTab />
</StyledContainer>
);
};
@@ -85,7 +85,7 @@ export const WorkflowStepFooter = ({
const handleViewAgent = () => {
closeDropdown(dropdownId);
if (isDefined(agentId)) {
navigateSettings(SettingsPath.AIAgentDetail, { agentId });
navigateSettings(SettingsPath.AiAgentDetail, { agentId });
}
};
@@ -1,8 +1,8 @@
import { gql } from '@apollo/client';
export const GET_AI_SYSTEM_PROMPT_PREVIEW = gql`
query GetAISystemPromptPreview {
getAISystemPromptPreview {
query GetAiSystemPromptPreview {
getAiSystemPromptPreview {
sections {
title
content
@@ -93,10 +93,10 @@ export const SettingsAdminNewAiProvider = () => {
const hasSelected = selectedModelsDevId !== null || isCustomMode;
const npmPackage = form.watch('npm');
const isBedrock = npmPackage === '@ai-sdk/amazon-bedrock';
const isOpenAICompatible = npmPackage === '@ai-sdk/openai-compatible';
const isOpenAiCompatible = npmPackage === '@ai-sdk/openai-compatible';
const needsApiKey = !isBedrock;
const isModelsDevWithoutNativeSdk =
selectedModelsDevId !== null && isOpenAICompatible;
selectedModelsDevId !== null && isOpenAiCompatible;
const handleProviderSelected = (providerId: string) => {
setSelectedModelsDevId(providerId);
@@ -150,7 +150,7 @@ export const SettingsAdminNewAiProvider = () => {
values.apiKey.trim() && {
apiKey: values.apiKey.trim(),
}),
...(isOpenAICompatible &&
...(isOpenAiCompatible &&
values.baseUrl.trim() && {
baseUrl: values.baseUrl.trim(),
}),
@@ -178,7 +178,7 @@ export const SettingsAdminNewAiProvider = () => {
}
}
if (!isBedrock && !isOpenAICompatible && !values.apiKey.trim()) {
if (!isBedrock && !isOpenAiCompatible && !values.apiKey.trim()) {
form.setError('apiKey', {
type: 'manual',
message: t`API key is required`,
@@ -187,7 +187,7 @@ export const SettingsAdminNewAiProvider = () => {
return;
}
if (isOpenAICompatible && !values.baseUrl.trim()) {
if (isOpenAiCompatible && !values.baseUrl.trim()) {
form.setError('baseUrl', {
type: 'manual',
message: t`Base URL is required`,
@@ -325,7 +325,7 @@ export const SettingsAdminNewAiProvider = () => {
</Section>
)}
{isOpenAICompatible && (
{isOpenAiCompatible && (
<Section>
<H2Title
title={t`Base URL`}
@@ -22,10 +22,10 @@ import {
} from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
import { UndecoratedLink } from 'twenty-ui/navigation';
import { SettingsAIMoreTab } from '~/pages/settings/ai/components/SettingsAIMoreTab';
import { SettingsAiMoreTab } from '~/pages/settings/ai/components/SettingsAiMoreTab';
import { SettingsAgentToolsTab } from '~/pages/settings/ai/components/SettingsAgentToolsTab';
import { SettingsAIModelsTab } from './components/SettingsAIModelsTab';
import { SettingsAIUsageTab } from './components/SettingsAIUsageTab';
import { SettingsAiModelsTab } from './components/SettingsAiModelsTab';
import { SettingsAiUsageTab } from './components/SettingsAiUsageTab';
import { SettingsAgentSkills } from './components/SettingsAgentSkills';
import { SETTINGS_AI_TABS } from './constants/SettingsAiTabs';
@@ -117,7 +117,7 @@ export const SettingsAI = () => {
title={t`AI`}
actionButton={
isSkillsTab ? (
<UndecoratedLink to={getSettingsPath(SettingsPath.AINewSkill)}>
<UndecoratedLink to={getSettingsPath(SettingsPath.AiNewSkill)}>
<Button
Icon={IconPlus}
title={t`New Skill`}
@@ -149,11 +149,11 @@ export const SettingsAI = () => {
tabs={tabs}
componentInstanceId={SETTINGS_AI_TABS.COMPONENT_INSTANCE_ID}
/>
{isModelsTab && <SettingsAIModelsTab />}
{isModelsTab && <SettingsAiModelsTab />}
{isSkillsTab && <SettingsAgentSkills />}
{isToolsTab && <SettingsAgentToolsTab />}
{isUsageTab && <SettingsAIUsageTab />}
{isMoreTab && <SettingsAIMoreTab />}
{isUsageTab && <SettingsAiUsageTab />}
{isMoreTab && <SettingsAiMoreTab />}
</SettingsPageContainer>
</SubMenuTopBarContainer>
);
@@ -1,4 +1,4 @@
import { AIChatAssistantMessageRenderer } from '@/ai/components/AIChatAssistantMessageRenderer';
import { AiChatAssistantMessageRenderer } from '@/ai/components/AiChatAssistantMessageRenderer';
import { mapDBMessagesToUIMessages } from '@/ai/utils/mapDBMessagesToUIMessages';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
@@ -84,7 +84,7 @@ export const SettingsAgentTurnDetail = () => {
{ children: t`AI`, href: getSettingsPath(SettingsPath.AI) },
{
children: t`Agent`,
href: getSettingsPath(SettingsPath.AIAgentDetail).replace(
href: getSettingsPath(SettingsPath.AiAgentDetail).replace(
':agentId',
agentId || '',
),
@@ -130,7 +130,7 @@ export const SettingsAgentTurnDetail = () => {
{ children: t`AI`, href: getSettingsPath(SettingsPath.AI) },
{
children: t`Agent`,
href: getSettingsPath(SettingsPath.AIAgentDetail).replace(
href: getSettingsPath(SettingsPath.AiAgentDetail).replace(
':agentId',
agentId || '',
),
@@ -171,7 +171,7 @@ export const SettingsAgentTurnDetail = () => {
<StyledMessageBubble key={message.id}>
<StyledMessageRole>{roleLabel}</StyledMessageRole>
<StyledMessageContent>
<AIChatAssistantMessageRenderer
<AiChatAssistantMessageRenderer
messageParts={message.parts}
isLastMessageStreaming={false}
/>
@@ -28,14 +28,14 @@ const StyledTitleContainer = styled.div`
margin-top: ${themeCssVariables.spacing[2]};
`;
export const SettingsAIPrompts = () => {
export const SettingsAiPrompts = () => {
const currentWorkspaceMember = useAtomStateValue(currentWorkspaceMemberState);
const { data: previewData, loading: previewLoading } = useQuery(
GetAiSystemPromptPreviewDocument,
);
const preview = previewData?.getAISystemPromptPreview;
const preview = previewData?.getAiSystemPromptPreview;
const sections = preview?.sections ?? [];
const buildUserContextPreview = (): string => {
@@ -14,7 +14,7 @@ import { SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
import { Section } from 'twenty-ui/layout';
export const SettingsAIUsageUserDetail = () => {
export const SettingsAiUsageUserDetail = () => {
const { t: tLingui } = useLingui();
const { userWorkspaceId } = useParams<{ userWorkspaceId: string }>();
@@ -239,7 +239,7 @@ export const SettingsAgentLogsTab = ({
>
{latestEvaluation && (
<UndecoratedLink
to={getSettingsPath(SettingsPath.AIAgentTurnDetail)
to={getSettingsPath(SettingsPath.AiAgentTurnDetail)
.replace(':agentId', agentId)
.replace(':turnId', turn.id)}
>
@@ -20,7 +20,7 @@ import {
CreateOneRoleDocument,
GetRolesDocument,
} from '~/generated-metadata/graphql';
import { type SettingsAIAgentFormValues } from '~/pages/settings/ai/hooks/useSettingsAgentFormState';
import { type SettingsAiAgentFormValues } from '~/pages/settings/ai/hooks/useSettingsAgentFormState';
const StyledWarningText = styled.div`
color: ${themeCssVariables.font.color.tertiary};
@@ -29,10 +29,10 @@ const StyledWarningText = styled.div`
`;
type SettingsAgentRoleTabProps = {
formValues: SettingsAIAgentFormValues;
formValues: SettingsAiAgentFormValues;
onFieldChange: (
field: keyof SettingsAIAgentFormValues,
value: SettingsAIAgentFormValues[keyof SettingsAIAgentFormValues],
field: keyof SettingsAiAgentFormValues,
value: SettingsAiAgentFormValues[keyof SettingsAiAgentFormValues],
) => void;
disabled: boolean;
agentId?: string;
@@ -21,7 +21,7 @@ import { type Agent } from '~/generated-metadata/graphql';
import { SettingsAgentDeleteConfirmationModal } from '~/pages/settings/ai/components/SettingsAgentDeleteConfirmationModal';
import { SettingsAgentResponseFormat } from '~/pages/settings/ai/components/SettingsAgentResponseFormat';
import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/computeMetadataNameFromLabel';
import { type SettingsAIAgentFormValues } from '~/pages/settings/ai/hooks/useSettingsAgentFormState';
import { type SettingsAiAgentFormValues } from '~/pages/settings/ai/hooks/useSettingsAgentFormState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
const StyledFormContainer = styled.div`
@@ -49,10 +49,10 @@ const StyledErrorMessage = styled.div`
const DELETE_AGENT_MODAL_ID = 'delete-agent-modal';
type SettingsAgentSettingsTabProps = {
formValues: SettingsAIAgentFormValues;
formValues: SettingsAiAgentFormValues;
onFieldChange: (
field: keyof SettingsAIAgentFormValues,
value: SettingsAIAgentFormValues[keyof SettingsAIAgentFormValues],
field: keyof SettingsAiAgentFormValues,
value: SettingsAiAgentFormValues[keyof SettingsAiAgentFormValues],
) => void;
disabled: boolean;
agent?: Agent;
@@ -85,7 +85,7 @@ export const SettingsAgentSkillsTable = ({
}
link={
skill.isActive
? getSettingsPath(SettingsPath.AISkillDetail, {
? getSettingsPath(SettingsPath.AiSkillDetail, {
skillId: skill.id,
})
: undefined
@@ -8,7 +8,7 @@ import { OverflowingTextWithTooltip, useIcons } from 'twenty-ui/display';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { type Agent } from '~/generated-metadata/graphql';
export type SettingsAIAgentTableRowProps = {
export type SettingsAiAgentTableRowProps = {
action: ReactNode;
agent: Agent;
link?: string;
@@ -21,11 +21,11 @@ const StyledIconContainer = styled.div`
height: ${themeCssVariables.spacing[4]};
`;
export const SettingsAIAgentTableRow = ({
export const SettingsAiAgentTableRow = ({
action,
agent,
link,
}: SettingsAIAgentTableRowProps) => {
}: SettingsAiAgentTableRowProps) => {
const { theme } = useContext(ThemeContext);
const { getIcon } = useIcons();
const Icon = getIcon(agent.icon || 'IconRobot');
@@ -24,8 +24,8 @@ import { FindManyAgentsDocument } from '~/generated-metadata/graphql';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import {
AI_AGENT_TABLE_ROW_GRID_TEMPLATE_COLUMNS,
SettingsAIAgentTableRow,
} from './SettingsAIAgentTableRow';
SettingsAiAgentTableRow,
} from './SettingsAiAgentTableRow';
const StyledSearchContainer = styled.div`
margin-bottom: ${themeCssVariables.spacing[2]};
@@ -39,7 +39,7 @@ const StyledTableHeaderRowContainer = styled.div`
margin-bottom: ${themeCssVariables.spacing[2]};
`;
export const SettingsAIAgentsTable = () => {
export const SettingsAiAgentsTable = () => {
const { theme } = useContext(ThemeContext);
const { data, loading } = useQuery(FindManyAgentsDocument);
@@ -104,13 +104,13 @@ export const SettingsAIAgentsTable = () => {
gridTemplateColumns={AI_AGENT_TABLE_ROW_GRID_TEMPLATE_COLUMNS}
>
{SETTINGS_AI_AGENT_TABLE_METADATA.fields.map(
(settingsAIAgentTableMetadataField) => (
(settingsAiAgentTableMetadataField) => (
<SortableTableHeader
key={settingsAIAgentTableMetadataField.fieldName}
fieldName={settingsAIAgentTableMetadataField.fieldName}
label={t(settingsAIAgentTableMetadataField.fieldLabel)}
key={settingsAiAgentTableMetadataField.fieldName}
fieldName={settingsAiAgentTableMetadataField.fieldName}
label={t(settingsAiAgentTableMetadataField.fieldLabel)}
tableId={SETTINGS_AI_AGENT_TABLE_METADATA.tableId}
align={settingsAIAgentTableMetadataField.align}
align={settingsAiAgentTableMetadataField.align}
initialSort={SETTINGS_AI_AGENT_TABLE_METADATA.initialSort}
/>
),
@@ -123,7 +123,7 @@ export const SettingsAIAgentsTable = () => {
<Skeleton height={32} borderRadius={4} key={index} />
))}
{filteredAgents.map((agent) => (
<SettingsAIAgentTableRow
<SettingsAiAgentTableRow
key={agent.id}
agent={agent}
action={
@@ -132,7 +132,7 @@ export const SettingsAIAgentsTable = () => {
stroke={theme.icon.stroke.sm}
/>
}
link={getSettingsPath(SettingsPath.AIAgentDetail, {
link={getSettingsPath(SettingsPath.AiAgentDetail, {
agentId: agent.id,
})}
/>
@@ -51,7 +51,7 @@ const StyledEditorContainer = styled.div`
type McpAuthMethod = 'oauth' | 'api-key';
export const SettingsAIMCP = () => {
export const SettingsAiMCP = () => {
const { t } = useLingui();
const { copyToClipboard } = useCopyToClipboard();
const [authMethod, setAuthMethod] = useState<McpAuthMethod>('oauth');
@@ -34,7 +34,7 @@ const StyledCustomModelsContainer = styled.div`
padding-top: ${themeCssVariables.spacing[4]};
`;
export const SettingsAIModelsTab = () => {
export const SettingsAiModelsTab = () => {
const { enqueueErrorSnackBar } = useSnackBar();
const [currentWorkspace, setCurrentWorkspace] = useAtomState(
currentWorkspaceState,
@@ -19,7 +19,7 @@ import {
GetAiSystemPromptPreviewDocument,
UpdateWorkspaceDocument,
} from '~/generated-metadata/graphql';
import { SettingsAIMCP } from '~/pages/settings/ai/components/SettingsAIMCP';
import { SettingsAiMCP } from '~/pages/settings/ai/components/SettingsAiMCP';
import { formatNumber } from '~/utils/format/formatNumber';
const StyledFormContainer = styled.div`
@@ -28,7 +28,7 @@ const StyledFormContainer = styled.div`
gap: ${themeCssVariables.spacing[4]};
`;
export const SettingsAIMoreTab = () => {
export const SettingsAiMoreTab = () => {
const { theme } = useContext(ThemeContext);
const { enqueueErrorSnackBar } = useSnackBar();
const [currentWorkspace, setCurrentWorkspace] = useAtomState(
@@ -87,7 +87,7 @@ export const SettingsAIMoreTab = () => {
};
const systemPromptTokenCount =
previewData?.getAISystemPromptPreview.estimatedTokenCount;
previewData?.getAiSystemPromptPreview.estimatedTokenCount;
const systemPromptDescription = isDefined(systemPromptTokenCount)
? t`Read the system prompts to understand how the AI works (~${formatNumber(
systemPromptTokenCount,
@@ -128,7 +128,7 @@ export const SettingsAIMoreTab = () => {
/>
</StyledFormContainer>
</Section>
<SettingsAIMCP />
<SettingsAiMCP />
<Section>
<H2Title
@@ -136,7 +136,7 @@ export const SettingsAIMoreTab = () => {
description={systemPromptDescription}
/>
<UndecoratedLink to={getSettingsPath(SettingsPath.AIPrompts)}>
<UndecoratedLink to={getSettingsPath(SettingsPath.AiPrompts)}>
<SettingsCard
Icon={<IconPrompt size={theme.icon.size.md} />}
title={t`Read system prompts`}
@@ -18,7 +18,7 @@ import { Tag } from 'twenty-ui/components';
import { H2Title, IconLock } from 'twenty-ui/display';
import { Section } from 'twenty-ui/layout';
export const SettingsAIUsageTab = () => {
export const SettingsAiUsageTab = () => {
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
const billing = useAtomStateValue(billingState);
const isBillingEnabled = billing?.isBillingEnabled ?? false;
@@ -130,7 +130,7 @@ export const SettingsAIUsageTab = () => {
description={t`Click a user to see their daily breakdown.`}
operationTypes={AI_OPERATION_TYPES}
getDetailPath={(userWorkspaceId) =>
getSettingsPath(SettingsPath.AIUsageUserDetail, {
getSettingsPath(SettingsPath.AiUsageUserDetail, {
userWorkspaceId,
})
}
@@ -115,7 +115,7 @@ export const SettingsToolsTable = () => {
const isCustom = (item: ToolItem) => isDefined(item.applicationId);
const getToolLink = (item: ToolItem) =>
getSettingsPath(SettingsPath.AIToolDetail, {
getSettingsPath(SettingsPath.AiToolDetail, {
toolIdentifier: item.identifier,
});
@@ -3,7 +3,7 @@ import { msg } from '@lingui/core/macro';
import { type Agent } from '~/generated-metadata/graphql';
export const SETTINGS_AI_AGENT_TABLE_METADATA: TableMetadata<Agent> = {
tableId: 'settingsAIAgent',
tableId: 'settingsAiAgent',
fields: [
{
fieldLabel: msg`Name`,
@@ -10,7 +10,7 @@ import { TextArea } from '@/ui/input/components/TextArea';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/computeMetadataNameFromLabel';
import { type SettingsAIAgentFormValues } from '~/pages/settings/ai/hooks/useSettingsAgentFormState';
import { type SettingsAiAgentFormValues } from '~/pages/settings/ai/hooks/useSettingsAgentFormState';
const StyledFormContainer = styled.div`
display: flex;
@@ -34,20 +34,20 @@ const StyledErrorMessage = styled.div`
margin-top: ${themeCssVariables.spacing[1]};
`;
type SettingsAIAgentFormProps = {
formValues: SettingsAIAgentFormValues;
type SettingsAiAgentFormProps = {
formValues: SettingsAiAgentFormValues;
onFieldChange: (
field: keyof SettingsAIAgentFormValues,
value: SettingsAIAgentFormValues[keyof SettingsAIAgentFormValues],
field: keyof SettingsAiAgentFormValues,
value: SettingsAiAgentFormValues[keyof SettingsAiAgentFormValues],
) => void;
disabled: boolean;
};
export const SettingsAIAgentForm = ({
export const SettingsAiAgentForm = ({
formValues,
onFieldChange,
disabled,
}: SettingsAIAgentFormProps) => {
}: SettingsAiAgentFormProps) => {
const { t } = useLingui();
const { options: modelOptions } = useAiModelOptions();
@@ -1,14 +1,14 @@
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { type z } from 'zod';
import { settingsAIAgentFormSchema } from '~/pages/settings/ai/validation-schemas/settingsAIAgentFormSchema';
import { settingsAiAgentFormSchema } from '~/pages/settings/ai/validation-schemas/settingsAiAgentFormSchema';
export type SettingsAIAgentFormValues = z.infer<
typeof settingsAIAgentFormSchema
export type SettingsAiAgentFormValues = z.infer<
typeof settingsAiAgentFormSchema
>;
export const useSettingsAgentFormState = (mode: 'create' | 'edit') => {
const [formValues, setFormValues] = useState<SettingsAIAgentFormValues>({
const [formValues, setFormValues] = useState<SettingsAiAgentFormValues>({
name: '',
label: '',
description: '',
@@ -29,7 +29,7 @@ export const useSettingsAgentFormState = (mode: 'create' | 'edit') => {
const validateForm = (): boolean => {
try {
settingsAIAgentFormSchema.parse(formValues);
settingsAiAgentFormSchema.parse(formValues);
return true;
} catch {
return false;
@@ -37,13 +37,13 @@ export const useSettingsAgentFormState = (mode: 'create' | 'edit') => {
};
const handleFieldChange = (
field: keyof SettingsAIAgentFormValues,
value: SettingsAIAgentFormValues[keyof SettingsAIAgentFormValues],
field: keyof SettingsAiAgentFormValues,
value: SettingsAiAgentFormValues[keyof SettingsAiAgentFormValues],
) => {
setFormValues((prev) => ({ ...prev, [field]: value }));
};
const resetForm = (values?: Partial<SettingsAIAgentFormValues>) => {
const resetForm = (values?: Partial<SettingsAiAgentFormValues>) => {
if (isDefined(values)) {
setFormValues((prev) => ({ ...prev, ...values }));
} else {
@@ -2,7 +2,7 @@ import { type AgentResponseSchema } from 'twenty-shared/ai';
import { z } from 'zod';
import { zodNonEmptyString } from '~/types/ZodNonEmptyString';
export const settingsAIAgentFormSchema = z.object({
export const settingsAiAgentFormSchema = z.object({
name: z.string().optional(),
label: zodNonEmptyString,
description: z.string().nullish(),
@@ -36,6 +36,6 @@ export const settingsAIAgentFormSchema = z.object({
evaluationInputs: z.array(z.string()).default([]),
});
export type SettingsAIAgentFormValues = z.infer<
typeof settingsAIAgentFormSchema
export type SettingsAiAgentFormValues = z.infer<
typeof settingsAiAgentFormSchema
>;
@@ -9,7 +9,7 @@ import { getSettingsPath, isDefined } from 'twenty-shared/utils';
import { H2Title } from 'twenty-ui/display';
import { Section } from 'twenty-ui/layout';
import { type Application } from '~/generated-metadata/graphql';
import { SettingsAIAgentsTable } from '~/pages/settings/ai/components/SettingsAIAgentsTable';
import { SettingsAiAgentsTable } from '~/pages/settings/ai/components/SettingsAiAgentsTable';
import {
SettingsApplicationDataTable,
type ApplicationDataTableRow,
@@ -139,7 +139,7 @@ export const SettingsApplicationDetailContentTab = ({
title={t`Agents`}
description={t`Agents powering this app`}
/>
<SettingsAIAgentsTable />
<SettingsAiAgentsTable />
</Section>
)}
</>
@@ -45,7 +45,7 @@ export const SettingsRoleAddObjectLevel = () => {
},
{
children: agent.label,
href: getSettingsPath(SettingsPath.AIAgentDetail, {
href: getSettingsPath(SettingsPath.AiAgentDetail, {
agentId: agent.id,
}),
},

Some files were not shown because too many files have changed in this diff Show More