mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-04 16:14:22 +08:00
feat: transition to a fully frontend architecture by removing backend dependencies and updating configuration for local deployment
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import axios from "axios";
|
||||
|
||||
import { buildApiUrl, type AiConfig } from "@/stores/use-config-store";
|
||||
import { buildApiUrl, resolveModelRequestConfig, type AiConfig, type ModelChannel } from "@/stores/use-config-store";
|
||||
import { nanoid } from "nanoid";
|
||||
import { dataUrlToFile } from "@/lib/image-utils";
|
||||
import { buildImageReferencePromptText } from "@/lib/image-reference-prompt";
|
||||
@@ -184,15 +184,16 @@ function withSystemMessage(config: AiConfig, messages: ChatCompletionMessage[])
|
||||
}
|
||||
|
||||
export async function requestGeneration(config: AiConfig, prompt: string) {
|
||||
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 quality = normalizeQuality(config.quality);
|
||||
const requestSize = resolveRequestSize(quality, config.size);
|
||||
try {
|
||||
const response = await axios.post<ImageApiResponse>(
|
||||
aiApiUrl(config, "/images/generations"),
|
||||
aiApiUrl(requestConfig, "/images/generations"),
|
||||
{
|
||||
model: config.model,
|
||||
prompt: withSystemPrompt(config, prompt),
|
||||
model: requestConfig.model,
|
||||
prompt: withSystemPrompt(requestConfig, prompt),
|
||||
n,
|
||||
...(quality ? { quality } : {}),
|
||||
...(requestSize ? { size: requestSize } : {}),
|
||||
@@ -200,7 +201,7 @@ export async function requestGeneration(config: AiConfig, prompt: string) {
|
||||
output_format: IMAGE_OUTPUT_FORMAT,
|
||||
},
|
||||
{
|
||||
headers: aiHeaders(config, "application/json"),
|
||||
headers: aiHeaders(requestConfig, "application/json"),
|
||||
},
|
||||
);
|
||||
const images = parseImagePayload(response.data);
|
||||
@@ -211,13 +212,14 @@ export async function requestGeneration(config: AiConfig, prompt: string) {
|
||||
}
|
||||
|
||||
export async function requestEdit(config: AiConfig, prompt: string, references: ReferenceImage[], mask?: ReferenceImage) {
|
||||
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 quality = normalizeQuality(config.quality);
|
||||
const requestSize = resolveRequestSize(quality, config.size);
|
||||
const requestPrompt = buildImageReferencePromptText(prompt, references);
|
||||
const formData = new FormData();
|
||||
formData.set("model", config.model);
|
||||
formData.set("prompt", withSystemPrompt(config, requestPrompt));
|
||||
formData.set("model", requestConfig.model);
|
||||
formData.set("prompt", withSystemPrompt(requestConfig, requestPrompt));
|
||||
formData.set("n", String(n));
|
||||
formData.set("response_format", "b64_json");
|
||||
formData.set("output_format", IMAGE_OUTPUT_FORMAT);
|
||||
@@ -232,7 +234,7 @@ export async function requestEdit(config: AiConfig, prompt: string, references:
|
||||
if (mask) formData.set("mask", dataUrlToFile(mask));
|
||||
|
||||
try {
|
||||
const response = await axios.post<ImageApiResponse>(aiApiUrl(config, "/images/edits"), formData, { headers: aiHeaders(config) });
|
||||
const response = await axios.post<ImageApiResponse>(aiApiUrl(requestConfig, "/images/edits"), formData, { headers: aiHeaders(requestConfig) });
|
||||
const images = parseImagePayload(response.data);
|
||||
return images;
|
||||
} catch (error) {
|
||||
@@ -241,21 +243,22 @@ export async function requestEdit(config: AiConfig, prompt: string, references:
|
||||
}
|
||||
|
||||
export async function requestImageQuestion(config: AiConfig, messages: ChatCompletionMessage[], onDelta: (text: string) => void) {
|
||||
const requestConfig = resolveModelRequestConfig(config, config.model || config.textModel);
|
||||
let buffer = "";
|
||||
let answer = "";
|
||||
let processedLength = 0;
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
aiApiUrl(config, "/chat/completions"),
|
||||
aiApiUrl(requestConfig, "/chat/completions"),
|
||||
{
|
||||
model: config.model,
|
||||
messages: withSystemMessage(config, messages),
|
||||
model: requestConfig.model,
|
||||
messages: withSystemMessage(requestConfig, messages),
|
||||
stream: true,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
...aiHeaders(config, "application/json"),
|
||||
...aiHeaders(requestConfig, "application/json"),
|
||||
} as Record<string, string>,
|
||||
responseType: "text",
|
||||
onDownloadProgress: (event) => {
|
||||
@@ -301,7 +304,7 @@ export async function requestImageQuestion(config: AiConfig, messages: ChatCompl
|
||||
return answer || "没有返回内容";
|
||||
}
|
||||
|
||||
export async function fetchImageModels(config: AiConfig) {
|
||||
export async function fetchImageModels(config: Pick<AiConfig, "baseUrl" | "apiKey">) {
|
||||
try {
|
||||
const response = await axios.get<{ data?: Array<{ id?: string }>; error?: { message?: string } }>(buildApiUrl(config.baseUrl, "/models"), {
|
||||
headers: {
|
||||
@@ -316,3 +319,7 @@ export async function fetchImageModels(config: AiConfig) {
|
||||
throw new Error(readAxiosError(error, "读取模型失败"));
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchChannelModels(channel: ModelChannel) {
|
||||
return fetchImageModels({ baseUrl: channel.baseUrl, apiKey: channel.apiKey });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user