From 137d906ef080913d12f4c531c97662eff2529189 Mon Sep 17 00:00:00 2001
From: zhengkunwang223 <1paneldev@sina.com>
Date: Thu, 25 Jun 2026 17:24:23 +0800
Subject: [PATCH] fix: Fixed issue with openclaw config telegram failed
---
agent/app/service/agents_channels.go | 33 ++++++--
agent/app/service/vllm_upgrade.go | 19 ++++-
frontend/src/lang/modules/en.ts | 5 ++
frontend/src/lang/modules/es-es.ts | 6 ++
frontend/src/lang/modules/ja.ts | 4 +
frontend/src/lang/modules/ko.ts | 4 +
frontend/src/lang/modules/ms.ts | 5 ++
frontend/src/lang/modules/pt-br.ts | 6 ++
frontend/src/lang/modules/ru.ts | 5 ++
frontend/src/lang/modules/tr.ts | 6 ++
frontend/src/lang/modules/zh-Hant.ts | 4 +
frontend/src/lang/modules/zh.ts | 4 +
.../src/views/ai/agents/model/add/index.vue | 77 +++++++++++++++++++
13 files changed, 169 insertions(+), 9 deletions(-)
diff --git a/agent/app/service/agents_channels.go b/agent/app/service/agents_channels.go
index 7ee0b82d51d3..60077441844a 100644
--- a/agent/app/service/agents_channels.go
+++ b/agent/app/service/agents_channels.go
@@ -811,9 +811,7 @@ func extractTelegramConfig(conf map[string]interface{}) dto.AgentTelegramConfig
result.RequireMention = result.GroupPolicy == "allowlist"
result.GroupAllowFrom = extractStringList(telegram["groupAllowFrom"])
result.Proxy = extractStringValue(telegram["proxy"])
- if streaming := extractStringValue(telegram["streaming"]); streaming != "" {
- result.Streaming = streaming
- }
+ result.Streaming = normalizeTelegramStreamingMode(telegram["streaming"], result.Streaming)
accounts := childMap(telegram, "accounts")
if len(accounts) == 0 {
botToken := extractStringValue(telegram["botToken"])
@@ -839,7 +837,7 @@ func extractTelegramConfig(conf map[string]interface{}) dto.AgentTelegramConfig
BotToken: extractStringValue(account["botToken"]),
DmPolicy: extractStringValue(account["dmPolicy"]),
GroupPolicy: extractStringValue(account["groupPolicy"]),
- Streaming: extractStringValue(account["streaming"]),
+ Streaming: normalizeTelegramStreamingMode(account["streaming"], result.Streaming),
})
}
result.DefaultAccount = normalizeDefaultAccount(extractStringValue(telegram["defaultAccount"]), getTelegramBotAccountIDs(bots))
@@ -879,7 +877,7 @@ func setTelegramConfig(conf map[string]interface{}, config dto.AgentTelegramConf
} else {
delete(telegram, "proxy")
}
- telegram["streaming"] = config.Streaming
+ telegram["streaming"] = buildTelegramStreamingConfig(config.Streaming)
accounts := make(map[string]interface{}, len(config.Bots))
for _, bot := range config.Bots {
account := map[string]interface{}{
@@ -888,7 +886,7 @@ func setTelegramConfig(conf map[string]interface{}, config dto.AgentTelegramConf
"botToken": bot.BotToken,
"dmPolicy": bot.DmPolicy,
"groupPolicy": bot.GroupPolicy,
- "streaming": bot.Streaming,
+ "streaming": buildTelegramStreamingConfig(bot.Streaming),
}
if bot.DmPolicy == "open" {
account["allowFrom"] = []string{"*"}
@@ -899,6 +897,29 @@ func setTelegramConfig(conf map[string]interface{}, config dto.AgentTelegramConf
delete(telegram, "botToken")
}
+func normalizeTelegramStreamingMode(value interface{}, defaultMode string) string {
+ mode := defaultMode
+ switch typed := value.(type) {
+ case string:
+ mode = typed
+ case map[string]interface{}:
+ mode = extractStringValue(typed["mode"])
+ }
+ mode = strings.ToLower(strings.TrimSpace(mode))
+ switch mode {
+ case "off", "partial", "block", "progress":
+ return mode
+ default:
+ return "partial"
+ }
+}
+
+func buildTelegramStreamingConfig(mode string) map[string]interface{} {
+ return map[string]interface{}{
+ "mode": normalizeTelegramStreamingMode(mode, "partial"),
+ }
+}
+
func extractDiscordConfig(conf map[string]interface{}) dto.AgentDiscordConfig {
result := dto.AgentDiscordConfig{Enabled: true, DmPolicy: "pairing", AllowFrom: []string{}, RequireMention: false, GroupPolicy: "open"}
discord := getChannelConfig(conf, "discord")
diff --git a/agent/app/service/vllm_upgrade.go b/agent/app/service/vllm_upgrade.go
index dd25a8c97fad..b13775af90ac 100644
--- a/agent/app/service/vllm_upgrade.go
+++ b/agent/app/service/vllm_upgrade.go
@@ -12,6 +12,7 @@ const (
vllmImageEnvKey = "IMAGE"
vllmImageTypeNvidia = "nvidia"
vllmImageTypeIntel = "intel"
+ vllmImageTypeAscend = "ascend"
)
func resolveVllmVersionFamily(version, image string) string {
@@ -19,6 +20,9 @@ func resolveVllmVersionFamily(version, image string) string {
if strings.HasPrefix(normalizedVersion, vllmImageTypeIntel+"-") {
return vllmImageTypeIntel
}
+ if strings.HasPrefix(normalizedVersion, vllmImageTypeAscend+"-") {
+ return vllmImageTypeAscend
+ }
if strings.HasPrefix(normalizedVersion, vllmImageTypeNvidia+"-") {
return vllmImageTypeNvidia
}
@@ -26,13 +30,16 @@ func resolveVllmVersionFamily(version, image string) string {
if strings.Contains(normalizedImage, "intel/") || strings.Contains(normalizedImage, "llm-scaler-vllm") {
return vllmImageTypeIntel
}
+ if strings.Contains(normalizedImage, "ascend/") || strings.Contains(normalizedImage, "vllm-ascend") {
+ return vllmImageTypeAscend
+ }
return vllmImageTypeNvidia
}
func trimVllmVersionFamily(version string) string {
trimmed := strings.TrimSpace(version)
normalized := strings.ToLower(trimmed)
- for _, family := range []string{vllmImageTypeNvidia, vllmImageTypeIntel} {
+ for _, family := range []string{vllmImageTypeNvidia, vllmImageTypeIntel, vllmImageTypeAscend} {
prefix := family + "-"
if strings.HasPrefix(normalized, prefix) {
return strings.TrimSpace(trimmed[len(prefix):])
@@ -43,12 +50,16 @@ func trimVllmVersionFamily(version string) string {
func buildDefaultVllmImageByVersion(version string) string {
tag := trimVllmVersionFamily(version)
- if resolveVllmVersionFamily(version, "") == vllmImageTypeIntel {
+ family := resolveVllmVersionFamily(version, "")
+ if family == vllmImageTypeIntel {
return "intel/llm-scaler-vllm:" + tag
}
if tag != "" && !strings.HasPrefix(strings.ToLower(tag), "v") {
tag = "v" + tag
}
+ if family == vllmImageTypeAscend {
+ return "quay.io/ascend/vllm-ascend:" + tag
+ }
return "vllm/vllm-openai:" + tag
}
@@ -60,7 +71,9 @@ func isVllmUpgradeVersionAllowed(currentVersion, targetVersion, currentImage str
func hasVllmVersionFamilyPrefix(version string) bool {
normalized := strings.ToLower(strings.TrimSpace(version))
- return strings.HasPrefix(normalized, vllmImageTypeNvidia+"-") || strings.HasPrefix(normalized, vllmImageTypeIntel+"-")
+ return strings.HasPrefix(normalized, vllmImageTypeNvidia+"-") ||
+ strings.HasPrefix(normalized, vllmImageTypeIntel+"-") ||
+ strings.HasPrefix(normalized, vllmImageTypeAscend+"-")
}
func isVllmUpgradeCandidate(currentVersion, targetVersion, currentImage string) bool {
diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index ba872c111f8d..077fe44fa488 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -855,6 +855,9 @@ const message = {
channelAutoRestartHelper: 'Saving will automatically restart the container so the changes take effect.',
channelDeleteConfirm: 'Delete the {0} channel configuration?',
customProviderHelper: 'Custom model providers do not validate whether the account is available.',
+ apiTypeBaseURLHelper: 'This type sends requests to {0}. Recommended Base URL: {1}',
+ apiTypeBaseURLMismatch:
+ 'The current Base URL looks like a {0} path, but {1} is selected. Recommended URL: {2}',
},
model: {
model: 'Models',
@@ -1025,6 +1028,8 @@ const message = {
healthUnknown: 'Unknown',
validationModelMapEmpty: 'Model mapping names cannot be empty',
validationModelMapDuplicate: 'Request model {0} is duplicated',
+ validateAvailability: 'Validate Account Availability',
+ validateAvailabilityHelper: 'Send a minimal message before saving to validate API availability',
modelGroup: 'Model Group',
availableModels: 'Available Models',
modelGroupModels: 'Request Models',
diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts
index fee362cff76b..82b25f62067c 100644
--- a/frontend/src/lang/modules/es-es.ts
+++ b/frontend/src/lang/modules/es-es.ts
@@ -866,6 +866,9 @@ const message = {
'Al guardar, el contenedor se reiniciará automáticamente para que la configuración surta efecto.',
channelDeleteConfirm: '¿Eliminar la configuración del canal {0}?',
customProviderHelper: 'En el proveedor de modelo personalizado no se valida si la cuenta está disponible',
+ apiTypeBaseURLHelper: 'Este tipo envía solicitudes a {0}. Base URL recomendada: {1}',
+ apiTypeBaseURLMismatch:
+ 'La Base URL actual parece una ruta {0}, pero está seleccionado {1}. URL recomendada: {2}',
},
model: {
model: 'Modelo',
@@ -1040,6 +1043,9 @@ const message = {
healthUnknown: 'Desconocido',
validationModelMapEmpty: 'Los nombres del mapeo de modelos no pueden estar vacíos',
validationModelMapDuplicate: 'El modelo solicitado {0} está duplicado',
+ validateAvailability: 'Validar disponibilidad de la cuenta',
+ validateAvailabilityHelper:
+ 'Enviar un mensaje mínimo antes de guardar para validar la disponibilidad de la API',
modelGroup: 'Grupo de modelos',
availableModels: 'Modelos disponibles',
modelGroupModels: 'Modelos solicitados',
diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts
index 0a735fb8c3ef..5c82210ee339 100644
--- a/frontend/src/lang/modules/ja.ts
+++ b/frontend/src/lang/modules/ja.ts
@@ -858,6 +858,8 @@ const message = {
channelAutoRestartHelper: '保存後、設定を反映するためにコンテナが自動で再起動されます。',
channelDeleteConfirm: '{0} チャンネルの設定を削除しますか?',
customProviderHelper: 'カスタムモデルプロバイダーでは、アカウントの有効性を検証しません',
+ apiTypeBaseURLHelper: 'このタイプは最終的に {0} にリクエストします。推奨 Base URL: {1}',
+ apiTypeBaseURLMismatch: '現在の Base URL は {0} のパスに見えますが、{1} が選択されています。推奨 URL: {2}',
},
model: {
model: 'モデル',
@@ -1030,6 +1032,8 @@ const message = {
healthUnknown: '不明',
validationModelMapEmpty: 'モデルマッピングのモデル名は空にできません',
validationModelMapDuplicate: 'リクエストモデル {0} が重複しています',
+ validateAvailability: 'アカウントの可用性を検証',
+ validateAvailabilityHelper: '保存前に最小メッセージを送信して API の可用性を検証します',
modelGroup: 'モデルグループ',
availableModels: '利用可能なモデル',
modelGroupModels: 'リクエストモデル',
diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts
index caa955bdfa3c..d5afa793906b 100644
--- a/frontend/src/lang/modules/ko.ts
+++ b/frontend/src/lang/modules/ko.ts
@@ -843,6 +843,8 @@ const message = {
channelAutoRestartHelper: '저장하면 설정 적용을 위해 컨테이너가 자동으로 재시작됩니다.',
channelDeleteConfirm: '{0} 채널 구성을 삭제하시겠습니까?',
customProviderHelper: '사용자 정의 모델 공급자는 계정 사용 가능 여부를 검증하지 않습니다',
+ apiTypeBaseURLHelper: '이 유형은 최종적으로 {0}에 요청합니다. 권장 Base URL: {1}',
+ apiTypeBaseURLMismatch: '현재 Base URL은 {0} 경로처럼 보이지만 {1}이 선택되었습니다. 권장 URL: {2}',
},
model: {
model: '모델',
@@ -1015,6 +1017,8 @@ const message = {
healthUnknown: '알 수 없음',
validationModelMapEmpty: '모델 매핑의 모델 이름은 비워 둘 수 없습니다',
validationModelMapDuplicate: '요청 모델 {0}이(가) 중복되었습니다',
+ validateAvailability: '계정 사용 가능 여부 검증',
+ validateAvailabilityHelper: '저장 전에 최소 메시지를 보내 API 사용 가능 여부를 검증합니다',
modelGroup: '모델 그룹',
availableModels: '사용 가능한 모델',
modelGroupModels: '요청 모델',
diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts
index 5cd1b0aa12a9..8b8c92665f7c 100644
--- a/frontend/src/lang/modules/ms.ts
+++ b/frontend/src/lang/modules/ms.ts
@@ -865,6 +865,9 @@ const message = {
'Menyimpan akan memulakan semula bekas secara automatik supaya konfigurasi berkuat kuasa.',
channelDeleteConfirm: 'Padam konfigurasi saluran {0}?',
customProviderHelper: 'Penyedia model tersuai tidak mengesahkan sama ada akaun boleh digunakan',
+ apiTypeBaseURLHelper: 'Jenis ini menghantar permintaan ke {0}. Base URL yang disyorkan: {1}',
+ apiTypeBaseURLMismatch:
+ 'Base URL semasa kelihatan seperti laluan {0}, tetapi {1} dipilih. URL yang disyorkan: {2}',
},
model: {
model: 'Model',
@@ -1038,6 +1041,8 @@ const message = {
healthUnknown: 'Tidak diketahui',
validationModelMapEmpty: 'Nama model dalam pemetaan model tidak boleh kosong',
validationModelMapDuplicate: 'Model permintaan {0} berulang',
+ validateAvailability: 'Sahkan Ketersediaan Akaun',
+ validateAvailabilityHelper: 'Hantar mesej minimum sebelum menyimpan untuk mengesahkan ketersediaan API',
modelGroup: 'Kumpulan Model',
availableModels: 'Model Tersedia',
modelGroupModels: 'Model Permintaan',
diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts
index 88cf8b4996f5..ffedcc1227a2 100644
--- a/frontend/src/lang/modules/pt-br.ts
+++ b/frontend/src/lang/modules/pt-br.ts
@@ -861,6 +861,9 @@ const message = {
'Ao salvar, o contêiner será reiniciado automaticamente para que a configuração entre em vigor.',
channelDeleteConfirm: 'Excluir a configuração do canal {0}?',
customProviderHelper: 'Provedores de modelo personalizados não validam se a conta está disponível',
+ apiTypeBaseURLHelper: 'Este tipo envia requisições para {0}. Base URL recomendada: {1}',
+ apiTypeBaseURLMismatch:
+ 'A Base URL atual parece um caminho {0}, mas {1} está selecionado. URL recomendada: {2}',
},
model: {
model: 'Modelo',
@@ -1034,6 +1037,9 @@ const message = {
healthUnknown: 'Desconhecido',
validationModelMapEmpty: 'Os nomes no mapeamento de modelos não podem ficar vazios',
validationModelMapDuplicate: 'O modelo solicitado {0} está duplicado',
+ validateAvailability: 'Validar disponibilidade da conta',
+ validateAvailabilityHelper:
+ 'Envie uma mensagem mínima antes de salvar para validar a disponibilidade da API',
modelGroup: 'Grupo de modelos',
availableModels: 'Modelos disponíveis',
modelGroupModels: 'Modelos solicitados',
diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts
index f9dfc5963b15..0174b7ed27f2 100644
--- a/frontend/src/lang/modules/ru.ts
+++ b/frontend/src/lang/modules/ru.ts
@@ -856,6 +856,8 @@ const message = {
'После сохранения контейнер будет автоматически перезапущен, чтобы настройки вступили в силу.',
channelDeleteConfirm: 'Удалить конфигурацию канала {0}?',
customProviderHelper: 'Для пользовательского провайдера модели доступность учетной записи не проверяется',
+ apiTypeBaseURLHelper: 'Этот тип отправляет запросы в {0}. Рекомендуемый Base URL: {1}',
+ apiTypeBaseURLMismatch: 'Текущий Base URL похож на путь {0}, но выбран {1}. Рекомендуемый URL: {2}',
},
model: {
model: 'Модель',
@@ -1029,6 +1031,9 @@ const message = {
healthUnknown: 'Неизвестно',
validationModelMapEmpty: 'Имена моделей в сопоставлении не могут быть пустыми',
validationModelMapDuplicate: 'Запрошенная модель {0} дублируется',
+ validateAvailability: 'Проверить доступность аккаунта',
+ validateAvailabilityHelper:
+ 'Отправить минимальное сообщение перед сохранением для проверки доступности API',
modelGroup: 'Группа моделей',
availableModels: 'Доступные модели',
modelGroupModels: 'Запрошенные модели',
diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts
index 40039d4d67c5..af8c9f092b16 100644
--- a/frontend/src/lang/modules/tr.ts
+++ b/frontend/src/lang/modules/tr.ts
@@ -864,6 +864,9 @@ const message = {
'Kaydettiğinizde ayarların etkili olması için konteyner otomatik olarak yeniden başlatılır.',
channelDeleteConfirm: '{0} kanal yapılandırması silinsin mi?',
customProviderHelper: 'Özel model sağlayıcısında hesabın kullanılabilirliği doğrulanmaz',
+ apiTypeBaseURLHelper: 'Bu tür istekleri {0} yoluna gönderir. Önerilen Base URL: {1}',
+ apiTypeBaseURLMismatch:
+ 'Geçerli Base URL bir {0} yolu gibi görünüyor, ancak {1} seçildi. Önerilen URL: {2}',
},
model: {
model: 'Model',
@@ -1037,6 +1040,9 @@ const message = {
healthUnknown: 'Bilinmiyor',
validationModelMapEmpty: 'Model eşlemesindeki model adları boş olamaz',
validationModelMapDuplicate: 'İstek modeli {0} yineleniyor',
+ validateAvailability: 'Hesap Kullanılabilirliğini Doğrula',
+ validateAvailabilityHelper:
+ 'Kaydetmeden önce API kullanılabilirliğini doğrulamak için en küçük iletiyi gönder',
modelGroup: 'Model Grubu',
availableModels: 'Kullanılabilir Modeller',
modelGroupModels: 'İstek Modelleri',
diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts
index 0430ffc50c79..5dc595f478f1 100644
--- a/frontend/src/lang/modules/zh-Hant.ts
+++ b/frontend/src/lang/modules/zh-Hant.ts
@@ -809,6 +809,8 @@ const message = {
channelAutoRestartHelper: '保存後將自動重新啟動容器以使設定生效。',
channelDeleteConfirm: '確認刪除 {0} 頻道設定?',
customProviderHelper: '自訂模型供應商不驗證帳號是否可用',
+ apiTypeBaseURLHelper: '目前類型最終請求 {0},Base URL 建議填寫 {1}',
+ apiTypeBaseURLMismatch: '目前 Base URL 看起來是 {0} 路徑,和已選擇的 {1} 不一致,建議改為 {2}',
},
model: {
model: '模型',
@@ -977,6 +979,8 @@ const message = {
healthUnknown: '未知',
validationModelMapEmpty: '模型映射的模型名稱不能為空',
validationModelMapDuplicate: '請求模型 {0} 重複',
+ validateAvailability: '驗證帳號可用性',
+ validateAvailabilityHelper: '儲存前發送最小訊息驗證介面可用性',
modelGroup: '模型組',
availableModels: '可用模型',
modelGroupModels: '請求模型',
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index 6d897e7108fe..14ee4d48696c 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -802,6 +802,8 @@ const message = {
channelAutoRestartHelper: '保存后将自动重启容器以使配置生效。',
channelDeleteConfirm: '确认删除 {0} 频道配置?',
customProviderHelper: '自定义模型供应商不验证账号是否可用',
+ apiTypeBaseURLHelper: '当前类型最终请求 {0},Base URL 建议填写 {1}',
+ apiTypeBaseURLMismatch: '当前 Base URL 看起来是 {0} 路径,和已选择的 {1} 不一致,建议改为 {2}',
},
model: {
model: '模型',
@@ -968,6 +970,8 @@ const message = {
healthUnknown: '未知',
validationModelMapEmpty: '模型映射的模型名不能为空',
validationModelMapDuplicate: '请求模型 {0} 重复',
+ validateAvailability: '验证账号可用性',
+ validateAvailabilityHelper: '保存前发送最小消息验证接口可用性',
modelGroup: '模型组',
availableModels: '可用模型',
modelGroupModels: '请求模型',
diff --git a/frontend/src/views/ai/agents/model/add/index.vue b/frontend/src/views/ai/agents/model/add/index.vue
index 4f44bd4948f6..7a2ce9c55137 100644
--- a/frontend/src/views/ai/agents/model/add/index.vue
+++ b/frontend/src/views/ai/agents/model/add/index.vue
@@ -30,6 +30,18 @@
+
+ {{ apiTypeBaseURLHelper }}
+
+
+ {{ baseURLAPITypeMismatchTip }}
+
@@ -133,6 +145,67 @@ const apiTypeOptions = computed(() => {
}
return ['openai-completions', 'openai-responses'];
});
+const apiTypeURLHints: Record = {
+ 'openai-completions': {
+ requestPath: '/v1/chat/completions',
+ example: 'http://127.0.0.1:8000/v1',
+ endpointSuffixes: ['/v1/chat/completions', '/v1beta/chat/completions', '/chat/completions'],
+ },
+ 'openai-responses': {
+ requestPath: '/v1/responses',
+ example: 'http://127.0.0.1:8000/v1',
+ endpointSuffixes: ['/v1/responses', '/responses'],
+ },
+ 'anthropic-messages': {
+ requestPath: '/v1/messages',
+ example: 'http://127.0.0.1:8000',
+ endpointSuffixes: ['/v1/messages', '/messages'],
+ },
+};
+const showAPITypeBaseURLTips = computed(() => form.provider === 'vllm');
+const apiTypeBaseURLHelper = computed(() => {
+ const hint = apiTypeURLHints[form.apiType];
+ if (!showAPITypeBaseURLTips.value || !hint) {
+ return '';
+ }
+ return i18n.global.t('aiTools.agents.apiTypeBaseURLHelper', [hint.requestPath, hint.example]);
+});
+
+const normalizeBaseURLPath = (baseURL: string) => {
+ const value = baseURL.trim().replace(/\/+$/, '');
+ if (!value) {
+ return '';
+ }
+ try {
+ return (new URL(value).pathname || '/').replace(/\/+$/, '').toLowerCase();
+ } catch {
+ return value.split(/[?#]/)[0].replace(/\/+$/, '').toLowerCase();
+ }
+};
+
+const detectAPITypeFromBaseURL = (baseURL: string) => {
+ const path = normalizeBaseURLPath(baseURL);
+ if (!path) {
+ return '';
+ }
+ for (const [apiType, hint] of Object.entries(apiTypeURLHints)) {
+ if (hint.endpointSuffixes.some((suffix) => path.endsWith(suffix))) {
+ return apiType;
+ }
+ }
+ return '';
+};
+const baseURLAPITypeMismatchTip = computed(() => {
+ if (!showAPITypeBaseURLTips.value || !form.baseURL) {
+ return '';
+ }
+ const detectedAPIType = detectAPITypeFromBaseURL(form.baseURL);
+ const expected = apiTypeURLHints[form.apiType];
+ if (!detectedAPIType || detectedAPIType === form.apiType || !expected) {
+ return '';
+ }
+ return i18n.global.t('aiTools.agents.apiTypeBaseURLMismatch', [detectedAPIType, form.apiType, expected.example]);
+});
const rules = reactive({
provider: [Rules.requiredSelect],
@@ -376,4 +449,8 @@ defineExpose({
white-space: nowrap;
}
}
+
+.base-url-warning {
+ margin-top: 8px;
+}