feat(canvas): 前端重构与渠道兼容 - 重构工作区、任务中心等多页面,修复智能体对话与节点生成

Co-authored-by: sikongyue <3155157671@qq.com>
Original-PR: https://github.com/ddcat-ai/open-ai-canvas/pull/217
This commit is contained in:
爱笑的毛毛虫
2026-08-14 12:01:21 +08:00
committed by GitHub
parent fb2a54b345
commit cfdf08d05f
37 changed files with 4599 additions and 912 deletions

View File

@@ -1,6 +1,6 @@
import { type GenerationTask } from "@/services/api/task-center";
import { backendProviderConfig, runBackendGenerationTask } from "@/services/api/generation-task";
import { configuredModelMatchesCapability, defaultConfig, resolveModelRequestConfig, type AiConfig } from "@/stores/use-config-store";
import { defaultConfig, modelMatchesCapability, modelOptionName, normalizeModelOptionValue, resolveModelRequestConfig, type AiConfig } from "@/stores/use-config-store";
import { resolveImageUrl, uploadImage } from "@/services/image-storage";
import { resolveMediaUrl } from "@/services/file-storage";
import { resourceIdFromStorageKey } from "@/services/api/resources";
@@ -287,8 +287,8 @@ export function getGenerationCount(count: string) {
export function buildGenerationConfig(config: AiConfig, node: CanvasNodeData | undefined, mode: CanvasNodeGenerationMode): AiConfig {
const defaultModel = mode === "image" ? config.imageModel : mode === "video" ? config.videoModel : mode === "audio" ? config.audioModel : config.textModel;
const fallbackModel = mode === "image" ? defaultConfig.imageModel : mode === "video" ? defaultConfig.videoModel : mode === "audio" ? defaultConfig.audioModel : defaultConfig.textModel;
const storedModel = node?.metadata?.model;
const model = storedModel && configuredModelMatchesCapability(config, storedModel, mode) ? storedModel : defaultModel && configuredModelMatchesCapability(config, defaultModel, mode) ? defaultModel : fallbackModel;
const storedModel = resolveCanvasGenerationModel(config, node?.metadata?.model, mode);
const model = storedModel || resolveCanvasGenerationModel(config, defaultModel, mode) || fallbackModel;
const imageProfile = mode === "image" ? modelCapabilityConfigFor(config, model).image! : undefined;
const normalizedImage = imageProfile ? normalizeImageValue(imageProfile, { quality: node?.metadata?.quality || config.quality || defaultConfig.quality, size: node?.metadata?.size || config.size || defaultConfig.size, transparentBackground: node?.metadata?.transparentBackground || config.transparentBackground, count: String(node?.metadata?.count || config.canvasImageCount || config.count || defaultConfig.count) }) : undefined;
return {
@@ -309,6 +309,13 @@ export function buildGenerationConfig(config: AiConfig, node: CanvasNodeData | u
};
}
export function resolveCanvasGenerationModel(config: AiConfig, model: string | undefined, mode: CanvasNodeGenerationMode): string {
if (!model) return "";
const normalized = normalizeModelOptionValue(model, config.channels);
if (!normalized) return "";
return modelMatchesCapability(modelOptionName(normalized), mode) ? normalized : "";
}
export function supportsVideoReferenceAudio(config: AiConfig) {
const interfaceType = resolveModelRequestConfig(config, config.model).interfaceType;
return interfaceType === "newapi-channel-1" || interfaceType === "newapi-channel-2" || isSeedanceVideoConfig(config);