diff --git a/CHANGELOG.md b/CHANGELOG.md index a0fe938..1e22814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased ++ [新增] 渠道兼容Gemini格式。 + ## v0.4.0 - 2026-06-16 + [新增] 新增网页版Agent Loop模式。 diff --git a/docs/content/docs/progress/pending-test.mdx b/docs/content/docs/progress/pending-test.mdx index 38daa60..b992dfe 100644 --- a/docs/content/docs/progress/pending-test.mdx +++ b/docs/content/docs/progress/pending-test.mdx @@ -5,3 +5,6 @@ description: 当前版本已实现但仍需人工验证的变更项 # 待测试 +- 配置与用户偏好:每个模型渠道新增 OpenAI / Gemini 调用格式选择,默认 OpenAI,切换默认格式时同步更新默认 Base URL;渠道 Tab 增加紧凑醒目的提醒,说明模型是否可选需要到“模型”Tab 选择。 +- Gemini 调用格式:支持拉取 Gemini 模型列表,并用于文本问答、在线 Agent 工具调用、基础生图和图生图请求。 +- 音频和视频生成:选择 Gemini 调用格式时先给出不支持提示,仍需使用 OpenAI 兼容渠道。 diff --git a/web/src/app/(user)/canvas/components/canvas-assistant-panel.tsx b/web/src/app/(user)/canvas/components/canvas-assistant-panel.tsx index 1485f8e..ea929c6 100644 --- a/web/src/app/(user)/canvas/components/canvas-assistant-panel.tsx +++ b/web/src/app/(user)/canvas/components/canvas-assistant-panel.tsx @@ -1056,7 +1056,7 @@ function isResponseToolCall(value: unknown): value is ResponseToolCall { } function toolCallToResponseInput(call: ResponseToolCall): ResponseInputMessage { - return { type: "function_call", call_id: call.id, name: call.function.name, arguments: call.function.arguments }; + return { type: "function_call", call_id: call.id, name: call.function.name, arguments: call.function.arguments, ...(call.thoughtSignature ? { thoughtSignature: call.thoughtSignature } : {}) }; } function summarizeToolCalls(calls: ResponseToolCall[]) { diff --git a/web/src/components/layout/app-config-modal.tsx b/web/src/components/layout/app-config-modal.tsx index 4af65e0..ea41f55 100644 --- a/web/src/components/layout/app-config-modal.tsx +++ b/web/src/components/layout/app-config-modal.tsx @@ -1,7 +1,7 @@ "use client"; import { App, Button, Form, Input, Modal, Progress, Segmented, Select, Tabs } from "antd"; -import { Cloud, Plus, RefreshCw, Trash2, Wifi } from "lucide-react"; +import { CircleAlert, Cloud, Plus, RefreshCw, Trash2, Wifi } from "lucide-react"; import { useState } from "react"; import { ModelPicker } from "@/components/model-picker"; @@ -9,7 +9,7 @@ import { fetchChannelModels } from "@/services/api/image"; import { syncAppDataToWebdav, type AppSyncDomainKey, type AppSyncProgressEvent } from "@/services/app-sync"; import { testWebdavConnection, WEBDAV_MANIFEST_FILE_NAME } from "@/services/webdav-sync"; import { audioFormatOptions, audioVoiceOptions, normalizeAudioSpeedValue } from "@/lib/audio-generation"; -import { createModelChannel, filterModelsByCapability, modelOptionLabel, modelOptionsFromChannels, normalizeModelOptionValue, useConfigStore, type AiConfig, type ModelCapability, type ModelChannel } from "@/stores/use-config-store"; +import { createModelChannel, defaultBaseUrlForApiFormat, filterModelsByCapability, modelOptionLabel, modelOptionsFromChannels, normalizeModelOptionValue, useConfigStore, type AiConfig, type ApiCallFormat, type ModelCapability, type ModelChannel } from "@/stores/use-config-store"; type ModelGroup = { capability: ModelCapability; @@ -34,6 +34,11 @@ const modelGroups: ModelGroup[] = [ { capability: "audio", modelKey: "audioModel", modelsKey: "audioModels", defaultLabel: "默认音频模型", optionsLabel: "音频模型可选项" }, ]; +const apiFormatOptions: Array<{ label: string; value: ApiCallFormat }> = [ + { label: "OpenAI", value: "openai" }, + { label: "Gemini", value: "gemini" }, +]; + const webdavDomainKeys: AppSyncDomainKey[] = ["canvas", "assets", "image-workbench", "video-workbench"]; const webdavDomainLabels: Record = { canvas: "画布", @@ -92,6 +97,11 @@ export function AppConfigModal() { updateChannels(config.channels.map((channel) => (channel.id === id ? { ...channel, ...patch, models: patch.models ? uniqueModels(patch.models) : channel.models } : channel))); }; + const updateChannelApiFormat = (channel: ModelChannel, apiFormat: ApiCallFormat) => { + const baseUrl = !channel.baseUrl.trim() || channel.baseUrl.trim() === defaultBaseUrlForApiFormat(channel.apiFormat) ? defaultBaseUrlForApiFormat(apiFormat) : channel.baseUrl; + updateChannel(channel.id, { apiFormat, baseUrl }); + }; + const addChannel = () => { updateChannels([...config.channels, createModelChannel({ name: `渠道 ${config.channels.length + 1}` })]); }; @@ -226,11 +236,17 @@ export function AppConfigModal() { children: (
-
-
多渠道聚合
-
每个渠道保存自己的 Base URL、API Key 和模型列表;模型选择时会显示模型名和渠道名。
+
+
+ + 重要: + 新增或拉取模型后,需要到“模型”Tab 选择可选项才会显示。 + +
-
+
@@ -245,7 +261,9 @@ export function AppConfigModal() {
{channel.name || "未命名渠道"}
-
已保存 {channel.models.length} 个模型
+
+ {apiFormatLabel(channel.apiFormat)} · 已保存 {channel.models.length} 个模型 +