split canvas agent mode toggle from agent workspace
This commit is contained in:
parent
1c1f7026d5
commit
63a01e6a5a
@ -248,6 +248,7 @@ type SiteSettings = {
|
||||
rankingEnabled: boolean;
|
||||
canvasEnabled: boolean;
|
||||
agentEnabled: boolean;
|
||||
canvasAgentModeEnabled: boolean;
|
||||
agentCategoryTreeConfig: {
|
||||
productCategories: string[];
|
||||
audienceTags: string[];
|
||||
@ -676,6 +677,7 @@ export function AdminSettingsClient() {
|
||||
rankingEnabled: true,
|
||||
canvasEnabled: true,
|
||||
agentEnabled: true,
|
||||
canvasAgentModeEnabled: true,
|
||||
agentCategoryTreeConfig: {
|
||||
productCategories: [],
|
||||
audienceTags: [],
|
||||
@ -761,6 +763,7 @@ export function AdminSettingsClient() {
|
||||
rankingEnabled: siteSettingsData.rankingEnabled ?? true,
|
||||
canvasEnabled: siteSettingsData.canvasEnabled ?? true,
|
||||
agentEnabled: (siteSettingsData as any).agentEnabled ?? true,
|
||||
canvasAgentModeEnabled: (siteSettingsData as any).canvasAgentModeEnabled ?? true,
|
||||
agentCategoryTreeConfig: {
|
||||
productCategories: Array.isArray((siteSettingsData as any).agentCategoryTreeConfig?.productCategories)
|
||||
? (siteSettingsData as any).agentCategoryTreeConfig.productCategories
|
||||
@ -5594,7 +5597,7 @@ export function AdminSettingsClient() {
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="agentEnabled">智能体功能</Label>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
开启后,首页侧边栏显示“智能体”入口,用户可进入画布智能体模式;关闭后隐藏入口。
|
||||
开启后,首页侧边栏显示“智能体”入口,用户可进入独立的智能体工作台;关闭后隐藏该入口。
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
@ -5606,6 +5609,22 @@ export function AdminSettingsClient() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between rounded-lg border p-3">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="canvasAgentModeEnabled">无限画布 Agent模式</Label>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
控制无限画布右侧对话框中的 Agent模式 入口,与上面的智能体工作台入口独立。
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
id="canvasAgentModeEnabled"
|
||||
checked={siteSettings.canvasAgentModeEnabled}
|
||||
onCheckedChange={(checked) =>
|
||||
setSiteSettings({ ...siteSettings, canvasAgentModeEnabled: checked })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{siteSettings.agentEnabled && (
|
||||
<div className="rounded-lg border p-4 space-y-4">
|
||||
<div>
|
||||
|
||||
@ -82,6 +82,7 @@ const MEMBERSHIP_USER_OVERRIDES_KEY = "membership_user_plan_overrides";
|
||||
const STORAGE_FAILOVER_CONFIG_KEY = "storage_failover_config";
|
||||
const REALTIME_CANVAS_CONFIG_KEY = "realtime_canvas_config";
|
||||
const AGENT_CATEGORY_TREE_CONFIG_KEY = "agent_category_tree_config";
|
||||
const CANVAS_AGENT_MODE_ENABLED_KEY = "canvas_agent_mode_enabled";
|
||||
|
||||
function normalizeHomeVariant(value: unknown): "classic" | "lovart" {
|
||||
return value === "lovart" ? "lovart" : "classic";
|
||||
@ -196,6 +197,10 @@ function normalizeStorageFailoverConfig(value: unknown): {
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeCanvasAgentModeEnabled(value: unknown): boolean {
|
||||
return value !== false;
|
||||
}
|
||||
|
||||
function normalizeAgentCategoryTreeConfig(value: unknown): AgentCategoryTreeConfig {
|
||||
const raw =
|
||||
value && typeof value === "object" && !Array.isArray(value)
|
||||
@ -244,6 +249,7 @@ export async function GET() {
|
||||
pointsPackagesSetting,
|
||||
dulupayConfigSetting,
|
||||
realtimeCanvasConfigSetting,
|
||||
canvasAgentModeEnabledSetting,
|
||||
storageFailoverConfigSetting,
|
||||
ossImageMigrationConfigSetting,
|
||||
agentPresetLibraryConfigSetting,
|
||||
@ -340,6 +346,12 @@ export async function GET() {
|
||||
.where(eq(systemSettings.key, REALTIME_CANVAS_CONFIG_KEY))
|
||||
.limit(1)
|
||||
.then(rows => rows[0]),
|
||||
db
|
||||
.select()
|
||||
.from(systemSettings)
|
||||
.where(eq(systemSettings.key, CANVAS_AGENT_MODE_ENABLED_KEY))
|
||||
.limit(1)
|
||||
.then(rows => rows[0]),
|
||||
db
|
||||
.select()
|
||||
.from(systemSettings)
|
||||
@ -429,6 +441,9 @@ export async function GET() {
|
||||
: normalizeDulupayForPublic(dulupayConfigSetting?.value);
|
||||
const realtimeCanvasServiceEnabled =
|
||||
(realtimeCanvasConfigSetting?.value as { enabled?: boolean } | undefined)?.enabled !== false;
|
||||
const canvasAgentModeEnabled = normalizeCanvasAgentModeEnabled(
|
||||
canvasAgentModeEnabledSetting?.value
|
||||
);
|
||||
const storageFailoverConfig = normalizeStorageFailoverConfig(
|
||||
storageFailoverConfigSetting?.value
|
||||
);
|
||||
@ -488,6 +503,7 @@ export async function GET() {
|
||||
rankingEnabled: true,
|
||||
canvasEnabled: true,
|
||||
agentEnabled: true,
|
||||
canvasAgentModeEnabled: true,
|
||||
agentPresetLibraryConfig: defaultAgentPresetLibraryConfig,
|
||||
agentCategoryTreeConfig: normalizeAgentCategoryTreeConfig(undefined),
|
||||
agentSecondaryTypeConfig: defaultAgentSecondaryTypeConfig,
|
||||
@ -552,6 +568,7 @@ export async function GET() {
|
||||
pointsPackages,
|
||||
dulupayConfig,
|
||||
realtimeCanvasServiceEnabled,
|
||||
canvasAgentModeEnabled,
|
||||
storageFailoverConfig,
|
||||
ossImageMigrationConfig,
|
||||
});
|
||||
@ -594,6 +611,7 @@ const updateSchema = z.object({
|
||||
rankingEnabled: z.boolean().optional(),
|
||||
canvasEnabled: z.boolean().optional(),
|
||||
agentEnabled: z.boolean().optional(),
|
||||
canvasAgentModeEnabled: z.boolean().optional(),
|
||||
agentPresetLibraryConfig: z
|
||||
.object({
|
||||
sections: z
|
||||
@ -869,6 +887,7 @@ export async function PUT(request: NextRequest) {
|
||||
dulupayConfig,
|
||||
storageFailoverConfig,
|
||||
ossImageMigrationConfig,
|
||||
canvasAgentModeEnabled,
|
||||
...siteSettingsPayload
|
||||
} = data;
|
||||
|
||||
@ -1026,6 +1045,26 @@ export async function PUT(request: NextRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
if (canvasAgentModeEnabled !== undefined) {
|
||||
const normalized = normalizeCanvasAgentModeEnabled(canvasAgentModeEnabled);
|
||||
await db
|
||||
.insert(systemSettings)
|
||||
.values({
|
||||
key: CANVAS_AGENT_MODE_ENABLED_KEY,
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: systemSettings.key,
|
||||
set: {
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (agentPresetLibraryConfig !== undefined) {
|
||||
const normalized = normalizeAgentPresetLibraryConfig(agentPresetLibraryConfig);
|
||||
await db
|
||||
@ -1416,6 +1455,10 @@ export async function PUT(request: NextRequest) {
|
||||
ossImageMigrationConfig !== undefined
|
||||
? normalizeOssImageMigrationConfig(ossImageMigrationConfig)
|
||||
: defaultOssImageMigrationConfig,
|
||||
canvasAgentModeEnabled:
|
||||
canvasAgentModeEnabled !== undefined
|
||||
? normalizeCanvasAgentModeEnabled(canvasAgentModeEnabled)
|
||||
: normalizeCanvasAgentModeEnabled(undefined),
|
||||
});
|
||||
} else {
|
||||
// 创建新设置
|
||||
@ -1597,6 +1640,26 @@ export async function PUT(request: NextRequest) {
|
||||
});
|
||||
}
|
||||
|
||||
if (canvasAgentModeEnabled !== undefined) {
|
||||
const normalized = normalizeCanvasAgentModeEnabled(canvasAgentModeEnabled);
|
||||
await db
|
||||
.insert(systemSettings)
|
||||
.values({
|
||||
key: CANVAS_AGENT_MODE_ENABLED_KEY,
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: systemSettings.key,
|
||||
set: {
|
||||
value: normalized,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: session.user.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (agentPresetLibraryConfig !== undefined) {
|
||||
const normalized = normalizeAgentPresetLibraryConfig(agentPresetLibraryConfig);
|
||||
await db
|
||||
@ -1965,6 +2028,10 @@ export async function PUT(request: NextRequest) {
|
||||
ossImageMigrationConfig !== undefined
|
||||
? normalizeOssImageMigrationConfig(ossImageMigrationConfig)
|
||||
: defaultOssImageMigrationConfig,
|
||||
canvasAgentModeEnabled:
|
||||
canvasAgentModeEnabled !== undefined
|
||||
? normalizeCanvasAgentModeEnabled(canvasAgentModeEnabled)
|
||||
: normalizeCanvasAgentModeEnabled(undefined),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@ -273,6 +273,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
siteLogo?: string | null;
|
||||
siteLogoDark?: string | null;
|
||||
agentEnabled?: boolean;
|
||||
canvasAgentModeEnabled?: boolean;
|
||||
realtimeCanvasEnabled?: boolean;
|
||||
realtimeCanvasServiceEnabled?: boolean;
|
||||
agentWorkflowShowcaseConfig?: AgentWorkflowShowcaseConfig;
|
||||
@ -306,9 +307,10 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
const previousBrandForModelRef = useRef("");
|
||||
const autoSelectedBrandModelBrandRef = useRef("");
|
||||
const requestedAgentMode = mode === "agent";
|
||||
const isAgentFeatureEnabled = siteSettingsData?.agentEnabled !== false;
|
||||
const isAgentWorkspaceEnabled = siteSettingsData?.agentEnabled !== false;
|
||||
const isCanvasAgentModeEnabled = siteSettingsData?.canvasAgentModeEnabled !== false;
|
||||
const isAgentMode =
|
||||
isAgentFeatureEnabled && requestedAgentMode;
|
||||
isAgentWorkspaceEnabled && requestedAgentMode;
|
||||
const resolvedBrandModelConfig = useMemo(
|
||||
() => normalizeAgentWorkflowBrandModelConfig(siteSettingsData?.agentWorkflowBrandModelConfig),
|
||||
[siteSettingsData?.agentWorkflowBrandModelConfig]
|
||||
@ -653,7 +655,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!requestedAgentMode || !isAgentFeatureEnabled || agentProjectId) return;
|
||||
if (!requestedAgentMode || !isAgentWorkspaceEnabled || agentProjectId) return;
|
||||
|
||||
let cancelled = false;
|
||||
const createAgentProject = async () => {
|
||||
@ -686,7 +688,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [agentProjectId, isAgentFeatureEnabled, requestedAgentMode, updateCanvasSearchParams]);
|
||||
}, [agentProjectId, isAgentWorkspaceEnabled, requestedAgentMode, updateCanvasSearchParams]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!requestedAgentMode || !agentProjectId) return;
|
||||
@ -1480,7 +1482,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
);
|
||||
|
||||
const agentDisabledNotice =
|
||||
requestedAgentMode && !isAgentFeatureEnabled ? (
|
||||
requestedAgentMode && !isAgentWorkspaceEnabled ? (
|
||||
<div className="absolute top-4 left-1/2 z-20 -translate-x-1/2">
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-amber-200 bg-amber-50 px-4 py-2 text-sm text-amber-800 shadow-sm dark:border-amber-900/60 dark:bg-amber-950/80 dark:text-amber-200">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
@ -1552,7 +1554,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
<AgentGenerationWorkspaceDarkV2
|
||||
chatId={agentModeChatId}
|
||||
projectId={id}
|
||||
selectedAgentPresetId={isAgentFeatureEnabled ? selectedAgentPresetId : null}
|
||||
selectedAgentPresetId={isAgentWorkspaceEnabled ? selectedAgentPresetId : null}
|
||||
selectedBrandModel={selectedBrandModel}
|
||||
workflowContext={workflowContext}
|
||||
agentModeState={agentModeState}
|
||||
@ -1674,7 +1676,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
onOpenFileList={() => setPanelMode('fileList')}
|
||||
selectedAgentPresetId={null}
|
||||
chatScope="canvas"
|
||||
agentEnabled={isAgentFeatureEnabled}
|
||||
agentEnabled={isCanvasAgentModeEnabled}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
@ -1725,7 +1727,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
||||
<TooltipContent side="top">平移 (H)</TooltipContent>
|
||||
</Tooltip>
|
||||
|
||||
{isAgentFeatureEnabled ? (
|
||||
{isAgentWorkspaceEnabled ? (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user