chore: Update flags for self-hosting agents (#40639)

/ok-to-test tags="@tag.Sanity"

<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/14994848262>
> Commit: 64bdb8cd0606bbc4c1b11d69b2d0e7cd7b5dd78a
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=14994848262&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Tue, 13 May 2025 11:39:41 UTC
<!-- end of auto-generated comment: Cypress test results  -->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new feature flag for AI agent instances, allowing for
more granular control over AI agent-related functionality.

- **Refactor**
- Updated various components and selectors to use the new AI agent
instance feature flag and related selectors, replacing previous flags
and logic.
- Separated agent and non-agent template handling for clearer template
management.
- Improved feature flag override capabilities, enabling dynamic
overrides via external sources.
- Added new selectors to better represent AI agent app and creation
states.
- Refined UI components and modals to reflect updated AI agent state
flags.
- Enhanced user authentication and signup flows with updated feature
flag conditions.

- **Bug Fixes**
- Ensured consistent UI behavior and conditional rendering based on the
updated feature flag logic.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Pawan Kumar 2025-05-13 17:36:58 +05:30 committed by GitHub
parent 04b3bc9830
commit d036064beb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 202 additions and 153 deletions

View File

@ -58,6 +58,7 @@ export const FEATURE_FLAG = {
"license_external_saas_plugins_enabled", "license_external_saas_plugins_enabled",
release_computation_cache_enabled: "release_computation_cache_enabled", release_computation_cache_enabled: "release_computation_cache_enabled",
release_ai_chat_integrations_enabled: "release_ai_chat_integrations_enabled", release_ai_chat_integrations_enabled: "release_ai_chat_integrations_enabled",
license_ai_agent_instance_enabled: "license_ai_agent_instance_enabled",
} as const; } as const;
export type FeatureFlag = keyof typeof FEATURE_FLAG; export type FeatureFlag = keyof typeof FEATURE_FLAG;
@ -106,6 +107,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
license_external_saas_plugins_enabled: false, license_external_saas_plugins_enabled: false,
release_computation_cache_enabled: false, release_computation_cache_enabled: false,
release_ai_chat_integrations_enabled: false, release_ai_chat_integrations_enabled: false,
license_ai_agent_instance_enabled: false,
}; };
export const AB_TESTING_EVENT_KEYS = { export const AB_TESTING_EVENT_KEYS = {

View File

@ -6,9 +6,9 @@ import {
} from "ee/pages/AdminSettings/config/types"; } from "ee/pages/AdminSettings/config/types";
import { AuditLogsUpgradePage } from "../../Upgrade/AuditLogsUpgradePage"; import { AuditLogsUpgradePage } from "../../Upgrade/AuditLogsUpgradePage";
import store from "store"; import store from "store";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
const isAIAgentFlowEnabled = getIsAiAgentFlowEnabled(store.getState()); const isAIAgentInstanceEnabled = getIsAiAgentInstanceEnabled(store.getState());
export const config: AdminConfigType = { export const config: AdminConfigType = {
icon: "file-list-2-line", icon: "file-list-2-line",
@ -19,5 +19,5 @@ export const config: AdminConfigType = {
title: "Audit logs", title: "Audit logs",
canSave: false, canSave: false,
isFeatureEnabled: false, isFeatureEnabled: false,
isEnterprise: isAIAgentFlowEnabled ? true : false, isEnterprise: isAIAgentInstanceEnabled ? true : false,
} as AdminConfigType; } as AdminConfigType;

View File

@ -16,7 +16,7 @@ import { PrivateEmbedSettings } from "ee/pages/Applications/PrivateEmbedSettings
import { getCurrentApplication } from "ee/selectors/applicationSelectors"; import { getCurrentApplication } from "ee/selectors/applicationSelectors";
import { useIsCloudBillingEnabled } from "hooks"; import { useIsCloudBillingEnabled } from "hooks";
import { ChromeExtensionBanner } from "ee/pages/Applications/ChromeExtensionBanner"; import { ChromeExtensionBanner } from "ee/pages/Applications/ChromeExtensionBanner";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
export const StyledPropertyHelpLabel = styled(PropertyHelpLabel)` export const StyledPropertyHelpLabel = styled(PropertyHelpLabel)`
.bp3-popover-content > div { .bp3-popover-content > div {
@ -53,10 +53,10 @@ export function ShareModal() {
const currentApplicationDetails = useSelector(getCurrentApplication); const currentApplicationDetails = useSelector(getCurrentApplication);
const isPublicApp = currentApplicationDetails?.isPublic || false; const isPublicApp = currentApplicationDetails?.isPublic || false;
const isCloudBillingEnabled = useIsCloudBillingEnabled(); const isCloudBillingEnabled = useIsCloudBillingEnabled();
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
const snippetUrl = getSnippetUrl( const snippetUrl = getSnippetUrl(
embedSnippet.appViewEndPoint, embedSnippet.appViewEndPoint,
isPublicApp || isAiAgentFlowEnabled, isPublicApp || isAgentApp,
selectedMethod, selectedMethod,
); );
@ -92,7 +92,7 @@ export function ShareModal() {
</div> </div>
)} )}
{Boolean(isAiAgentFlowEnabled) === false && ( {Boolean(isAgentApp) === false && (
<Switch <Switch
data-testid={"show-navigation-bar-toggle"} data-testid={"show-navigation-bar-toggle"}
defaultSelected={embedSnippet.currentEmbedSetting?.showNavigationBar} defaultSelected={embedSnippet.currentEmbedSetting?.showNavigationBar}
@ -107,7 +107,7 @@ export function ShareModal() {
</Switch> </Switch>
)} )}
{!isPublicApp && !isAiAgentFlowEnabled && ( {!isPublicApp && !isAgentApp && (
<PrivateEmbedSettings <PrivateEmbedSettings
selectedMethod={selectedMethod} selectedMethod={selectedMethod}
setSelectedMethod={setSelectedMethod} setSelectedMethod={setSelectedMethod}
@ -142,10 +142,10 @@ export function AppSettings() {
); );
const currentApplicationDetails = useSelector(getCurrentApplication); const currentApplicationDetails = useSelector(getCurrentApplication);
const isPublicApp = currentApplicationDetails?.isPublic || false; const isPublicApp = currentApplicationDetails?.isPublic || false;
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
const snippetUrl = getSnippetUrl( const snippetUrl = getSnippetUrl(
embedSnippet.appViewEndPoint, embedSnippet.appViewEndPoint,
isPublicApp || isAiAgentFlowEnabled, isPublicApp || isAgentApp,
selectedMethod, selectedMethod,
); );
const isCloudBillingEnabled = useIsCloudBillingEnabled(); const isCloudBillingEnabled = useIsCloudBillingEnabled();
@ -183,7 +183,7 @@ export function AppSettings() {
</div> </div>
)} )}
{Boolean(isAiAgentFlowEnabled) === false && ( {Boolean(isAgentApp) === false && (
<Switch <Switch
data-testid={"show-navigation-bar-toggle"} data-testid={"show-navigation-bar-toggle"}
defaultSelected={ defaultSelected={
@ -200,7 +200,7 @@ export function AppSettings() {
</Switch> </Switch>
)} )}
{!isPublicApp && !isAiAgentFlowEnabled && ( {!isPublicApp && !isAgentApp && (
<PrivateEmbedSettings <PrivateEmbedSettings
selectedMethod={selectedMethod} selectedMethod={selectedMethod}
setSelectedMethod={setSelectedMethod} setSelectedMethod={setSelectedMethod}
@ -222,9 +222,9 @@ export function EmbedSnippetTab({
}) { }) {
const currentApplicationDetails = useSelector(getCurrentApplication); const currentApplicationDetails = useSelector(getCurrentApplication);
const isPublicApp = currentApplicationDetails?.isPublic || false; const isPublicApp = currentApplicationDetails?.isPublic || false;
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
if (!isPublicApp && !isAiAgentFlowEnabled) { if (!isPublicApp && !isAgentApp) {
return ( return (
<div className="flex flex-col gap-6"> <div className="flex flex-col gap-6">
<PrivateEmbeddingContent <PrivateEmbeddingContent

View File

@ -18,7 +18,10 @@ import {
NO_WORKSPACE_HEADING, NO_WORKSPACE_HEADING,
WORKSPACES_HEADING, WORKSPACES_HEADING,
} from "ee/constants/messages"; } from "ee/constants/messages";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import {
getIsAiAgentFlowEnabled,
getIsAiAgentInstanceEnabled,
} from "ee/selectors/aiAgentSelectors";
import type { ApplicationPayload } from "entities/Application"; import type { ApplicationPayload } from "entities/Application";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import { createWorkspaceSubmitHandler } from "ee/pages/workspace/helpers"; import { createWorkspaceSubmitHandler } from "ee/pages/workspace/helpers";
@ -129,7 +132,6 @@ import CreateNewAppFromTemplatesWrapper from "./CreateNewAppFromTemplateModal/Cr
import { getAssetUrl } from "ee/utils/airgapHelpers"; import { getAssetUrl } from "ee/utils/airgapHelpers";
import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants";
import { LayoutSystemTypes } from "layoutSystems/types"; import { LayoutSystemTypes } from "layoutSystems/types";
import { getIsAnvilLayoutEnabled } from "layoutSystems/anvil/integrations/selectors";
import OldGitSyncModal from "pages/Editor/gitSync/GitSyncModal"; import OldGitSyncModal from "pages/Editor/gitSync/GitSyncModal";
import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks";
import { import {
@ -553,10 +555,8 @@ export function ApplicationsSection(props: any) {
const isDeletingWorkspace = useSelector(getIsDeletingWorkspace); const isDeletingWorkspace = useSelector(getIsDeletingWorkspace);
const { isFetchingPackages } = usePackage(); const { isFetchingPackages } = usePackage();
const creatingApplicationMap = useSelector(getIsCreatingApplication); const creatingApplicationMap = useSelector(getIsCreatingApplication);
// This checks if the Anvil feature flag is enabled and shows different sections in the workspace
// for Anvil and Classic applications
const isAnvilEnabled = useSelector(getIsAnvilLayoutEnabled);
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled);
const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
const currentUser = useSelector(getCurrentUser); const currentUser = useSelector(getCurrentUser);
const isMobile = useIsMobileDevice(); const isMobile = useIsMobileDevice();
const urlParams = new URLSearchParams(location.search); const urlParams = new URLSearchParams(location.search);
@ -901,7 +901,7 @@ export function ApplicationsSection(props: any) {
<ResourceListLoader isMobile={isMobile} resources={applications} /> <ResourceListLoader isMobile={isMobile} resources={applications} />
) : ( ) : (
<> <>
{!isAiAgentFlowEnabled && ( {!isAiAgentInstanceEnabled && (
<ApplicationCardList <ApplicationCardList
applications={nonAnvilApplications} applications={nonAnvilApplications}
canInviteToWorkspace={canInviteToWorkspace} canInviteToWorkspace={canInviteToWorkspace}
@ -918,8 +918,7 @@ export function ApplicationsSection(props: any) {
workspaceId={activeWorkspace.id} workspaceId={activeWorkspace.id}
/> />
)} )}
{((isAnvilEnabled && anvilApplications.length > 0) || {isAiAgentFlowEnabled && (
isAiAgentFlowEnabled) && (
<ApplicationCardList <ApplicationCardList
applications={anvilApplications} applications={anvilApplications}
canInviteToWorkspace={canInviteToWorkspace} canInviteToWorkspace={canInviteToWorkspace}

View File

@ -7,7 +7,7 @@ import {
SKIP_TO_APPLICATION_FOR_AGENTS, SKIP_TO_APPLICATION_FOR_AGENTS,
createMessage, createMessage,
} from "ee/constants/messages"; } from "ee/constants/messages";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsCreatingAgent } from "ee/selectors/aiAgentSelectors";
import { getApplicationByIdFromWorkspaces } from "ee/selectors/applicationSelectors"; import { getApplicationByIdFromWorkspaces } from "ee/selectors/applicationSelectors";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
@ -17,7 +17,7 @@ interface UseReconnectModalDataProps {
} }
function useReconnectModalData({ appId, pageId }: UseReconnectModalDataProps) { function useReconnectModalData({ appId, pageId }: UseReconnectModalDataProps) {
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isCreatingAgent = useSelector(getIsCreatingAgent);
const application = useSelector((state) => const application = useSelector((state) =>
getApplicationByIdFromWorkspaces(state, appId ?? ""), getApplicationByIdFromWorkspaces(state, appId ?? ""),
); );
@ -31,18 +31,16 @@ function useReconnectModalData({ appId, pageId }: UseReconnectModalDataProps) {
basePageId, basePageId,
branch, branch,
params: { params: {
type: isAiAgentFlowEnabled ? "agent" : undefined, type: isCreatingAgent ? "agent" : undefined,
}, },
}); });
return { return {
skipMessage: createMessage( skipMessage: createMessage(
isAiAgentFlowEnabled isCreatingAgent ? SKIP_TO_APPLICATION_FOR_AGENTS : SKIP_TO_APPLICATION,
? SKIP_TO_APPLICATION_FOR_AGENTS
: SKIP_TO_APPLICATION,
), ),
missingDsCredentialsDescription: createMessage( missingDsCredentialsDescription: createMessage(
isAiAgentFlowEnabled isCreatingAgent
? RECONNECT_MISSING_DATASOURCE_CREDENTIALS_DESCRIPTION_FOR_AGENTS ? RECONNECT_MISSING_DATASOURCE_CREDENTIALS_DESCRIPTION_FOR_AGENTS
: RECONNECT_MISSING_DATASOURCE_CREDENTIALS_DESCRIPTION, : RECONNECT_MISSING_DATASOURCE_CREDENTIALS_DESCRIPTION,
), ),

View File

@ -20,7 +20,7 @@ import {
import useOnUpgrade from "utils/hooks/useOnUpgrade"; import useOnUpgrade from "utils/hooks/useOnUpgrade";
import { RampFeature, RampSection } from "utils/ProductRamps/RampsControlList"; import { RampFeature, RampSection } from "utils/ProductRamps/RampsControlList";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
export function AuditLogsUpgradePage() { export function AuditLogsUpgradePage() {
const { onUpgrade } = useOnUpgrade({ const { onUpgrade } = useOnUpgrade({
@ -29,7 +29,7 @@ export function AuditLogsUpgradePage() {
featureName: RampFeature.AuditLogs, featureName: RampFeature.AuditLogs,
sectionName: RampSection.AdminSettings, sectionName: RampSection.AdminSettings,
}); });
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
const header: Header = { const header: Header = {
heading: createMessage(INTRODUCING, "audit logs"), heading: createMessage(INTRODUCING, "audit logs"),
@ -83,9 +83,9 @@ export function AuditLogsUpgradePage() {
message: createMessage( message: createMessage(
EXCLUSIVE_TO_BUSINESS, EXCLUSIVE_TO_BUSINESS,
["audit logs"], ["audit logs"],
isAiAgentFlowEnabled ? "enterprise" : "business", isAiAgentInstanceEnabled ? "enterprise" : "business",
), ),
isEnterprise: isAiAgentFlowEnabled ? true : false, isEnterprise: isAiAgentInstanceEnabled ? true : false,
}; };
const props = { header, carousel, footer }; const props = { header, carousel, footer };

View File

@ -121,7 +121,7 @@ import type { Page } from "entities/Page";
import type { ApplicationPayload } from "entities/Application"; import type { ApplicationPayload } from "entities/Application";
import { objectKeys } from "@appsmith/utils"; import { objectKeys } from "@appsmith/utils";
import { findDefaultPage } from "pages/utils"; import { findDefaultPage } from "pages/utils";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
export let windowReference: Window | null = null; export let windowReference: Window | null = null;
@ -802,6 +802,7 @@ export function* showReconnectDatasourcesModalSaga(
yield put(setWorkspaceIdForImport({ editorId: application.id, workspaceId })); yield put(setWorkspaceIdForImport({ editorId: application.id, workspaceId }));
yield put(setPageIdForImport(pageId)); yield put(setPageIdForImport(pageId));
yield put(setIsReconnectingDatasourcesModalOpen({ isOpen: true })); yield put(setIsReconnectingDatasourcesModalOpen({ isOpen: true }));
} }
@ -1005,8 +1006,7 @@ export function* initDatasourceConnectionDuringImport(
}>, }>,
) { ) {
const workspaceId = action.payload.workspaceId; const workspaceId = action.payload.workspaceId;
const isAgentFlowEnabled: boolean = yield select(getIsAiAgentFlowEnabled); const isAgentFlowEnabled: boolean = yield select(getIsAiAgentInstanceEnabled);
const pluginsAndDatasourcesCalls: boolean = yield failFastApiCalls( const pluginsAndDatasourcesCalls: boolean = yield failFastApiCalls(
[fetchPlugins({ workspaceId }), fetchDatasources({ workspaceId })], [fetchPlugins({ workspaceId }), fetchDatasources({ workspaceId })],
[ [

View File

@ -1,11 +1,25 @@
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import type { DefaultRootState } from "react-redux"; import type { DefaultRootState } from "react-redux";
import { selectFeatureFlagCheck } from "ee/selectors/featureFlagsSelectors";
export const getAgentChatQuery = () => { export const getAgentChatQuery = () => {
return undefined; return undefined;
}; };
export const getIsAiAgentFlowEnabled = (state: DefaultRootState) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars
return selectFeatureFlagCheck(state, FEATURE_FLAG.license_ai_agent_enabled); export const getIsAiAgentInstanceEnabled = (state: DefaultRootState) => {
return false;
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const getIsAiAgentFlowEnabled = (state: DefaultRootState) => {
return false;
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const getIsAiAgentApp = (state: DefaultRootState) => {
return false;
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const getIsCreatingAgent = (state: DefaultRootState) => {
return false;
}; };

View File

@ -23,7 +23,7 @@ export interface RedirectUserAfterSignupProps {
shouldEnableFirstTimeUserOnboarding: string | null; shouldEnableFirstTimeUserOnboarding: string | null;
validLicense?: boolean; validLicense?: boolean;
dispatch: Dispatch; dispatch: Dispatch;
isAiAgentFlowEnabled: boolean; isAiAgentInstanceEnabled: boolean;
isOnLoginPage: boolean; isOnLoginPage: boolean;
} }

View File

@ -47,7 +47,7 @@ import {
checkIfJSObjectCreationAllowed, checkIfJSObjectCreationAllowed,
useWorkflowOptions, useWorkflowOptions,
} from "ee/utils/workflowHelpers"; } from "ee/utils/workflowHelpers";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
export interface FilterFileOperationsProps { export interface FilterFileOperationsProps {
canCreateActions: boolean; canCreateActions: boolean;
@ -84,7 +84,7 @@ export const useFilteredFileOperations = ({
); );
const isGACEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); const isGACEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
const AiPlugin = useSelector((state: DefaultRootState) => const AiPlugin = useSelector((state: DefaultRootState) =>
getPluginByPackageName(state, PluginPackageName.APPSMITH_AI), getPluginByPackageName(state, PluginPackageName.APPSMITH_AI),
); );
@ -106,7 +106,7 @@ export const useFilteredFileOperations = ({
.filter((ds) => { .filter((ds) => {
// We don't want to show the AI datasource in the // We don't want to show the AI datasource in the
// lists if the AI agent flow is enabled // lists if the AI agent flow is enabled
if (isAiAgentFlowEnabled && AiPlugin) { if (isAgentApp && AiPlugin) {
return AiPlugin.id !== ds.pluginId; return AiPlugin.id !== ds.pluginId;
} }

View File

@ -21,3 +21,12 @@ export const toggleFCIntegrations = ({
type: "", type: "",
payload: { isEnabled }, payload: { isEnabled },
}); });
export const setIsCreatingAgent = ({
isCreatingAgent,
}: {
isCreatingAgent: boolean;
}) => ({
type: "",
payload: { isCreatingAgent },
});

View File

@ -50,7 +50,7 @@ import {
import { Classes } from "@blueprintjs/core"; import { Classes } from "@blueprintjs/core";
import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks";
import useGlobalProfile from "git/hooks/useGlobalProfile"; import useGlobalProfile from "git/hooks/useGlobalProfile";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
const nameValidator = ( const nameValidator = (
value: string, value: string,
@ -95,7 +95,7 @@ export const Profile = () => {
); );
const [authorName, setAuthorNameInState] = useState(gitConfig?.authorName); const [authorName, setAuthorNameInState] = useState(gitConfig?.authorName);
const [authorEmail, setAuthorEmailInState] = useState(gitConfig?.authorEmail); const [authorEmail, setAuthorEmailInState] = useState(gitConfig?.authorEmail);
const isAIAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
useEffect(() => { useEffect(() => {
setIsSaving(false); setIsSaving(false);
@ -277,12 +277,12 @@ export const Profile = () => {
</Flex> </Flex>
</FieldWrapper> </FieldWrapper>
</Flex> </Flex>
{!isAIAgentFlowEnabled && ( {!isAiAgentInstanceEnabled && (
<SubCategory kind="heading-s" renderAs="p"> <SubCategory kind="heading-s" renderAs="p">
Git author Git author
</SubCategory> </SubCategory>
)} )}
{!isAIAgentFlowEnabled && ( {!isAiAgentInstanceEnabled && (
<Flex flexDirection="column" gap="spaces-5"> <Flex flexDirection="column" gap="spaces-5">
<FieldWrapper> <FieldWrapper>
{isFetching && <Loader className={Classes.SKELETON} />} {isFetching && <Loader className={Classes.SKELETON} />}

View File

@ -34,7 +34,7 @@ import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { Divider } from "@appsmith/ads"; import { Divider } from "@appsmith/ads";
import { ImportAppSettings } from "./components/ImportAppSettings"; import { ImportAppSettings } from "./components/ImportAppSettings";
import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
export enum AppSettingsTabs { export enum AppSettingsTabs {
General, General,
@ -194,9 +194,9 @@ function AppSettings() {
}, },
]; ];
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
if (isAiAgentFlowEnabled) { if (isAgentApp) {
SectionHeadersConfig = SectionHeadersConfig.filter( SectionHeadersConfig = SectionHeadersConfig.filter(
(config) => config.id !== "t--navigation-settings-header", (config) => config.id !== "t--navigation-settings-header",
); );

View File

@ -12,7 +12,7 @@ import { getRampLink, showProductRamps } from "ee/selectors/rampSelectors";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import EnterpriseTag from "components/EnterpriseTag"; import EnterpriseTag from "components/EnterpriseTag";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
function PrivateEmbeddingContent(props: { function PrivateEmbeddingContent(props: {
// TODO: Fix this the next time the file is edited // TODO: Fix this the next time the file is edited
@ -56,10 +56,10 @@ export function PrivateEmbedRampModal() {
false, false,
isPrivateEmbedEnabled, isPrivateEmbedEnabled,
); );
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
const canShowRamp = useSelector(showRampSelector); const canShowRamp = useSelector(showRampSelector);
if (canShowRamp && !isAiAgentFlowEnabled) { if (canShowRamp && !isAgentApp) {
return ( return (
<div className="flex justify-between items-start"> <div className="flex justify-between items-start">
<div className="flex flex-col gap-1 w-4/5"> <div className="flex flex-col gap-1 w-4/5">
@ -108,10 +108,10 @@ export function PrivateEmbedRampSidebar() {
false, false,
isPrivateEmbedEnabled, isPrivateEmbedEnabled,
); );
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
const canShowRamp = useSelector(showRampSelector); const canShowRamp = useSelector(showRampSelector);
if (canShowRamp && !isAiAgentFlowEnabled) { if (canShowRamp && !isAgentApp) {
return ( return (
<div className="mt-6" data-testid="t--private-embed-settings-ramp"> <div className="mt-6" data-testid="t--private-embed-settings-ramp">
<Text kind="body-m"> <Text kind="body-m">

View File

@ -103,7 +103,10 @@ import DatasourceTabs from "../DatasourceInfo/DatasorceTabs";
import DatasourceInformation, { ViewModeWrapper } from "./DatasourceSection"; import DatasourceInformation, { ViewModeWrapper } from "./DatasourceSection";
import { convertToPageIdSelector } from "selectors/pageListSelectors"; import { convertToPageIdSelector } from "selectors/pageListSelectors";
import { getApplicationByIdFromWorkspaces } from "ee/selectors/applicationSelectors"; import { getApplicationByIdFromWorkspaces } from "ee/selectors/applicationSelectors";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import {
getIsAiAgentApp,
getIsCreatingAgent,
} from "ee/selectors/aiAgentSelectors";
interface ReduxStateProps { interface ReduxStateProps {
canDeleteDatasource: boolean; canDeleteDatasource: boolean;
@ -144,7 +147,8 @@ interface ReduxStateProps {
featureFlags?: FeatureFlags; featureFlags?: FeatureFlags;
isPluginAllowedToPreviewData: boolean; isPluginAllowedToPreviewData: boolean;
isOnboardingFlow?: boolean; isOnboardingFlow?: boolean;
isAiAgentFlowEnabled?: boolean; isCreatingAgent?: boolean;
isAgentApp?: boolean;
} }
const Form = styled.div` const Form = styled.div`
@ -162,9 +166,11 @@ type Props = ReduxStateProps &
basePageId: string; basePageId: string;
}>; }>;
export const DSEditorWrapper = styled.div<{ isAiAgentFlowEnabled?: boolean }>` export const DSEditorWrapper = styled.div<{
isCreatingAiAgent?: boolean;
}>`
height: ${(props) => height: ${(props) =>
props.isAiAgentFlowEnabled props.isCreatingAiAgent
? `auto` ? `auto`
: `calc(100vh - ${props.theme.headerHeight})`}; : `calc(100vh - ${props.theme.headerHeight})`};
overflow: hidden; overflow: hidden;
@ -1027,7 +1033,9 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
> >
<DSEditorWrapper <DSEditorWrapper
className={!!isOnboardingFlow ? "onboarding-flow" : ""} className={!!isOnboardingFlow ? "onboarding-flow" : ""}
isAiAgentFlowEnabled={this.props.isAiAgentFlowEnabled} isCreatingAiAgent={
this.props.isCreatingAgent || this.props.isAgentApp
}
> >
{viewMode && !isInsideReconnectModal ? ( {viewMode && !isInsideReconnectModal ? (
this.renderTabsForViewMode() this.renderTabsForViewMode()
@ -1164,8 +1172,8 @@ const mapStateToProps = (
const featureFlags = selectFeatureFlags(state); const featureFlags = selectFeatureFlags(state);
const isFeatureEnabled = isGACEnabled(featureFlags); const isFeatureEnabled = isGACEnabled(featureFlags);
const isAiAgentFlowEnabled = getIsAiAgentFlowEnabled(state); const isAgentApp = getIsAiAgentApp(state);
const isCreatingAgent = getIsCreatingAgent(state);
const canManageDatasource = getHasManageDatasourcePermission( const canManageDatasource = getHasManageDatasourcePermission(
isFeatureEnabled, isFeatureEnabled,
datasourcePermissions, datasourcePermissions,
@ -1233,7 +1241,8 @@ const mapStateToProps = (
defaultKeyValueArrayConfig, defaultKeyValueArrayConfig,
initialValue, initialValue,
showDebugger, showDebugger,
isAiAgentFlowEnabled, isAgentApp,
isCreatingAgent,
}; };
}; };

View File

@ -24,7 +24,7 @@ import { toast } from "@appsmith/ads";
import { DOCS_AI_BASE_URL, DOCS_BASE_URL } from "constants/ThirdPartyConstants"; import { DOCS_AI_BASE_URL, DOCS_BASE_URL } from "constants/ThirdPartyConstants";
import { getAppsmithConfigs } from "ee/configs"; import { getAppsmithConfigs } from "ee/configs";
import { getCurrentUser } from "selectors/usersSelectors"; import { getCurrentUser } from "selectors/usersSelectors";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
const { cloudHosting, intercomAppID } = getAppsmithConfigs(); const { cloudHosting, intercomAppID } = getAppsmithConfigs();
@ -108,7 +108,7 @@ export const useNavigationMenuData = ({
} }
}, [applicationId, dispatch, history]); }, [applicationId, dispatch, history]);
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
return useMemo( return useMemo(
() => () =>
@ -152,9 +152,7 @@ export const useNavigationMenuData = ({
{ {
text: "Documentation", text: "Documentation",
onClick: () => onClick: () =>
openExternalLink( openExternalLink(isAgentApp ? DOCS_AI_BASE_URL : DOCS_BASE_URL),
isAiAgentFlowEnabled ? DOCS_AI_BASE_URL : DOCS_BASE_URL,
),
type: MenuTypes.MENU, type: MenuTypes.MENU,
isVisible: true, isVisible: true,
startIcon: "book-line", startIcon: "book-line",
@ -166,7 +164,7 @@ export const useNavigationMenuData = ({
"https://github.com/appsmithorg/appsmith/issues/new/choose", "https://github.com/appsmithorg/appsmith/issues/new/choose",
), ),
type: MenuTypes.MENU, type: MenuTypes.MENU,
isVisible: !isAiAgentFlowEnabled, isVisible: !isAgentApp,
startIcon: "bug-line", startIcon: "bug-line",
}, },
{ {
@ -191,7 +189,7 @@ export const useNavigationMenuData = ({
hasExportPermission, hasExportPermission,
hasDeletePermission, hasDeletePermission,
deleteApplication, deleteApplication,
isAiAgentFlowEnabled, isAgentApp,
setForkApplicationModalOpen, setForkApplicationModalOpen,
isIntercomConsentGiven, isIntercomConsentGiven,
dispatch, dispatch,

View File

@ -37,7 +37,7 @@ import { showSignpostingModal } from "actions/onboardingActions";
import TooltipContent from "./FirstTimeUserOnboarding/TooltipContent"; import TooltipContent from "./FirstTimeUserOnboarding/TooltipContent";
import { getInstanceId } from "ee/selectors/organizationSelectors"; import { getInstanceId } from "ee/selectors/organizationSelectors";
import { updateIntercomConsent, updateUserDetails } from "actions/userActions"; import { updateIntercomConsent, updateUserDetails } from "actions/userActions";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
import { DOCS_AI_BASE_URL } from "constants/ThirdPartyConstants"; import { DOCS_AI_BASE_URL } from "constants/ThirdPartyConstants";
const { appVersion, cloudHosting, intercomAppID } = getAppsmithConfigs(); const { appVersion, cloudHosting, intercomAppID } = getAppsmithConfigs();
@ -190,9 +190,9 @@ function HelpButton() {
} }
: {}; : {};
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAgentApp = useSelector(getIsAiAgentApp);
if (isAiAgentFlowEnabled) { if (isAgentApp) {
const docItem = HELP_MENU_ITEMS.find( const docItem = HELP_MENU_ITEMS.find(
(item) => item.label === "Documentation", (item) => item.label === "Documentation",
); );

View File

@ -94,7 +94,10 @@ import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import DatasourceTabs from "../DatasourceInfo/DatasorceTabs"; import DatasourceTabs from "../DatasourceInfo/DatasorceTabs";
import { getCurrentApplicationIdForCreateNewApp } from "ee/selectors/applicationSelectors"; import { getCurrentApplicationIdForCreateNewApp } from "ee/selectors/applicationSelectors";
import { convertToPageIdSelector } from "selectors/pageListSelectors"; import { convertToPageIdSelector } from "selectors/pageListSelectors";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import {
getIsAiAgentApp,
getIsCreatingAgent,
} from "ee/selectors/aiAgentSelectors";
const ViewModeContainer = styled.div` const ViewModeContainer = styled.div`
display: flex; display: flex;
@ -189,7 +192,7 @@ interface SaasEditorWrappperProps {
datasourceId: string; datasourceId: string;
pageId: string; pageId: string;
pluginPackageName: string; pluginPackageName: string;
isAiAgentFlowEnabled?: boolean; isCreatingAiAgent?: boolean;
} }
interface RouteProps { interface RouteProps {
datasourceId: string; datasourceId: string;
@ -645,9 +648,7 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
showingTabsOnViewMode && "saas-form-resizer-content-show-tabs" showingTabsOnViewMode && "saas-form-resizer-content-show-tabs"
}`} }`}
> >
<DSEditorWrapper <DSEditorWrapper isCreatingAiAgent={this.props.isCreatingAiAgent}>
isAiAgentFlowEnabled={this.props.isAiAgentFlowEnabled}
>
<DSDataFilter <DSDataFilter
filterId={this.state.filterParams.id} filterId={this.state.filterParams.id}
isInsideReconnectModal={!!isInsideReconnectModal} isInsideReconnectModal={!!isInsideReconnectModal}
@ -856,7 +857,8 @@ const mapStateToProps = (state: DefaultRootState, props: any) => {
// should plugin be able to preview data // should plugin be able to preview data
const isPluginAllowedToPreviewData = const isPluginAllowedToPreviewData =
!!plugin && isEnabledForPreviewData(datasource as Datasource, plugin); !!plugin && isEnabledForPreviewData(datasource as Datasource, plugin);
const isAiAgentFlowEnabled = getIsAiAgentFlowEnabled(state); const isCreatingAgent = getIsCreatingAgent(state);
const isAgentApp = getIsAiAgentApp(state);
return { return {
datasource, datasource,
@ -895,7 +897,7 @@ const mapStateToProps = (state: DefaultRootState, props: any) => {
isPluginAuthFailed, isPluginAuthFailed,
featureFlags: selectFeatureFlags(state), featureFlags: selectFeatureFlags(state),
isPluginAllowedToPreviewData, isPluginAllowedToPreviewData,
isAiAgentFlowEnabled, isCreatingAiAgent: isCreatingAgent || isAgentApp,
}; };
}; };

View File

@ -16,7 +16,7 @@ import {
Text, Text,
} from "@appsmith/ads"; } from "@appsmith/ads";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentApp } from "ee/selectors/aiAgentSelectors";
const BodyContainer = styled.div` const BodyContainer = styled.div`
display: flex; display: flex;
@ -42,7 +42,7 @@ function ImportSuccessModal(props: ImportSuccessModalProps) {
const importedAppSuccess = localStorage.getItem("importSuccess"); const importedAppSuccess = localStorage.getItem("importSuccess");
// const isOpen = importedAppSuccess === "true"; // const isOpen = importedAppSuccess === "true";
const [isOpen, setIsOpen] = useState(importedAppSuccess === "true"); const [isOpen, setIsOpen] = useState(importedAppSuccess === "true");
const isAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentApp = useSelector(getIsAiAgentApp);
const onClose = (open: boolean) => { const onClose = (open: boolean) => {
if (!open) { if (!open) {
@ -56,7 +56,7 @@ function ImportSuccessModal(props: ImportSuccessModalProps) {
}; };
return ( return (
<Modal onOpenChange={onClose} open={isOpen && !isAgentFlowEnabled}> <Modal onOpenChange={onClose} open={isOpen && !isAiAgentApp}>
<StyledModalContent className={"t--import-app-success-modal"}> <StyledModalContent className={"t--import-app-success-modal"}>
<ModalHeader>Datasource configured</ModalHeader> <ModalHeader>Datasource configured</ModalHeader>
<ModalBody> <ModalBody>

View File

@ -76,7 +76,8 @@ import useReconnectModalData from "ee/pages/Editor/gitSync/useReconnectModalData
import { resetImportData } from "ee/actions/workspaceActions"; import { resetImportData } from "ee/actions/workspaceActions";
import { getLoadingTokenForDatasourceId } from "selectors/datasourceSelectors"; import { getLoadingTokenForDatasourceId } from "selectors/datasourceSelectors";
import ReconnectDatasourceForm from "Datasource/components/ReconnectDatasourceForm"; import ReconnectDatasourceForm from "Datasource/components/ReconnectDatasourceForm";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsCreatingAgent } from "ee/selectors/aiAgentSelectors";
import { setIsCreatingAgent } from "ee/actions/aiAgentActions";
const Section = styled.div` const Section = styled.div`
display: flex; display: flex;
@ -87,10 +88,10 @@ const Section = styled.div`
width: calc(100% - 206px); width: calc(100% - 206px);
`; `;
const BodyContainer = styled.div<{ isAiAgentFlowEnabled?: boolean }>` const BodyContainer = styled.div<{ isCreatingAiAgent?: boolean }>`
flex: 3; flex: 3;
height: ${(props) => (props.isAiAgentFlowEnabled ? "auto" : "640px")}; height: ${(props) => (props.isCreatingAiAgent ? "auto" : "640px")};
max-height: ${(props) => (props.isAiAgentFlowEnabled ? "auto" : "82vh")}; max-height: ${(props) => (props.isCreatingAiAgent ? "auto" : "82vh")};
`; `;
// TODO: Removed usage of "t--" classes since they clash with the test classes. // TODO: Removed usage of "t--" classes since they clash with the test classes.
@ -226,9 +227,9 @@ const ModalHeaderWrapper = styled.div<{ isAgentFlowEnabled: boolean }>`
`; `;
const ModalContentWrapper = styled(ModalContent)<{ const ModalContentWrapper = styled(ModalContent)<{
isAiAgentFlowEnabled?: boolean; isCreatingAiAgent?: boolean;
}>` }>`
width: ${(props) => (props.isAiAgentFlowEnabled ? "auto" : "100%")}; width: ${(props) => (props.isCreatingAiAgent ? "auto" : "100%")};
`; `;
const ModalBodyWrapper = styled(ModalBody)` const ModalBodyWrapper = styled(ModalBody)`
overflow-y: hidden; overflow-y: hidden;
@ -342,7 +343,7 @@ function ReconnectDatasourceModal() {
parentEntityId, // appId or packageId from query params parentEntityId, // appId or packageId from query params
skipMessage, skipMessage,
} = useReconnectModalData({ pageId, appId }); } = useReconnectModalData({ pageId, appId });
const isAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isCreatingAgent = useSelector(getIsCreatingAgent);
// when redirecting from oauth, processing the status // when redirecting from oauth, processing the status
if (isImport) { if (isImport) {
@ -624,27 +625,32 @@ function ReconnectDatasourceModal() {
}; };
return ( return (
<Modal open={isModalOpen}> <Modal
onOpenChange={(isOpen) => {
if (!isOpen) {
dispatch(setIsCreatingAgent({ isCreatingAgent: false }));
}
}}
open={isModalOpen}
>
<ModalContentWrapper <ModalContentWrapper
data-testid="reconnect-datasource-modal" data-testid="reconnect-datasource-modal"
isAiAgentFlowEnabled={isAgentFlowEnabled} isCreatingAiAgent={isCreatingAgent}
onClick={handleClose} onClick={handleClose}
onEscapeKeyDown={onClose} onEscapeKeyDown={onClose}
onInteractOutside={handleClose} onInteractOutside={handleClose}
overlayClassName="reconnect-datasource-modal" overlayClassName="reconnect-datasource-modal"
> >
<ModalHeaderWrapper isAgentFlowEnabled={isAgentFlowEnabled}> <ModalHeaderWrapper isAgentFlowEnabled={isCreatingAgent}>
<ModalHeader> <ModalHeader>
{isAgentFlowEnabled {isCreatingAgent ? "Connect Datasources" : "Reconnect datasources"}
? "Connect Datasources"
: "Reconnect datasources"}
</ModalHeader> </ModalHeader>
</ModalHeaderWrapper> </ModalHeaderWrapper>
<ModalBodyWrapper <ModalBodyWrapper
style={{ padding: isAgentFlowEnabled ? "0px" : undefined }} style={{ padding: isCreatingAgent ? "0px" : undefined }}
> >
<BodyContainer isAiAgentFlowEnabled={isAgentFlowEnabled}> <BodyContainer isCreatingAiAgent={isCreatingAgent}>
{!isAgentFlowEnabled && ( {!isCreatingAgent && (
<Title> <Title>
{createMessage(RECONNECT_MISSING_DATASOURCE_CREDENTIALS)} {createMessage(RECONNECT_MISSING_DATASOURCE_CREDENTIALS)}
</Title> </Title>

View File

@ -7,8 +7,10 @@ import LeftSideContent from "./LeftSideContent";
import { getAppsmithConfigs } from "ee/configs"; import { getAppsmithConfigs } from "ee/configs";
import { useIsMobileDevice } from "utils/hooks/useDeviceDetect"; import { useIsMobileDevice } from "utils/hooks/useDeviceDetect";
import styled from "styled-components"; import styled from "styled-components";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
import clsx from "clsx"; import clsx from "clsx";
import { selectFeatureFlags } from "ee/selectors/featureFlagsSelectors";
import { isBrandingEnabled, isMultiOrgFFEnabled } from "ee/utils/planHelpers";
interface ContainerProps { interface ContainerProps {
title: string; title: string;
@ -45,18 +47,24 @@ function Container(props: ContainerProps) {
const organizationConfig = useSelector(getOrganizationConfig); const organizationConfig = useSelector(getOrganizationConfig);
const { cloudHosting } = getAppsmithConfigs(); const { cloudHosting } = getAppsmithConfigs();
const isMobileDevice = useIsMobileDevice(); const isMobileDevice = useIsMobileDevice();
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const featureFlags = useSelector(selectFeatureFlags);
const multiOrgEnabled = isMultiOrgFFEnabled(featureFlags);
const brandingEnabled = isBrandingEnabled(featureFlags);
const shouldShowLeftSideContent =
cloudHosting && !isMobileDevice && !multiOrgEnabled && brandingEnabled;
const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
return ( return (
<ContainerWrapper <ContainerWrapper
className={clsx({ className={clsx({
"my-auto flex items-center justify-center min-w-min": true, "my-auto flex items-center justify-center min-w-min": true,
"flex-col-reverse gap-4": isAiAgentFlowEnabled, "flex-col-reverse gap-4": isAiAgentInstanceEnabled,
"flex-row gap-14": !isAiAgentFlowEnabled, "flex-row gap-14": !isAiAgentInstanceEnabled,
})} })}
data-testid={testId} data-testid={testId}
> >
{cloudHosting && !isMobileDevice && <LeftSideContent />} {shouldShowLeftSideContent && <LeftSideContent />}
<BoxWrapper <BoxWrapper
className={`t--login-container ${ className={`t--login-container ${
isMobileDevice ? "w-full" : "w-[min(400px,80%)]" isMobileDevice ? "w-full" : "w-[min(400px,80%)]"

View File

@ -3,7 +3,7 @@ import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants";
import { Avatar } from "@appsmith/ads"; import { Avatar } from "@appsmith/ads";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
const Wrapper = styled.div` const Wrapper = styled.div`
@ -72,11 +72,11 @@ const QUOTE = {
}; };
function LeftSideContent() { function LeftSideContent() {
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
return ( return (
<Wrapper> <Wrapper>
{!isAiAgentFlowEnabled && ( {!isAiAgentInstanceEnabled && (
<div className="left-description"> <div className="left-description">
<div className="left-description-container"> <div className="left-description-container">
&quot;{QUOTE.quote}&quot; &quot;{QUOTE.quote}&quot;
@ -102,7 +102,7 @@ function LeftSideContent() {
</div> </div>
<div <div
className="client-logo-section" className="client-logo-section"
style={{ marginBottom: isAiAgentFlowEnabled ? "0px" : "24px" }} style={{ marginBottom: isAiAgentInstanceEnabled ? "0px" : "24px" }}
> >
<img <img
alt="GSK logo" alt="GSK logo"

View File

@ -63,8 +63,8 @@ import { SELF_HOSTING_DOC } from "constants/ThirdPartyConstants";
import CsrfTokenInput from "pages/UserAuth/CsrfTokenInput"; import CsrfTokenInput from "pages/UserAuth/CsrfTokenInput";
import { useIsCloudBillingEnabled } from "hooks"; import { useIsCloudBillingEnabled } from "hooks";
import { isLoginHostname } from "utils/cloudBillingUtils"; import { isLoginHostname } from "utils/cloudBillingUtils";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors";
import { appsmithTelemetry } from "instrumentation"; import { appsmithTelemetry } from "instrumentation";
import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
import { getSafeErrorMessage } from "ee/constants/approvedErrorMessages"; import { getSafeErrorMessage } from "ee/constants/approvedErrorMessages";
declare global { declare global {
@ -103,10 +103,10 @@ type SignUpFormProps = InjectedFormProps<
export function SignUp(props: SignUpFormProps) { export function SignUp(props: SignUpFormProps) {
const history = useHistory(); const history = useHistory();
const isFormLoginEnabled = useSelector(getIsFormLoginEnabled); const isFormLoginEnabled = useSelector(getIsFormLoginEnabled);
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
useEffect(() => { useEffect(() => {
if (!isFormLoginEnabled && !isAiAgentFlowEnabled) { if (!isFormLoginEnabled && !isAiAgentInstanceEnabled) {
const search = new URL(window.location.href)?.searchParams?.toString(); const search = new URL(window.location.href)?.searchParams?.toString();
history.replace({ history.replace({
@ -227,7 +227,7 @@ export function SignUp(props: SignUpFormProps) {
</Link> </Link>
</div> </div>
)} )}
{cloudHosting && !isAiAgentFlowEnabled && ( {cloudHosting && !isAiAgentInstanceEnabled && (
<> <>
<OrWithLines>or</OrWithLines> <OrWithLines>or</OrWithLines>
<div className="px-2 text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]"> <div className="px-2 text-center text-[color:var(--ads-v2\-color-fg)] text-[14px]">
@ -251,7 +251,7 @@ export function SignUp(props: SignUpFormProps) {
<Container <Container
footer={footerSection} footer={footerSection}
title={createMessage( title={createMessage(
isAiAgentFlowEnabled ? SIGNUP_PAGE_TITLE : LOGIN_PAGE_TITLE, isAiAgentInstanceEnabled ? SIGNUP_PAGE_TITLE : LOGIN_PAGE_TITLE,
)} )}
> >
<Helmet> <Helmet>

View File

@ -40,7 +40,7 @@ import { IntercomConsent } from "pages/Editor/HelpButton";
import { DOCS_AI_BASE_URL, DOCS_BASE_URL } from "constants/ThirdPartyConstants"; import { DOCS_AI_BASE_URL, DOCS_BASE_URL } from "constants/ThirdPartyConstants";
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
import styled from "styled-components"; import styled from "styled-components";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
const { cloudHosting, intercomAppID } = getAppsmithConfigs(); const { cloudHosting, intercomAppID } = getAppsmithConfigs();
export const VersionData = styled.div` export const VersionData = styled.div`
@ -71,7 +71,7 @@ const HomepageHeaderAction = ({
const { appVersion } = getAppsmithConfigs(); const { appVersion } = getAppsmithConfigs();
const howMuchTimeBefore = howMuchTimeBeforeText(appVersion.releaseDate); const howMuchTimeBefore = howMuchTimeBeforeText(appVersion.releaseDate);
const [showIntercomConsent, setShowIntercomConsent] = useState(false); const [showIntercomConsent, setShowIntercomConsent] = useState(false);
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
if (!isHomePage || !!isCreateNewAppFlow) return null; if (!isHomePage || !!isCreateNewAppFlow) return null;
@ -129,7 +129,7 @@ const HomepageHeaderAction = ({
<MenuItem <MenuItem
className="t--documentation-button" className="t--documentation-button"
onClick={() => { onClick={() => {
if (isAiAgentFlowEnabled) { if (isAiAgentInstanceEnabled) {
window.open(DOCS_AI_BASE_URL, "_blank"); window.open(DOCS_AI_BASE_URL, "_blank");
return; return;

View File

@ -45,7 +45,7 @@ import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { getHasManageDatasourcePermission } from "ee/utils/BusinessFeatures/permissionPageHelpers"; import { getHasManageDatasourcePermission } from "ee/utils/BusinessFeatures/permissionPageHelpers";
import { resetCurrentPluginIdForCreateNewApp } from "actions/onboardingActions"; import { resetCurrentPluginIdForCreateNewApp } from "actions/onboardingActions";
import { useParentEntityDetailsFromParams } from "ee/entities/Engine/actionHelpers"; import { useParentEntityDetailsFromParams } from "ee/entities/Engine/actionHelpers";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsCreatingAgent } from "ee/selectors/aiAgentSelectors";
interface Props { interface Props {
datasource: Datasource; datasource: Datasource;
@ -200,7 +200,7 @@ function DatasourceAuth({
isInsideReconnectModal, isInsideReconnectModal,
); );
const isAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isCreatingAgent = useSelector(getIsCreatingAgent);
useEffect(() => { useEffect(() => {
if ( if (
@ -455,7 +455,7 @@ function DatasourceAuth({
size="md" size="md"
> >
{createMessage( {createMessage(
isAgentFlowEnabled isCreatingAgent
? CONNECT_DATASOURCE_BUTTON_TEXT_FOR_AGENTS ? CONNECT_DATASOURCE_BUTTON_TEXT_FOR_AGENTS
: CONNECT_DATASOURCE_BUTTON_TEXT, : CONNECT_DATASOURCE_BUTTON_TEXT,
)} )}

View File

@ -15,7 +15,7 @@ import {
import { redirectUserAfterSignup } from "ee/utils/signupHelpers"; import { redirectUserAfterSignup } from "ee/utils/signupHelpers";
import { setUserSignedUpFlag } from "utils/storage"; import { setUserSignedUpFlag } from "utils/storage";
import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import AnalyticsUtil from "ee/utils/AnalyticsUtil";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
export function SignupSuccess() { export function SignupSuccess() {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -24,7 +24,7 @@ export function SignupSuccess() {
const shouldEnableFirstTimeUserOnboarding = urlObject?.searchParams.get( const shouldEnableFirstTimeUserOnboarding = urlObject?.searchParams.get(
"enableFirstTimeUserExperience", "enableFirstTimeUserExperience",
); );
const isAiAgentFlowEnabled = useSelector(getIsAiAgentFlowEnabled); const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
const validLicense = useSelector(isValidLicense); const validLicense = useSelector(isValidLicense);
const user = useSelector(getCurrentUser); const user = useSelector(getCurrentUser);
const isOnLoginPage = !useSelector(isWithinAnOrganization); const isOnLoginPage = !useSelector(isWithinAnOrganization);
@ -42,7 +42,7 @@ export function SignupSuccess() {
shouldEnableFirstTimeUserOnboarding, shouldEnableFirstTimeUserOnboarding,
validLicense, validLicense,
dispatch, dispatch,
isAiAgentFlowEnabled, isAiAgentInstanceEnabled,
isOnLoginPage, isOnLoginPage,
}), }),
[ [
@ -82,7 +82,7 @@ export function SignupSuccess() {
user?.isSuperUser || user?.isSuperUser ||
((user?.role || user?.proficiency) && user?.useCase) || ((user?.role || user?.proficiency) && user?.useCase) ||
shouldEnableFirstTimeUserOnboarding !== "true" || shouldEnableFirstTimeUserOnboarding !== "true" ||
isAiAgentFlowEnabled isAiAgentInstanceEnabled
) { ) {
redirectUsingQueryParam(); redirectUsingQueryParam();

View File

@ -50,8 +50,7 @@ import {
openCarbonModal, openCarbonModal,
setCreateAgentModalOpen, setCreateAgentModalOpen,
} from "ee/actions/aiAgentActions"; } from "ee/actions/aiAgentActions";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors"; import { getAgentTemplatesSelector } from "selectors/templatesSelectors";
import { getTemplatesByFlagSelector } from "selectors/templatesSelectors";
const isAirgappedInstance = isAirgapped(); const isAirgappedInstance = isAirgapped();
const AI_DATASOURCE_NAME = "AI Datasource"; const AI_DATASOURCE_NAME = "AI Datasource";
@ -82,9 +81,10 @@ function* getAllTemplatesSaga() {
function* importTemplateToWorkspaceSaga( function* importTemplateToWorkspaceSaga(
action: ReduxAction<{ templateId: string; workspaceId: string }>, action: ReduxAction<{ templateId: string; workspaceId: string }>,
) { ) {
const isAiAgentFlowEnabled: boolean = yield select(getIsAiAgentFlowEnabled); const agentTemplates: ReturnType<typeof getAgentTemplatesSelector> =
const templates: ReturnType<typeof getTemplatesByFlagSelector> = yield select( yield select(getAgentTemplatesSelector);
getTemplatesByFlagSelector, const isAgentTemplate: boolean = agentTemplates.some(
(template) => template.id === action.payload.templateId,
); );
try { try {
@ -108,8 +108,8 @@ function* importTemplateToWorkspaceSaga(
payload: response.data.application, payload: response.data.application,
}); });
if (isAiAgentFlowEnabled) { if (isAgentTemplate) {
const isScratchTemplate = templates.find( const isScratchTemplate = agentTemplates.find(
(template) => template.title === "AI Agent", (template) => template.title === "AI Agent",
); );
@ -141,7 +141,7 @@ function* importTemplateToWorkspaceSaga(
const pageURL = builderURL({ const pageURL = builderURL({
basePageId: application.defaultBasePageId, basePageId: application.defaultBasePageId,
params: { params: {
type: isAiAgentFlowEnabled ? "agent" : undefined, type: isAgentTemplate ? "agent" : undefined,
}, },
}); });

View File

@ -13,7 +13,6 @@ import Fuse from "fuse.js";
import type { Filter } from "pages/Templates/TemplateFilters"; import type { Filter } from "pages/Templates/TemplateFilters";
import { TEMPLATE_BUILDING_BLOCKS_FILTER_FUNCTION_VALUE } from "pages/Templates/constants"; import { TEMPLATE_BUILDING_BLOCKS_FILTER_FUNCTION_VALUE } from "pages/Templates/constants";
import { createSelector } from "reselect"; import { createSelector } from "reselect";
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors";
import type { DefaultRootState } from "react-redux"; import type { DefaultRootState } from "react-redux";
const fuzzySearchOptions = { const fuzzySearchOptions = {
@ -27,24 +26,14 @@ const fuzzySearchOptions = {
const AGENT_TEMPLATES_USE_CASE = "Agent"; const AGENT_TEMPLATES_USE_CASE = "Agent";
export const getTemplatesSelector = (state: DefaultRootState) => export const getTemplatesSelector = (state: DefaultRootState) =>
state.ui.templates.templates; state.ui.templates.templates.filter(
(template) => !template.useCases.includes(AGENT_TEMPLATES_USE_CASE),
);
export const getTemplatesByFlagSelector = createSelector( export const getAgentTemplatesSelector = (state: DefaultRootState) =>
(state: DefaultRootState) => state.ui.templates.templates, state.ui.templates.templates.filter((template) =>
getIsAiAgentFlowEnabled, template.useCases.includes(AGENT_TEMPLATES_USE_CASE),
(templates, isAiAgentFlowEnabled) => { );
// For agents, we only show the templates that have the use case "Agent".
// The "Agent" use case acts as a filter for us to just show the templates
// that are relevant to agents.
return templates.filter((template) => {
if (isAiAgentFlowEnabled) {
return template.useCases.includes(AGENT_TEMPLATES_USE_CASE);
}
return template.useCases.includes(AGENT_TEMPLATES_USE_CASE) === false;
});
},
);
export const isImportingTemplateSelector = (state: DefaultRootState) => export const isImportingTemplateSelector = (state: DefaultRootState) =>
state.ui.templates.isImportingTemplate; state.ui.templates.isImportingTemplate;
@ -116,7 +105,7 @@ export const getBuildingBlockExplorerCards = createSelector(
); );
export const getFilteredTemplateList = createSelector( export const getFilteredTemplateList = createSelector(
getTemplatesByFlagSelector, getTemplatesSelector,
getTemplateFilterSelector, getTemplateFilterSelector,
getTemplateFiltersLength, getTemplateFiltersLength,
(templates, templatesFilters, numberOfFiltersApplied) => { (templates, templatesFilters, numberOfFiltersApplied) => {
@ -180,7 +169,7 @@ export const getSearchedTemplateList = createSelector(
// Get the list of datasources which are used by templates // Get the list of datasources which are used by templates
export const templatesDatasourceFiltersSelector = createSelector( export const templatesDatasourceFiltersSelector = createSelector(
getTemplatesByFlagSelector, getTemplatesSelector,
getDefaultPlugins, getDefaultPlugins,
(templates, plugins) => { (templates, plugins) => {
const datasourceFilters: { label: string; value: string }[] = []; const datasourceFilters: { label: string; value: string }[] = [];
@ -216,7 +205,7 @@ export const allTemplatesFiltersSelector = (state: DefaultRootState) =>
// Get all filters which is associated with atleast one template // Get all filters which is associated with atleast one template
// If no template is associated with a filter, then the filter shouldn't be in the filter list // If no template is associated with a filter, then the filter shouldn't be in the filter list
export const getFilterListSelector = createSelector( export const getFilterListSelector = createSelector(
getTemplatesByFlagSelector, getTemplatesSelector,
allTemplatesFiltersSelector, allTemplatesFiltersSelector,
(templates, allTemplateFilters) => { (templates, allTemplateFilters) => {
const FUNCTIONS_FILTER = "functions"; const FUNCTIONS_FILTER = "functions";

View File

@ -17,6 +17,7 @@ export const AvailableFeaturesToOverride: FeatureFlag[] = [
"release_layout_conversion_enabled", "release_layout_conversion_enabled",
"license_ai_agent_enabled", "license_ai_agent_enabled",
"release_ai_chat_integrations_enabled", "release_ai_chat_integrations_enabled",
"license_ai_agent_instance_enabled",
]; ];
export type OverriddenFeatureFlags = Partial<Record<FeatureFlag, boolean>>; export type OverriddenFeatureFlags = Partial<Record<FeatureFlag, boolean>>;
@ -24,6 +25,20 @@ export const useFeatureFlagOverride = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const areFeatureFlagsFetched = useSelector(getFeatureFlagsFetched); const areFeatureFlagsFetched = useSelector(getFeatureFlagsFetched);
/**
* This is for listeninging the message from the feature flag overrrider chrome extension
*/
useEffect(() => {
window.addEventListener("message", (event) => {
if (event.data.action === "featureFlagOverrideValuesSet") {
const featureFlagValues = event.data.values;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).overrideFeatureFlag(featureFlagValues);
}
});
}, []);
/** /**
* Fetches the feature flag override values and updates the state. * Fetches the feature flag override values and updates the state.
*/ */