diff --git a/.env b/.env index 72324e587..424107578 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ # 微信小程序 web-view 登录配置。 # 留空时不覆盖已有微信网页 OAuth 配置;正式联调时再填小程序 AppID / AppSecret。 -VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=false +GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=false WECHAT_MINI_PROGRAM_APP_ID="" WECHAT_MINI_PROGRAM_APP_SECRET="" diff --git a/.env.example b/.env.example index 32a49b796..6b611bebd 100644 --- a/.env.example +++ b/.env.example @@ -199,9 +199,9 @@ VITE_LLM_DEBUG_LOG="false" # Set to "true" to expose local diagnostic panels, or "false" to hide them. VITE_DEBUG_MODE="" -# Optional: show the image editor right-side Agent entry. -# Keep this off by default outside local development. -VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR="false" +# Optional: show the image editor right-side Agent entry at runtime. +# This is read by api-server and exposed through /api/runtime/frontend-config. +GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR="false" # Optional: official VikingDB credentials for regenerating build-tag similarities # with the Python embedding script. The script auto-loads `.env.local` and uses diff --git a/.env.local b/.env.local index cbc3ab9a0..66c7cb8e0 100644 --- a/.env.local +++ b/.env.local @@ -42,7 +42,7 @@ LLM_DEBUG_LOG="true" # 注意:不要在客户端启用调试日志,避免敏感数据泄露 # VITE_LLM_DEBUG_LOG="false" -VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=true +GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=true ALIYUN_OSS_BUCKET="xushi-dev" ALIYUN_OSS_REGION="oss-cn-beijing" diff --git a/deploy/env/api-server.env.example b/deploy/env/api-server.env.example index a0ac06244..55e98f44a 100644 --- a/deploy/env/api-server.env.example +++ b/deploy/env/api-server.env.example @@ -49,6 +49,7 @@ AUTH_REFRESH_COOKIE_PATH=/api/auth AUTH_REFRESH_COOKIE_SAME_SITE=Lax AUTH_REFRESH_COOKIE_SECURE=true GENARRATIVE_DEV_PASSWORD_ENTRY_AUTO_REGISTER_ENABLED=false +GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=false GENARRATIVE_SPACETIME_SERVER_URL=http://127.0.0.1:3101 GENARRATIVE_SPACETIME_DATABASE=genarrative-prod diff --git a/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md b/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md index f70da612d..c85477a89 100644 --- a/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md +++ b/docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md @@ -60,7 +60,7 @@ npm run check:server-rs-ddd - 平台基础能力:`/api/llm/*`、`/api/speech/volcengine/*`,只保留通用 LLM 和语音代理。 - 资产基础能力:`/api/assets/direct-upload-tickets`、`/api/assets/sts-upload-credentials`、`/api/assets/objects/*`、`/api/assets/read-*`,负责直传、确认、绑定和读取。 - 外部 OpenAPI:`/api/external/v1/openapi.json`、`/api/external/v1/assets/direct-upload-tickets`、`/api/external/v1/assets/objects/confirm`、`/api/external/v1/assets/read-url`、`/api/external/v1/editor/*`,使用 Bearer API Key 鉴权;API Key 管理仍在登录态 `/api/profile/api-keys`,不进入外部 OpenAPI JSON。 -- 创作 / 游玩支撑能力:`/api/creation-entry/config`、`/api/ai/tasks*`、`/api/runtime/chat/*`、`/api/runtime/settings`、`/api/runtime/save/snapshot`、`/api/profile/browse-history`、`/api/profile/save-archives*`、`/api/profile/play-stats`、`/api/assets/history`、`/api/assets/character-visual/*`、`/api/assets/character-animation/*`、`/api/assets/character-workflow-cache*`、`/api/assets/hyper3d/*`、`/api/runtime/custom-world/asset-studio/*`、`/api/editor/projects*`、`/api/editor/projects/{projectId}/agent-conversations`、`/api/editor/agent-conversations/{conversationId}*`。`/api/runtime/custom-world/asset-studio/*` 解析默认角色形象 / 动作提示词时可以在 OSS 缓存不可用或未配置时按无缓存返回默认提示;保存 workflow 缓存和真实素材读写仍必须要求 OSS 正常可用。 +- 创作 / 游玩支撑能力:`/api/creation-entry/config`、`/api/ai/tasks*`、`/api/runtime/frontend-config`、`/api/runtime/chat/*`、`/api/runtime/settings`、`/api/runtime/save/snapshot`、`/api/profile/browse-history`、`/api/profile/save-archives*`、`/api/profile/play-stats`、`/api/assets/history`、`/api/assets/character-visual/*`、`/api/assets/character-animation/*`、`/api/assets/character-workflow-cache*`、`/api/assets/hyper3d/*`、`/api/runtime/custom-world/asset-studio/*`、`/api/editor/projects*`、`/api/editor/projects/{projectId}/agent-conversations`、`/api/editor/agent-conversations/{conversationId}*`。`/api/runtime/frontend-config` 由 `api-server` 从运行时环境变量下发非敏感 UI 开关;画板右侧 Agent 入口由 `GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR` 控制,默认关闭,前端不再读取 `VITE_*` 构建期变量决定生产显示。`/api/runtime/custom-world/asset-studio/*` 解析默认角色形象 / 动作提示词时可以在 OSS 缓存不可用或未配置时按无缓存返回默认提示;保存 workflow 缓存和真实素材读写仍必须要求 OSS 正常可用。 - 后台入口配置:`/admin/api/creation-entry/config`、`/admin/api/creation-entry/config/banners` 和 `/admin/api/creation-entry/config/interactions`。 - 后台素材查询:`GET /admin/api/editor-assets` 通过 `admin_list_editor_assets_and_return` 后台只读 procedure 读取私有账号级 `editor_asset` 中 `source_type = 'generated'` 的素材,支持 `ownerUserId`、`keyword`、`createdAfter`、`createdBefore`、`cursor` 和 `limit`;返回缩略图 / Object Key、作者展示名、陶泥号、提示词、生成输入和生成成本,只用于查询,不提供分类筛选,也不执行精选审核、返还或展示状态修改,不通过后台 SQL 直查私有表。 - 自定义世界 / RPG:`/api/runtime/custom-world*`、`/api/story/*`、`/api/runtime/chat/*`。 diff --git a/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md b/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md index 720e9d07f..c72151731 100644 --- a/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md +++ b/docs/【开发运维】本地开发验证与生产运维-2026-05-15.md @@ -234,6 +234,10 @@ npm run database:backup:oss -- --data-dir /stdb --stop-service spacetimedb.servi 生产环境变量模板在 `deploy/env/api-server.env.example`: +主站前端运行时配置由 `api-server` 下发;画板右侧 Agent 入口使用 +`GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=false` 默认关闭,需要开启时只改生产 +api-server 环境变量并重启 `api-server`,不再通过 `VITE_*` 构建期变量控制。 + ```env GENARRATIVE_DATABASE_BACKUP_DATA_DIR=/stdb GENARRATIVE_DATABASE_BACKUP_WORK_DIR=/var/lib/genarrative/database-backups diff --git a/server-rs/crates/api-server/src/app.rs b/server-rs/crates/api-server/src/app.rs index 48bc995f1..3ede90f65 100644 --- a/server-rs/crates/api-server/src/app.rs +++ b/server-rs/crates/api-server/src/app.rs @@ -43,6 +43,7 @@ pub fn build_router(state: AppState) -> Router { .merge(modules::auth::router(state.clone())) .merge(modules::profile::router(state.clone())) .merge(modules::external_api::router(state.clone())) + .merge(modules::frontend_runtime_config::router(state.clone())) .merge(modules::assets::router(state.clone())) .merge(modules::editor_project::router(state.clone())) .merge(modules::platform::router(state.clone())) @@ -518,6 +519,51 @@ mod tests { ); } + #[tokio::test] + async fn frontend_runtime_config_defaults_agent_sidebar_to_disabled() { + let app = build_router(AppState::new(AppConfig::default()).expect("state should build")); + + let response = app + .oneshot( + Request::builder() + .uri("/api/runtime/frontend-config") + .body(Body::empty()) + .expect("frontend config request should build"), + ) + .await + .expect("frontend config request should succeed"); + + assert_eq!(response.status(), StatusCode::OK); + let payload = read_json_response(response).await; + assert_eq!( + payload["imageEditorAgentSidebarEnabled"], + Value::Bool(false) + ); + } + + #[tokio::test] + async fn frontend_runtime_config_returns_agent_sidebar_env_flag() { + let config = AppConfig { + image_editor_agent_sidebar_enabled: true, + ..AppConfig::default() + }; + let app = build_router(AppState::new(config).expect("state should build")); + + let response = app + .oneshot( + Request::builder() + .uri("/api/runtime/frontend-config") + .body(Body::empty()) + .expect("frontend config request should build"), + ) + .await + .expect("frontend config request should succeed"); + + assert_eq!(response.status(), StatusCode::OK); + let payload = read_json_response(response).await; + assert_eq!(payload["imageEditorAgentSidebarEnabled"], Value::Bool(true)); + } + #[tokio::test] async fn spacetime_unavailable_router_returns_service_unavailable_for_requests() { let app = diff --git a/server-rs/crates/api-server/src/config.rs b/server-rs/crates/api-server/src/config.rs index fa03dc2a6..721500570 100644 --- a/server-rs/crates/api-server/src/config.rs +++ b/server-rs/crates/api-server/src/config.rs @@ -56,6 +56,7 @@ pub struct AppConfig { pub editor_background_removal_base_url: String, pub editor_background_removal_token: Option, pub editor_background_removal_request_timeout_ms: u64, + pub image_editor_agent_sidebar_enabled: bool, pub log_filter: String, pub otel_enabled: bool, pub admin_username: Option, @@ -283,6 +284,7 @@ impl Default for AppConfig { editor_background_removal_token: None, editor_background_removal_request_timeout_ms: DEFAULT_EDITOR_BACKGROUND_REMOVAL_REQUEST_TIMEOUT_MS, + image_editor_agent_sidebar_enabled: false, log_filter: "info,tower_http=info".to_string(), otel_enabled: false, admin_username: None, @@ -473,6 +475,11 @@ impl AppConfig { ]) { config.editor_background_removal_request_timeout_ms = timeout_ms; } + if let Some(enabled) = + read_first_bool_env(&["GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR"]) + { + config.image_editor_agent_sidebar_enabled = enabled; + } if let Some(listen_backlog) = read_first_positive_i32_env(&["GENARRATIVE_API_LISTEN_BACKLOG"]) { @@ -2176,6 +2183,26 @@ mod tests { } } + #[test] + fn from_env_reads_image_editor_agent_sidebar_runtime_flag() { + let _guard = ENV_LOCK + .get_or_init(|| Mutex::new(())) + .lock() + .expect("env lock should not poison"); + + unsafe { + std::env::remove_var("GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR"); + std::env::set_var("GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR", "true"); + } + + let config = AppConfig::from_env(); + assert!(config.image_editor_agent_sidebar_enabled); + + unsafe { + std::env::remove_var("GENARRATIVE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR"); + } + } + #[test] fn from_env_reads_prefixed_character_animation_ffmpeg_paths() { let _guard = ENV_LOCK diff --git a/server-rs/crates/api-server/src/frontend_runtime_config.rs b/server-rs/crates/api-server/src/frontend_runtime_config.rs new file mode 100644 index 000000000..64aea1631 --- /dev/null +++ b/server-rs/crates/api-server/src/frontend_runtime_config.rs @@ -0,0 +1,25 @@ +use axum::{ + Json, + extract::{Extension, State}, +}; +use serde::Serialize; + +use crate::{api_response::json_success_body, request_context::RequestContext, state::AppState}; + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct FrontendRuntimeConfigResponse { + pub image_editor_agent_sidebar_enabled: bool, +} + +pub async fn get_frontend_runtime_config( + State(state): State, + Extension(request_context): Extension, +) -> Json { + json_success_body( + Some(&request_context), + FrontendRuntimeConfigResponse { + image_editor_agent_sidebar_enabled: state.config.image_editor_agent_sidebar_enabled, + }, + ) +} diff --git a/server-rs/crates/api-server/src/main.rs b/server-rs/crates/api-server/src/main.rs index 6e109a4cb..c05b63082 100644 --- a/server-rs/crates/api-server/src/main.rs +++ b/server-rs/crates/api-server/src/main.rs @@ -52,6 +52,7 @@ mod external_editor_api; mod external_generation; mod external_generation_worker; mod external_generation_worker_controller; +mod frontend_runtime_config; pub(crate) mod generated_asset_sheets; mod generated_image_assets; mod health; diff --git a/server-rs/crates/api-server/src/modules.rs b/server-rs/crates/api-server/src/modules.rs index ee51d7682..5b1da6d9b 100644 --- a/server-rs/crates/api-server/src/modules.rs +++ b/server-rs/crates/api-server/src/modules.rs @@ -8,6 +8,7 @@ pub mod editor_project; pub mod edutainment; pub mod external_api; pub mod external_generation; +pub mod frontend_runtime_config; pub mod health; pub mod internal; pub mod jump_hop; diff --git a/server-rs/crates/api-server/src/modules/frontend_runtime_config.rs b/server-rs/crates/api-server/src/modules/frontend_runtime_config.rs new file mode 100644 index 000000000..0307b2e62 --- /dev/null +++ b/server-rs/crates/api-server/src/modules/frontend_runtime_config.rs @@ -0,0 +1,10 @@ +use axum::{Router, routing::get}; + +use crate::{frontend_runtime_config::get_frontend_runtime_config, state::AppState}; + +pub fn router(_state: AppState) -> Router { + Router::new().route( + "/api/runtime/frontend-config", + get(get_frontend_runtime_config), + ) +} diff --git a/src/components/image-editor/ImageCanvasEditorView.test.tsx b/src/components/image-editor/ImageCanvasEditorView.test.tsx index 67b9f73a7..0406607f6 100644 --- a/src/components/image-editor/ImageCanvasEditorView.test.tsx +++ b/src/components/image-editor/ImageCanvasEditorView.test.tsx @@ -41,7 +41,6 @@ type EditorAgentConversationSummary = Awaited< type EditorAgentConversationDetail = Awaited< ReturnType >; -const EDITOR_AGENT_SIDEBAR_ENV = 'VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR'; const listEditorAgentConversationsMock = vi.hoisted(() => vi.fn< @@ -110,6 +109,7 @@ const loadOrCreateRecentEditorProjectMock = vi.hoisted(() => vi.fn()); const renameEditorProjectMock = vi.hoisted(() => vi.fn()); const saveEditorProjectLayoutMock = vi.hoisted(() => vi.fn()); const getPlatformProfileDashboardMock = vi.hoisted(() => vi.fn()); +const loadFrontendRuntimeConfigMock = vi.hoisted(() => vi.fn()); vi.mock('../../services/image-editor/editorProjectClient', async () => { const actual = await vi.importActual< @@ -140,6 +140,10 @@ vi.mock('../../services/platform-entry/platformProfileClient', () => ({ getPlatformProfileDashboard: getPlatformProfileDashboardMock, })); +vi.mock('../../services/frontendRuntimeConfigService', () => ({ + loadFrontendRuntimeConfig: loadFrontendRuntimeConfigMock, +})); + vi.mock('../../services/image-editor/editorAgentClient', () => ({ createEditorAgentConversation: createEditorAgentConversationMock, deleteEditorAgentConversation: deleteEditorAgentConversationMock, @@ -214,7 +218,7 @@ function openMinimap() { } async function ensureAgentConversationOpen() { - const agentButton = screen.getByRole('button', { name: '画布 Agent' }); + const agentButton = await screen.findByRole('button', { name: '画布 Agent' }); if (agentButton.getAttribute('aria-pressed') !== 'true') { fireEvent.click(agentButton); } @@ -222,7 +226,9 @@ async function ensureAgentConversationOpen() { } function enableEditorAgentSidebarForTest() { - vi.stubEnv(EDITOR_AGENT_SIDEBAR_ENV, 'true'); + loadFrontendRuntimeConfigMock.mockResolvedValue({ + imageEditorAgentSidebarEnabled: true, + }); } describe('ImageCanvasEditorView', () => { @@ -246,7 +252,9 @@ describe('ImageCanvasEditorView', () => { }); beforeEach(() => { - vi.stubEnv(EDITOR_AGENT_SIDEBAR_ENV, 'false'); + loadFrontendRuntimeConfigMock.mockResolvedValue({ + imageEditorAgentSidebarEnabled: false, + }); listEditorAgentConversationsMock.mockResolvedValue([]); createEditorAgentConversationMock.mockResolvedValue({ ...createEditorAgentConversationSummary({ @@ -277,7 +285,7 @@ describe('ImageCanvasEditorView', () => { deleteEditorAgentConversationMock.mockReset(); streamEditorAgentMessageMock.mockReset(); getPlatformProfileDashboardMock.mockReset(); - vi.unstubAllEnvs(); + loadFrontendRuntimeConfigMock.mockReset(); }); it('loads the project from projectid query before falling back to recent project', async () => { @@ -1487,6 +1495,8 @@ describe('ImageCanvasEditorView', () => { enableEditorAgentSidebarForTest(); render(); + await screen.findByRole('button', { name: '画布 Agent' }); + const assetSidebar = openAssetSidebar(); expect(within(assetSidebar).getByText('素材')).toBeTruthy(); @@ -1507,7 +1517,7 @@ describe('ImageCanvasEditorView', () => { screen.getByRole('complementary', { name: '画布任务列表' }), ).toBeTruthy(); - fireEvent.click(screen.getByRole('button', { name: '画布 Agent' })); + fireEvent.click(await screen.findByRole('button', { name: '画布 Agent' })); expect( screen.getByRole('complementary', { name: '图片资源栏' }), ).toBeTruthy(); diff --git a/src/components/image-editor/ImageCanvasEditorView.tsx b/src/components/image-editor/ImageCanvasEditorView.tsx index 504334bf5..8f96c6ef3 100644 --- a/src/components/image-editor/ImageCanvasEditorView.tsx +++ b/src/components/image-editor/ImageCanvasEditorView.tsx @@ -19,6 +19,7 @@ import { loadEditorProject, loadEditorGenerationPricing, } from '../../services/image-editor/editorProjectClient'; +import { loadFrontendRuntimeConfig } from '../../services/frontendRuntimeConfigService'; import { shouldShowRechargeEntry } from '../../services/payment/paymentPlatform'; import { getPlatformProfileDashboard } from '../../services/platform-entry/platformProfileClient'; import { useAuthUi } from '../auth/AuthUiContext'; @@ -117,12 +118,6 @@ type ImageCanvasEditorViewProps = { onProjectAccessLost?: () => void; }; -function resolveEditorAgentSidebarEnabled( - rawValue = import.meta.env.VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR, -): boolean { - return rawValue === 'true' || rawValue === '1'; -} - function isCanvasStartupTool(value: string | null): value is CanvasStartupTool { return CANVAS_STARTUP_TOOLS.includes(value as CanvasStartupTool); } @@ -327,6 +322,9 @@ export function ImageCanvasEditorView({ const showRechargeEntry = shouldShowRechargeEntry(); const currentEditorUserId = authUi?.user?.id ?? null; const [isToolbarGuideVisible, setIsToolbarGuideVisible] = useState(false); + const [isAgentConversationEnabled, setIsAgentConversationEnabled] = + useState(false); + const [isAgentConversationOpen, setIsAgentConversationOpen] = useState(false); useEffect(() => { let isMounted = true; @@ -345,6 +343,28 @@ export function ImageCanvasEditorView({ isMounted = false; }; }, []); + useEffect(() => { + let isMounted = true; + void loadFrontendRuntimeConfig() + .then((config) => { + if (!isMounted) { + return; + } + const enabled = config.imageEditorAgentSidebarEnabled === true; + setIsAgentConversationEnabled(enabled); + setIsAgentConversationOpen(enabled); + }) + .catch(() => { + if (!isMounted) { + return; + } + setIsAgentConversationEnabled(false); + setIsAgentConversationOpen(false); + }); + return () => { + isMounted = false; + }; + }, []); const selectedLayerIdsRef = useRef([]); const setQuickEditPanelRef = useRef< Dispatch> @@ -1167,10 +1187,6 @@ export function ImageCanvasEditorView({ applyProjectSnapshot: applyGeneratedProjectSnapshot, onWalletBalanceMayHaveChanged: refreshEditorWalletBalance, }); - const isAgentConversationEnabled = resolveEditorAgentSidebarEnabled(); - const [isAgentConversationOpen, setIsAgentConversationOpen] = useState( - () => isAgentConversationEnabled, - ); const effectiveIsAgentConversationOpen = isAgentConversationEnabled && isAgentConversationOpen; const toggleAgentConversation = useCallback(() => { diff --git a/src/services/frontendRuntimeConfigService.test.ts b/src/services/frontendRuntimeConfigService.test.ts new file mode 100644 index 000000000..1c6adca9a --- /dev/null +++ b/src/services/frontendRuntimeConfigService.test.ts @@ -0,0 +1,43 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +const apiClientMocks = vi.hoisted(() => ({ + requestJson: vi.fn(), +})); + +vi.mock('./apiClient', async () => { + const actual = + await vi.importActual('./apiClient'); + return { + ...actual, + requestJson: apiClientMocks.requestJson, + }; +}); + +import { loadFrontendRuntimeConfig } from './frontendRuntimeConfigService'; + +describe('frontendRuntimeConfigService', () => { + beforeEach(() => { + vi.clearAllMocks(); + apiClientMocks.requestJson.mockResolvedValue({ + imageEditorAgentSidebarEnabled: false, + }); + }); + + it('loads public frontend runtime config without auth side effects', async () => { + await expect(loadFrontendRuntimeConfig()).resolves.toEqual({ + imageEditorAgentSidebarEnabled: false, + }); + + expect(apiClientMocks.requestJson).toHaveBeenCalledWith( + '/api/runtime/frontend-config', + { method: 'GET' }, + '读取前端运行时配置失败', + { + skipAuth: true, + skipRefresh: true, + notifyAuthStateChange: false, + clearAuthOnUnauthorized: false, + }, + ); + }); +}); diff --git a/src/services/frontendRuntimeConfigService.ts b/src/services/frontendRuntimeConfigService.ts new file mode 100644 index 000000000..2b76fba27 --- /dev/null +++ b/src/services/frontendRuntimeConfigService.ts @@ -0,0 +1,21 @@ +import { requestJson } from './apiClient'; + +const FRONTEND_RUNTIME_CONFIG_API = '/api/runtime/frontend-config'; + +export type FrontendRuntimeConfig = { + imageEditorAgentSidebarEnabled: boolean; +}; + +export async function loadFrontendRuntimeConfig() { + return requestJson( + FRONTEND_RUNTIME_CONFIG_API, + { method: 'GET' }, + '读取前端运行时配置失败', + { + skipAuth: true, + skipRefresh: true, + notifyAuthStateChange: false, + clearAuthOnUnauthorized: false, + }, + ); +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 0cf010431..81879c63e 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -2,7 +2,6 @@ interface ImportMetaEnv { readonly VITE_DEBUG_MODE?: string; - readonly VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR?: string; } interface Window {