feat(model): enhance model configuration and script handling for audio and video capabilities

This commit is contained in:
HouYunFei
2026-07-15 10:13:32 +08:00
parent a4dcc679c9
commit c57f7d61a7
13 changed files with 690 additions and 266 deletions
+65 -1
View File
@@ -1,6 +1,7 @@
import axios from "axios";
import { buildApiUrl, resolveModelRequestConfig, type AiConfig, type ModelChannel } from "@/stores/use-config-store";
import { buildApiUrl, resolveModelRequestConfig, resolveModelScript, type AiConfig, type ModelChannel } from "@/stores/use-config-store";
import { normalizePluginImages, runModelPlugin } from "./model-plugin";
import { nanoid } from "nanoid";
import { dataUrlToFile } from "@/lib/image-utils";
import { buildImageReferencePromptText } from "@/lib/image-reference-prompt";
@@ -656,6 +657,28 @@ function parseGeminiImagePayload(payload: GeminiPayload) {
export async function requestGeneration(config: AiConfig, prompt: string, options?: RequestOptions) {
const requestConfig = resolveModelRequestConfig(config, config.model || config.imageModel);
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
const script = resolveModelScript(config, config.model || config.imageModel);
if (script) {
const quality = normalizeQuality(config.quality);
const requestSize = resolveRequestSize(quality, config.size);
try {
const result = await runModelPlugin({
capability: "image",
script,
config: requestConfig,
input: {
prompt: withSystemPrompt(requestConfig, prompt),
references: [],
params: { size: requestSize, quality, count: n },
body: { model: requestConfig.model, n, ...(quality ? { quality } : {}), ...(requestSize ? { size: requestSize } : {}), response_format: "b64_json", output_format: IMAGE_OUTPUT_FORMAT },
},
signal: options?.signal,
});
return normalizePluginImages(result).map((dataUrl) => ({ id: nanoid(), dataUrl }));
} catch (error) {
throw new Error(readAxiosError(error, "请求失败"));
}
}
if (requestConfig.apiFormat === "gemini") {
try {
return await requestGeminiImages(requestConfig, prompt, [], n, options);
@@ -693,6 +716,29 @@ export async function requestEdit(config: AiConfig, prompt: string, references:
const requestConfig = resolveModelRequestConfig(config, config.model || config.imageModel);
const n = Math.max(1, Math.min(15, Math.floor(Math.abs(Number(config.count)) || 1)));
const requestPrompt = buildImageReferencePromptText(prompt, references);
const script = resolveModelScript(config, config.model || config.imageModel);
if (script) {
const quality = normalizeQuality(config.quality);
const requestSize = resolveRequestSize(quality, config.size);
const refs = await Promise.all(references.map((image) => imageToDataUrl(image)));
try {
const result = await runModelPlugin({
capability: "image",
script,
config: requestConfig,
input: {
prompt: withSystemPrompt(requestConfig, requestPrompt),
references: refs,
params: { size: requestSize, quality, count: n },
body: { model: requestConfig.model, n, ...(quality ? { quality } : {}), ...(requestSize ? { size: requestSize } : {}), response_format: "b64_json", output_format: IMAGE_OUTPUT_FORMAT },
},
signal: options?.signal,
});
return normalizePluginImages(result).map((dataUrl) => ({ id: nanoid(), dataUrl }));
} catch (error) {
throw new Error(readAxiosError(error, "请求失败"));
}
}
if (requestConfig.apiFormat === "gemini") {
if (mask) throw new Error("Gemini 调用格式暂不支持蒙版编辑");
try {
@@ -730,6 +776,24 @@ export async function requestEdit(config: AiConfig, prompt: string, references:
export async function requestImageQuestion(config: AiConfig, messages: AiTextMessage[], onDelta: (text: string) => void, options?: RequestOptions) {
const requestConfig = resolveModelRequestConfig(config, config.model || config.textModel);
const script = resolveModelScript(config, config.model || config.textModel);
if (script) {
try {
const answer = await runModelPlugin<string>({
capability: "text",
script,
config: requestConfig,
input: { messages: withSystemMessage(requestConfig, messages), body: { model: requestConfig.model } },
signal: options?.signal,
onDelta,
});
const text = String(answer ?? "").trim() || "没有返回内容";
if (text === "没有返回内容") onDelta(text);
return text;
} catch (error) {
throw new Error(readAxiosError(error, "请求失败"));
}
}
try {
if (requestConfig.apiFormat === "gemini") {
const answer = (await requestGeminiStreamingResponse(requestConfig, toGeminiBody(requestConfig, messages), onDelta, options)).content || "没有返回内容";