Browse Source

修改生成节点默认模型逻辑

TEST-s
weige 2 months ago
parent
commit
791a66d172
  1. 9
      src/components/FloatingActionBar.tsx
  2. 13
      src/components/WorkflowCanvas.tsx
  3. 3
      src/lib/llmModels.ts
  4. 16
      src/store/utils/defaultImageModel.ts
  5. 4
      src/store/utils/nodeDefaults.ts
  6. 101
      src/utils/defaultGenerationNodeModel.ts

9
src/components/FloatingActionBar.tsx

@ -8,6 +8,7 @@ import { useReactFlow } from "@xyflow/react";
import { ModelSearchDialog } from "./modals/ModelSearchDialog";
import { useFTUXStore, TutorialStep } from "@/store/ftuxStore";
import { TranslationKey, useI18n } from "@/i18n";
import { buildDefaultGenerationNodeData } from "@/utils/defaultGenerationNodeModel";
// All nodes menu categories
const ALL_NODES_CATEGORIES: { labelKey: TranslationKey; nodes: { type: NodeType; labelKey: TranslationKey }[] }[] = [
@ -183,14 +184,14 @@ function GenerateComboButton() {
};
}, [isOpen]);
const handleAddNode = (type: NodeType) => {
const handleAddNode = async (type: NodeType) => {
const center = getPaneCenter();
const position = screenToFlowPosition({
x: center.x + Math.random() * 100 - 50,
y: center.y + Math.random() * 100 - 50,
});
addNode(type, position);
addNode(type, position, await buildDefaultGenerationNodeData(type));
setIsOpen(false);
};
@ -303,14 +304,14 @@ function AllNodesMenu() {
};
}, [isOpen]);
const handleAddNode = useCallback((type: NodeType) => {
const handleAddNode = useCallback(async (type: NodeType) => {
const center = getPaneCenter();
const position = screenToFlowPosition({
x: center.x + Math.random() * 100 - 50,
y: center.y + Math.random() * 100 - 50,
});
addNode(type, position);
addNode(type, position, await buildDefaultGenerationNodeData(type));
setIsOpen(false);
}, [addNode, screenToFlowPosition]);

13
src/components/WorkflowCanvas.tsx

@ -99,6 +99,7 @@ import { TutorialOverlay } from "./onboarding/TutorialOverlay";
import { useFTUXStore } from "@/store/ftuxStore";
import { useI18n } from "@/i18n";
import { isPopiProviderMode } from "@/lib/providerMode";
import { buildDefaultGenerationNodeData } from "@/utils/defaultGenerationNodeModel";
const nodeTypes: NodeTypes = {
imageInput: ImageInputNode,
@ -2040,7 +2041,13 @@ export function WorkflowCanvas() {
glbViewer: { width: 360, height: 380 },
};
const dims = defaultDimensions[nodeType];
addNode(nodeType, { x: centerX - dims.width / 2, y: centerY - dims.height / 2 });
void (async () => {
addNode(
nodeType,
{ x: centerX - dims.width / 2, y: centerY - dims.height / 2 },
await buildDefaultGenerationNodeData(nodeType)
);
})();
return;
}
}
@ -2321,7 +2328,7 @@ export function WorkflowCanvas() {
}, []);
const handleDrop = useCallback(
(event: DragEvent<HTMLDivElement>) => {
async (event: DragEvent<HTMLDivElement>) => {
event.preventDefault();
setIsDragOver(false);
setDropType(null);
@ -2333,7 +2340,7 @@ export function WorkflowCanvas() {
x: event.clientX,
y: event.clientY,
});
addNode(nodeType, position);
addNode(nodeType, position, await buildDefaultGenerationNodeData(nodeType));
return;
}

3
src/lib/llmModels.ts

@ -1,5 +1,6 @@
import type { LLMModelType, LLMProvider } from "@/types";
import { getProviderDisplayName, isPopiProviderMode } from "@/lib/providerMode";
import { POPISERVER_DEFAULT_LLM_MODEL_ID } from "@/store/utils/defaultImageModel";
export interface LLMModelOption {
value: LLMModelType;
@ -7,7 +8,7 @@ export interface LLMModelOption {
}
export const DEFAULT_NEWAPIWG_LLM_MODEL_ID: LLMModelType = "doubao-seed-2-0-lite-260428";
export const DEFAULT_POPISERVER_LLM_MODEL_ID: LLMModelType = "kimi-k2.6";
export const DEFAULT_POPISERVER_LLM_MODEL_ID: LLMModelType = POPISERVER_DEFAULT_LLM_MODEL_ID;
const ALL_LLM_PROVIDERS: { value: LLMProvider; label: string }[] = [
{ value: "popiserver", label: getProviderDisplayName("popiserver") },

16
src/store/utils/defaultImageModel.ts

@ -7,12 +7,16 @@ const NEWAPIWG_DEFAULT_IMAGE_FALLBACK_MODEL_ID = "apiyi_nano_banana_2";
const NEWAPIWG_LEGACY_DEFAULT_IMAGE_MODEL_ID = "apiyi_nano_banana_2";
const NEWAPIWG_DEFAULT_VIDEO_MODEL_ID = "viduq3-turbo";
const DEFAULT_AUDIO_MODEL_ID = "elevenlabs/turbo-v2.5";
export const POPISERVER_DEFAULT_IMAGE_MODEL_ID = "gpt-image-2-all";
export const POPISERVER_DEFAULT_VIDEO_MODEL_ID = "viduq3-turbo";
export const POPISERVER_DEFAULT_AUDIO_MODEL_ID = "speech-2.8-hd";
export const POPISERVER_DEFAULT_LLM_MODEL_ID = "kimi-k2.6";
export function createPopiserverDefaultImageModel(): SelectedModel {
return {
provider: POPI_PROVIDER_ID,
modelId: "",
displayName: "Select model",
modelId: POPISERVER_DEFAULT_IMAGE_MODEL_ID,
displayName: POPISERVER_DEFAULT_IMAGE_MODEL_ID,
capabilities: ["text-to-image", "image-to-image"],
};
}
@ -20,8 +24,8 @@ export function createPopiserverDefaultImageModel(): SelectedModel {
export function createPopiserverDefaultVideoModel(): SelectedModel {
return {
provider: POPI_PROVIDER_ID,
modelId: "",
displayName: "Select model",
modelId: POPISERVER_DEFAULT_VIDEO_MODEL_ID,
displayName: POPISERVER_DEFAULT_VIDEO_MODEL_ID,
capabilities: ["text-to-video", "image-to-video"],
};
}
@ -29,8 +33,8 @@ export function createPopiserverDefaultVideoModel(): SelectedModel {
export function createPopiserverDefaultAudioModel(): SelectedModel {
return {
provider: POPI_PROVIDER_ID,
modelId: "",
displayName: "Select model",
modelId: POPISERVER_DEFAULT_AUDIO_MODEL_ID,
displayName: POPISERVER_DEFAULT_AUDIO_MODEL_ID,
capabilities: ["text-to-audio"],
};
}

4
src/store/utils/nodeDefaults.ts

@ -28,7 +28,7 @@ import {
SelectedModel,
} from "@/types";
import { loadGenerateImageDefaults, loadNodeDefaults } from "./localStorage";
import { DEFAULT_NEWAPIWG_LLM_MODEL_ID } from "@/lib/llmModels";
import { DEFAULT_NEWAPIWG_LLM_MODEL_ID, DEFAULT_POPISERVER_LLM_MODEL_ID } from "@/lib/llmModels";
import {
createDefaultAudioModel,
createNewApiWGDefaultImageModel,
@ -246,7 +246,7 @@ export const createDefaultNodeData = (type: NodeType): WorkflowNodeData => {
inputVideos: [],
outputText: null,
provider: llmDefaults?.provider ?? (isPopiProviderMode() ? "popiserver" : "newapiwg"),
model: llmDefaults?.model ?? DEFAULT_NEWAPIWG_LLM_MODEL_ID,
model: llmDefaults?.model ?? (isPopiProviderMode() ? DEFAULT_POPISERVER_LLM_MODEL_ID : DEFAULT_NEWAPIWG_LLM_MODEL_ID),
temperature: llmDefaults?.temperature ?? 0.7,
maxTokens: llmDefaults?.maxTokens ?? 8192,
status: "idle",

101
src/utils/defaultGenerationNodeModel.ts

@ -0,0 +1,101 @@
import type { LLMModelType, NodeType, SelectedModel, WorkflowNodeData } from "@/types";
import type { ProviderModel } from "@/lib/providers/types";
import { isPopiProviderMode, POPI_PROVIDER_ID } from "@/lib/providerMode";
import { useModelStore, type PopiModelKind } from "@/store/modelStore";
import { loadNodeDefaults } from "@/store/utils/localStorage";
import {
POPISERVER_DEFAULT_AUDIO_MODEL_ID,
POPISERVER_DEFAULT_IMAGE_MODEL_ID,
POPISERVER_DEFAULT_LLM_MODEL_ID,
POPISERVER_DEFAULT_VIDEO_MODEL_ID,
} from "@/store/utils/defaultImageModel";
type GenerationNodeType = "nanoBanana" | "generateVideo" | "generateAudio" | "llmGenerate";
function getKindForNodeType(type: NodeType): PopiModelKind | null {
if (type === "nanoBanana") return "image";
if (type === "generateVideo") return "video";
if (type === "generateAudio") return "audio";
if (type === "llmGenerate") return "llm";
return null;
}
function getConfiguredPopiModelId(type: GenerationNodeType): string | null {
const defaults = loadNodeDefaults();
if (type === "nanoBanana") {
const model = defaults.generateImage?.selectedModel;
return model?.provider === POPI_PROVIDER_ID && model.modelId ? model.modelId : null;
}
if (type === "generateVideo") {
const model = defaults.generateVideo?.selectedModel;
return model?.provider === POPI_PROVIDER_ID && model.modelId ? model.modelId : null;
}
if (type === "generateAudio") {
const model = defaults.generateAudio?.selectedModel;
return model?.provider === POPI_PROVIDER_ID && model.modelId ? model.modelId : null;
}
const llm = defaults.llm;
return llm?.provider === POPI_PROVIDER_ID && llm.model ? llm.model : null;
}
function getCodeDefaultPopiModelId(type: GenerationNodeType): string {
if (type === "nanoBanana") return POPISERVER_DEFAULT_IMAGE_MODEL_ID;
if (type === "generateVideo") return POPISERVER_DEFAULT_VIDEO_MODEL_ID;
if (type === "generateAudio") return POPISERVER_DEFAULT_AUDIO_MODEL_ID;
return POPISERVER_DEFAULT_LLM_MODEL_ID;
}
function matchesConfiguredModel(model: ProviderModel, configuredModelId: string): boolean {
return (
model.id === configuredModelId ||
String(model.metadata?.aiModelId ?? "") === configuredModelId ||
String(model.metadata?.aiModelCode ?? "") === configuredModelId ||
String(model.metadata?.aiModelCodeAlias ?? "") === configuredModelId
);
}
function providerModelToSelectedModel(model: ProviderModel): SelectedModel {
return {
provider: model.provider,
modelId: model.id,
displayName: model.name,
capabilities: model.capabilities,
metadata: model.metadata,
pricing: model.pricing
? {
type: model.pricing.type,
amount: model.pricing.amount,
variants: model.pricing.variants,
}
: undefined,
};
}
export async function buildDefaultGenerationNodeData(
type: NodeType
): Promise<Partial<WorkflowNodeData> | undefined> {
if (!isPopiProviderMode()) return undefined;
const kind = getKindForNodeType(type);
if (!kind || kind === "3d") return undefined;
const generationType = type as GenerationNodeType;
await useModelStore.getState().initializePopiModels();
const models = useModelStore.getState().byKind[kind];
if (models.length === 0) return undefined;
const preferredModelId = getConfiguredPopiModelId(generationType) ?? getCodeDefaultPopiModelId(generationType);
const model = models.find((item) => matchesConfiguredModel(item, preferredModelId)) ?? models[0];
const selectedModel = providerModelToSelectedModel(model);
if (generationType === "llmGenerate") {
return {
provider: POPI_PROVIDER_ID,
model: selectedModel.modelId as LLMModelType,
selectedModel,
} as Partial<WorkflowNodeData>;
}
return { selectedModel } as Partial<WorkflowNodeData>;
}
Loading…
Cancel
Save