add test env (#1565)
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Pre-commit / pre-commit (push) Waiting to run
Test / Run Python Tests (push) Waiting to run

This commit is contained in:
Tong Chen 2026-05-01 11:15:27 +08:00 committed by GitHub
parent 8b10717c8a
commit 6afbd0378b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 47 additions and 28 deletions

View file

@ -1,8 +1,12 @@
VITE_BASE_URL=/api
# =======Production environment variables=======
SERVER_URL=https://dev.eigent.ai
VITE_PROXY_URL=https://dev.eigent.ai
VITE_SITE_URL=https://www.eigent.ai
VITE_USE_LOCAL_PROXY=false
# =======Local environment variables=======
# VITE_PROXY_URL=http://localhost:3001
# VITE_USE_LOCAL_PROXY=true

2
backend/uv.lock generated
View file

@ -1,5 +1,5 @@
version = 1
revision = 2
revision = 3
requires-python = "==3.11.*"
resolution-markers = [
"sys_platform == 'win32'",

View file

@ -289,6 +289,16 @@ export async function startBackend(
}
}
// In dev mode, also check .env.development for SERVER_URL
if (!resolvedServerUrl && devServerUrl) {
const devEnvPath = path.join(app.getAppPath(), '.env.development');
const devFileServerUrl = readEnvValue(devEnvPath, 'SERVER_URL');
if (devFileServerUrl) {
resolvedServerUrl = devFileServerUrl;
resolvedSource = `dev env file SERVER_URL (${devEnvPath})`;
}
}
if (!resolvedServerUrl && process.env.SERVER_URL) {
resolvedServerUrl = process.env.SERVER_URL;
resolvedSource = 'process.env SERVER_URL';

View file

@ -13,6 +13,7 @@
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
import i18n from '@/i18n';
import { SITE_URL } from '@/lib';
import { toast } from 'sonner';
export function showCreditsToast() {
@ -22,7 +23,7 @@ export function showCreditsToast() {
{i18n.t('chat.you-ve-reached-the-limit-of-your-current-plan')}
<a
className="cursor-pointer underline"
onClick={() => (window.location.href = 'https://www.eigent.ai/pricing')}
onClick={() => (window.location.href = `${SITE_URL}/pricing`)}
>
{i18n.t('chat.upgrade')}
</a>{' '}

View file

@ -13,6 +13,7 @@
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
import i18n from '@/i18n';
import { SITE_URL } from '@/lib';
import { toast } from 'sonner';
export function showStorageToast() {
@ -25,7 +26,7 @@ export function showStorageToast() {
Please{' '}
<a
className="cursor-pointer underline"
onClick={() => (window.location.href = 'https://www.eigent.ai/pricing')}
onClick={() => (window.location.href = `${SITE_URL}/pricing`)}
>
{i18n.t('chat.upgrade')}
</a>{' '}

View file

@ -25,6 +25,7 @@ import EndNoticeDialog from '@/components/Dialog/EndNotice';
import { Button } from '@/components/ui/button';
import { TooltipSimple } from '@/components/ui/tooltip';
import useChatStoreAdapter from '@/hooks/useChatStoreAdapter';
import { SITE_URL } from '@/lib';
import { share } from '@/lib/share';
import { useAuthStore } from '@/store/authStore';
import { useInstallationUI } from '@/store/installationStore';
@ -113,7 +114,7 @@ function HeaderWin() {
try {
const res: any = await proxyFetchGet('/api/v1/user/invite_code');
if (res?.invite_code) {
const inviteLink = `https://www.eigent.ai/signup?invite_code=${res.invite_code}`;
const inviteLink = `${SITE_URL}/signup?invite_code=${res.invite_code}`;
await navigator.clipboard.writeText(inviteLink);
toast.success(t('layout.invitation-link-copied'));
} else {

View file

@ -14,6 +14,9 @@
import { getAuthStore } from '@/store/authStore';
export const SITE_URL =
import.meta.env.VITE_SITE_URL || 'https://www.eigent.ai';
export function getProxyBaseURL() {
const isDev = import.meta.env.DEV;

View file

@ -13,6 +13,7 @@
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
import { proxyFetchPost } from '@/api/http';
import { SITE_URL } from '@/lib';
import { toast } from 'sonner';
export const share = async (taskId: string) => {
@ -20,7 +21,7 @@ export const share = async (taskId: string) => {
const res = await proxyFetchPost(`/api/v1/chat/share`, {
task_id: taskId,
});
const shareLink = `${import.meta.env.VITE_USE_LOCAL_PROXY === 'true' ? 'eigent://callback' : 'https://www.eigent.ai/download'}?share_token=${res.share_token}__${taskId}`;
const shareLink = `${import.meta.env.VITE_USE_LOCAL_PROXY === 'true' ? 'eigent://callback' : `${SITE_URL}/download`}?share_token=${res.share_token}__${taskId}`;
navigator.clipboard
.writeText(shareLink)
.then(() => {

View file

@ -37,6 +37,7 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { SITE_URL } from '@/lib';
import { INIT_PROVODERS } from '@/lib/llm';
import { useAuthStore } from '@/store/authStore';
import { Provider } from '@/types';
@ -1200,7 +1201,7 @@ export default function SettingModels() {
</span>
<span
onClick={() => {
window.location.href = `https://www.eigent.ai/pricing`;
window.location.href = `${SITE_URL}/pricing`;
}}
className="cursor-pointer text-body-sm text-text-label underline"
>
@ -1223,7 +1224,7 @@ export default function SettingModels() {
</div>
<Button
onClick={() => {
window.location.href = `https://www.eigent.ai/dashboard`;
window.location.href = `${SITE_URL}/dashboard`;
}}
variant="primary"
size="sm"

View file

@ -15,6 +15,7 @@
import { fetchDelete, fetchGet, fetchPost } from '@/api/http';
import AlertDialog from '@/components/ui/alertDialog';
import { Button } from '@/components/ui/button';
import { SITE_URL } from '@/lib';
import { Cookie, Plus, RefreshCw, Trash2 } from 'lucide-react';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -332,7 +333,7 @@ export default function Cookies() {
<div className="w-full text-center text-label-xs text-text-label">
For more information, check out our
<a
href="https://www.eigent.ai/privacy-policy"
href={`${SITE_URL}/privacy-policy`}
target="_blank"
className="ml-1 text-text-information underline"
rel="noreferrer"

View file

@ -20,7 +20,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
import { proxyFetchGet, proxyFetchPost } from '@/api/http';
import WindowControls from '@/components/WindowControls';
import { hasStackKeys } from '@/lib';
import { hasStackKeys, SITE_URL } from '@/lib';
import { useTranslation } from 'react-i18next';
import background from '@/assets/background.png';
@ -352,7 +352,7 @@ export default function Login() {
onClick={() => {
setIsLoading(true);
window.open(
`https://www.eigent.ai/signin?callbackUrl=${encodeURIComponent(callbackUrl || 'eigent://auth/callback')}`,
`${SITE_URL}/signin?callbackUrl=${encodeURIComponent(callbackUrl || 'eigent://auth/callback')}`,
'_blank',
'noopener,noreferrer'
);

View file

@ -18,6 +18,7 @@ import transparent from '@/assets/transparent.png';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { LocaleEnum, switchLanguage } from '@/i18n';
import { SITE_URL } from '@/lib';
import { useAuthStore } from '@/store/authStore';
import { useInstallationStore } from '@/store/installationStore';
import { LogOut, Settings } from 'lucide-react';
@ -266,7 +267,7 @@ export default function SettingGeneral() {
<div className="flex items-center gap-sm">
<Button
onClick={() => {
window.location.href = `https://www.eigent.ai/dashboard?email=${authStore.email}`;
window.location.href = `${SITE_URL}/dashboard?email=${authStore.email}`;
}}
variant="primary"
size="sm"

View file

@ -15,6 +15,7 @@
import { proxyFetchGet, proxyFetchPut } from '@/api/http';
import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch';
import { SITE_URL } from '@/lib';
import { ChevronDown } from 'lucide-react';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -64,7 +65,7 @@ export default function SettingPrivacy() {
{t('setting.data-privacy-description')}{' '}
<a
className="text-blue-500 no-underline"
href="https://www.eigent.ai/privacy-policy"
href={`${SITE_URL}/privacy-policy`}
target="_blank"
rel="noreferrer"
>

View file

@ -18,6 +18,7 @@ import VerticalNavigation, {
type VerticalNavItem,
} from '@/components/Navigation';
import useAppVersion from '@/hooks/use-app-version';
import { SITE_URL } from '@/lib';
import General from '@/pages/Setting/General';
import Privacy from '@/pages/Setting/Privacy';
import { useAuthStore } from '@/store/authStore';
@ -69,8 +70,8 @@ export default function Setting() {
return (
<div className="m-auto flex h-auto max-w-[940px] flex-col">
<div className="px-6 flex h-auto w-full">
<div className="top-20 w-40 pr-6 pt-8 sticky flex h-full flex-shrink-0 flex-grow-0 flex-col justify-between self-start">
<div className="flex h-auto w-full px-6">
<div className="sticky top-20 flex h-full w-40 flex-shrink-0 flex-grow-0 flex-col justify-between self-start pr-6 pt-8">
<VerticalNavigation
items={
settingMenus.map((menu) => {
@ -84,11 +85,11 @@ export default function Setting() {
}
value={activeTab}
onValueChange={handleTabChange}
className="min-h-0 gap-0 h-full w-full flex-1"
className="h-full min-h-0 w-full flex-1 gap-0"
listClassName="w-full h-full overflow-y-auto"
contentClassName="hidden"
/>
<div className="mt-4 gap-4 border-border-secondary py-4 flex w-full flex-shrink-0 flex-grow-0 flex-col items-center justify-center border-x-0 border-t-[0.5px] border-b-0 border-solid">
<div className="mt-4 flex w-full flex-shrink-0 flex-grow-0 flex-col items-center justify-center gap-4 border-x-0 border-b-0 border-t-[0.5px] border-solid border-border-secondary py-4">
<button
onClick={() =>
window.open(
@ -97,7 +98,7 @@ export default function Setting() {
'noopener,noreferrer'
)
}
className="gap-2 rounded-lg bg-surface-tertiary px-6 py-1.5 flex w-full cursor-pointer flex-row items-center justify-center transition-opacity duration-200 hover:opacity-60"
className="flex w-full cursor-pointer flex-row items-center justify-center gap-2 rounded-lg bg-surface-tertiary px-6 py-1.5 transition-opacity duration-200 hover:opacity-60"
>
<TagIcon className="h-4 w-4 text-text-success" />
<div className="text-label-sm font-semibold text-text-body">
@ -106,11 +107,7 @@ export default function Setting() {
</button>
<button
onClick={() =>
window.open(
'https://www.eigent.ai',
'_blank',
'noopener,noreferrer'
)
window.open(SITE_URL, '_blank', 'noopener,noreferrer')
}
className="flex cursor-pointer items-center bg-transparent transition-opacity duration-200 hover:opacity-60"
>
@ -120,7 +117,7 @@ export default function Setting() {
</div>
<div className="flex h-auto w-full flex-1 flex-col">
<div className="gap-4 flex flex-col">
<div className="flex flex-col gap-4">
{activeTab === 'general' && <General />}
{activeTab === 'privacy' && <Privacy />}
</div>

View file

@ -13,6 +13,7 @@
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
import { Button } from '@/components/ui/button';
import { SITE_URL } from '@/lib';
import { useAuthStore } from '@/store/authStore';
import { useStackApp } from '@stackframe/react';
import { useCallback, useEffect, useRef, useState } from 'react';
@ -52,11 +53,7 @@ export default function SignUp() {
// Hybrid/app mode without Stack keys: redirect to external signup
useEffect(() => {
if (!IS_LOCAL_MODE && !HAS_STACK_KEYS) {
window.open(
'https://www.eigent.ai/signup',
'_blank',
'noopener,noreferrer'
);
window.open(`${SITE_URL}/signup`, '_blank', 'noopener,noreferrer');
navigate('/login', { replace: true });
}
}, [navigate]);