ai-chatbot/lib/agents/workflow-brand-model-config.ts
Your Name dae5f59417
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
feat: add brand model selection to agent flow
2026-03-17 22:42:03 +08:00

116 lines
3.4 KiB
TypeScript

import type {
AgentWorkflowBrandModelConfig,
AgentWorkflowBrandModelEntry,
AgentWorkflowBrandModelImage,
} from "@/types/agent";
export const AGENT_WORKFLOW_BRAND_MODEL_CONFIG_KEY = "agent_workflow_brand_model_config";
export const defaultAgentWorkflowBrandModelConfig: AgentWorkflowBrandModelConfig = {
entries: [],
};
function sanitizeText(value: unknown, maxLength: number) {
return String(value || "").trim().slice(0, maxLength);
}
function normalizeBrandModelImage(
value: unknown,
index: number
): AgentWorkflowBrandModelImage | null {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return null;
}
const raw = value as Record<string, unknown>;
const imageUrl = sanitizeText(raw.imageUrl, 2000);
if (!imageUrl) return null;
const assetId = sanitizeText(raw.assetId, 128) || null;
const id = sanitizeText(raw.id, 128) || assetId || `brand-model-${index + 1}`;
return {
id,
assetId,
imageUrl,
displayName: sanitizeText(raw.displayName, 255) || null,
mimeType: sanitizeText(raw.mimeType, 128) || null,
sortOrder: Number.isFinite(Number(raw.sortOrder))
? Math.max(0, Math.min(999, Math.round(Number(raw.sortOrder))))
: index,
};
}
function normalizeBrandModelEntry(
value: unknown,
index: number
): AgentWorkflowBrandModelEntry | null {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return null;
}
const raw = value as Record<string, unknown>;
const brandName = sanitizeText(raw.brandName, 64);
if (!brandName) return null;
const rawImages = Array.isArray(raw.images) ? raw.images : [];
const images = rawImages
.map((item, imageIndex) => normalizeBrandModelImage(item, imageIndex))
.filter((item): item is AgentWorkflowBrandModelImage => Boolean(item))
.sort((left, right) => left.sortOrder - right.sortOrder)
.slice(0, 100);
return {
brandName,
images,
};
}
export function normalizeAgentWorkflowBrandModelConfig(
value: unknown
): AgentWorkflowBrandModelConfig {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return defaultAgentWorkflowBrandModelConfig;
}
const raw = value as Record<string, unknown>;
const rawEntries = Array.isArray(raw.entries) ? raw.entries : [];
const entryMap = new Map<string, AgentWorkflowBrandModelEntry>();
rawEntries.forEach((item, index) => {
const normalized = normalizeBrandModelEntry(item, index);
if (!normalized) return;
const existing = entryMap.get(normalized.brandName);
if (!existing) {
entryMap.set(normalized.brandName, normalized);
return;
}
const imageMap = new Map<string, AgentWorkflowBrandModelImage>();
[...existing.images, ...normalized.images].forEach((image, imageIndex) => {
const key = image.assetId || image.id || image.imageUrl || `image-${imageIndex + 1}`;
if (!imageMap.has(key)) {
imageMap.set(key, {
...image,
sortOrder: imageMap.size,
});
}
});
entryMap.set(normalized.brandName, {
brandName: normalized.brandName,
images: Array.from(imageMap.values()),
});
});
return {
entries: Array.from(entryMap.values())
.map((entry) => ({
...entry,
images: entry.images.slice().sort((left, right) => left.sortOrder - right.sortOrder),
}))
.sort((left, right) => left.brandName.localeCompare(right.brandName, "zh-CN")),
};
}