feat: clarify image generation output controls
This commit is contained in:
@@ -37,7 +37,7 @@ const NAV_SECTIONS: NavSection[] = [
|
|||||||
{ to: '/skills', label: '技能' },
|
{ to: '/skills', label: '技能' },
|
||||||
{ to: '/policies', label: '策略' },
|
{ to: '/policies', label: '策略' },
|
||||||
{ to: '/providers', label: '统一模型中心' },
|
{ to: '/providers', label: '统一模型中心' },
|
||||||
{ to: '/asset-gateway', label: '资产能力' },
|
{ to: '/asset-gateway', label: '图片生成' },
|
||||||
{ to: '/blocked-words', label: '违禁词管理' },
|
{ to: '/blocked-words', label: '违禁词管理' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ export function AssetGatewayPage() {
|
|||||||
const [message, setMessage] = useState<string | null>(null);
|
const [message, setMessage] = useState<string | null>(null);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const activeKeys = useMemo(() => keys.filter((key) => key.status === 'active'), [keys]);
|
const activeKeys = useMemo(() => keys.filter((key) => key.status === 'active'), [keys]);
|
||||||
|
const orderedPlugins = useMemo(() => config?.plugins.slice().sort((left, right) => {
|
||||||
|
if (left.pluginId === 'asset-generate') return -1;
|
||||||
|
if (right.pluginId === 'asset-generate') return 1;
|
||||||
|
return left.pluginId.localeCompare(right.pluginId);
|
||||||
|
}) ?? [], [config]);
|
||||||
|
|
||||||
const load = useCallback(async () => {
|
const load = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -108,16 +113,16 @@ export function AssetGatewayPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="admin-page">
|
<div className="admin-page">
|
||||||
<div className="admin-page-head">
|
<div className="admin-page-head">
|
||||||
<h2>资产能力</h2>
|
<h2>图片生成</h2>
|
||||||
<p className="muted">可插拔图片、素材与处理能力。默认关闭,不会影响现有聊天或页面生成流程。</p>
|
<p className="muted">分别控制正文图片、页面头图、卡片封面和信息流缩略图;未勾选的 AI 图片项不会执行。</p>
|
||||||
</div>
|
</div>
|
||||||
{error && <p className="banner banner-error">{error}</p>}
|
{error && <p className="banner banner-error">{error}</p>}
|
||||||
{message && <p className="banner banner-success">{message}</p>}
|
{message && <p className="banner banner-success">{message}</p>}
|
||||||
<section className="asset-gateway-hero">
|
<section className="asset-gateway-hero">
|
||||||
<div>
|
<div>
|
||||||
<div className="asset-kicker">OPTIONAL CAPABILITY</div>
|
<div className="asset-kicker">OPTIONAL CAPABILITY</div>
|
||||||
<h3>资产能力 Gateway</h3>
|
<h3>图片与素材能力总开关</h3>
|
||||||
<p>关闭时所有调用自动降级为现有流程;配置保留,现有聊天和页面生成不受影响。</p>
|
<p>关闭时不调用图片模型;页面仍保留现有无图样式和基础缩略图流程。</p>
|
||||||
</div>
|
</div>
|
||||||
<label className="asset-toggle">
|
<label className="asset-toggle">
|
||||||
<input type="checkbox" checked={config.enabled} disabled={busy === 'global'} onChange={(event) => void saveGlobal(event.target.checked)} />
|
<input type="checkbox" checked={config.enabled} disabled={busy === 'global'} onChange={(event) => void saveGlobal(event.target.checked)} />
|
||||||
@@ -125,7 +130,7 @@ export function AssetGatewayPage() {
|
|||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
<div className="asset-plugin-grid asset-plugin-grid--balanced">
|
<div className="asset-plugin-grid asset-plugin-grid--balanced">
|
||||||
{config.plugins.map((plugin) => {
|
{orderedPlugins.map((plugin) => {
|
||||||
const draft = drafts[plugin.pluginId] ?? draftFromPlugin(plugin);
|
const draft = drafts[plugin.pluginId] ?? draftFromPlugin(plugin);
|
||||||
const selectedKey = activeKeys.find((key) => key.id === draft.llmProviderKeyId);
|
const selectedKey = activeKeys.find((key) => key.id === draft.llmProviderKeyId);
|
||||||
const visual = pluginVisuals[plugin.pluginId] ?? { icon: '✦', accent: 'blue' };
|
const visual = pluginVisuals[plugin.pluginId] ?? { icon: '✦', accent: 'blue' };
|
||||||
@@ -165,7 +170,7 @@ export function AssetGatewayPage() {
|
|||||||
</> : <div className="asset-no-llm">确定性处理 · 不调用 LLM</div>}
|
</> : <div className="asset-no-llm">确定性处理 · 不调用 LLM</div>}
|
||||||
{plugin.pluginId === 'asset-generate' && plugin.purposeCatalog?.length ? (
|
{plugin.pluginId === 'asset-generate' && plugin.purposeCatalog?.length ? (
|
||||||
<fieldset className="asset-purpose-fieldset" disabled={!draft.enabled || draft.provider !== 'image_make'}>
|
<fieldset className="asset-purpose-fieldset" disabled={!draft.enabled || draft.provider !== 'image_make'}>
|
||||||
<legend>image_make 生效范围</legend>
|
<legend>AI 图片输出项</legend>
|
||||||
<div className="asset-purpose-grid">
|
<div className="asset-purpose-grid">
|
||||||
{plugin.purposeCatalog.map((purpose) => (
|
{plugin.purposeCatalog.map((purpose) => (
|
||||||
<label key={purpose.id}>
|
<label key={purpose.id}>
|
||||||
@@ -174,11 +179,14 @@ export function AssetGatewayPage() {
|
|||||||
checked={Boolean(draft.purposes[purpose.id])}
|
checked={Boolean(draft.purposes[purpose.id])}
|
||||||
onChange={(event) => updatePurpose(plugin.pluginId, purpose.id, event.target.checked)}
|
onChange={(event) => updatePurpose(plugin.pluginId, purpose.id, event.target.checked)}
|
||||||
/>
|
/>
|
||||||
<span>{purpose.label}<small>{purpose.presetId}</small></span>
|
<span>
|
||||||
|
{purpose.label}
|
||||||
|
<small>{purpose.strategy === 'derive' ? '从页面头图派生 · 不重复生图' : purpose.presetId}</small>
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<p>信息流缩略图仍由 MindSpace 从封面源图派生,不会重复调用生图模型。</p>
|
<p>页面头图最多生成一次;卡片封面和信息流缩略图复用同一张主图裁剪。关闭某项后,该位置不使用 AI 图片;基础页面缩略图仍保留。</p>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const QUICK_LINKS = [
|
|||||||
{ to: '/users', label: '用户管理', desc: '创建账号、启用禁用' },
|
{ to: '/users', label: '用户管理', desc: '创建账号、启用禁用' },
|
||||||
{ to: '/billing/recharge', label: '充值', desc: '为用户账户充值' },
|
{ to: '/billing/recharge', label: '充值', desc: '为用户账户充值' },
|
||||||
{ to: '/providers', label: '统一模型中心', desc: 'Provider、执行器模型与启动控制' },
|
{ to: '/providers', label: '统一模型中心', desc: 'Provider、执行器模型与启动控制' },
|
||||||
{ to: '/asset-gateway', label: '资产能力', desc: '可插拔素材插件、Provider 与专属 LLM 选择' },
|
{ to: '/asset-gateway', label: '图片生成', desc: '配置正文图、页面头图、卡片封面与信息流缩略图' },
|
||||||
{ to: '/mindspace', label: 'MindSpace 配置', desc: '公开页上限与空间发布参数' },
|
{ to: '/mindspace', label: 'MindSpace 配置', desc: '公开页上限与空间发布参数' },
|
||||||
{ to: '/memory-v2', label: 'Memory V2', desc: '长期记忆 backend 与前置路由开关' },
|
{ to: '/memory-v2', label: 'Memory V2', desc: '长期记忆 backend 与前置路由开关' },
|
||||||
{ to: '/skill-runtime', label: 'Skill Runtime', desc: 'H5 manifest 关键词路由开关' },
|
{ to: '/skill-runtime', label: 'Skill Runtime', desc: 'H5 manifest 关键词路由开关' },
|
||||||
|
|||||||
@@ -1111,6 +1111,11 @@ body,
|
|||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.asset-purpose-grid small {
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
line-height: 1.35;
|
||||||
|
}
|
||||||
|
|
||||||
.asset-purpose-grid {
|
.asset-purpose-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ export type AssetPluginConfig = {
|
|||||||
id: string;
|
id: string;
|
||||||
label: string;
|
label: string;
|
||||||
presetId: string;
|
presetId: string;
|
||||||
|
strategy?: 'generate' | 'derive';
|
||||||
|
sourcePurpose?: string | null;
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user