From 9dbdca0e5e6503eaa66affc53d6e41a3e45524aa Mon Sep 17 00:00:00 2001 From: decolua Date: Fri, 28 Aug 2026 16:12:04 +0700 Subject: [PATCH] refactor(search): fold zai-search into the glm provider The separate zai-search entry showed "No connections" on the web search page because credentials live on the `glm` connection, not on it. Every other provider that does both chat and search (antigravity, kimi, xai, gemini) declares webSearch on the provider itself, so do the same here. - glm gains serviceKinds ["llm", "webSearch"] and the MCP searchConfig - the request builder / normalizer move from "zai-search" to "glm" - drop the zai-search registry entry and its svg logo, which also removes the only need for svg logo support in getProviderIconSrc ollama-search keeps its own entry and credentialFallback: its search endpoint is unrelated to the ollama chat transport. --- open-sse/handlers/search/callers.js | 6 ++-- open-sse/handlers/search/normalizers.js | 6 ++-- open-sse/providers/registry/glm.js | 14 ++++++++++ open-sse/providers/registry/index.js | 2 -- open-sse/providers/registry/zai-search.js | 34 ----------------------- public/providers/zai-search.svg | 5 ---- src/shared/utils/providerIcon.js | 10 ++----- 7 files changed, 22 insertions(+), 55 deletions(-) delete mode 100644 open-sse/providers/registry/zai-search.js delete mode 100644 public/providers/zai-search.svg diff --git a/open-sse/handlers/search/callers.js b/open-sse/handlers/search/callers.js index f17d318d..5e3b3c09 100644 --- a/open-sse/handlers/search/callers.js +++ b/open-sse/handlers/search/callers.js @@ -394,12 +394,12 @@ function buildOllamaSearchRequest(config, params) { }; } -// ── Z.AI Coding plan MCP web_search_prime ───────────────────────────────── +// ── GLM Coding plan MCP web_search_prime ────────────────────────────────── // POST https://api.z.ai/api/mcp/web_search_prime/mcp // JSON-RPC envelope: { jsonrpc, id, method: "tools/call", // params: { name: "web_search_prime", arguments: { search_query, count } } } // Response: { result: { content: [{ type: "text", text: "" }] } } -function buildZaiSearchRequest(config, params) { +function buildGlmSearchRequest(config, params) { const body = { jsonrpc: "2.0", id: `9r-${Date.now()}`, @@ -437,7 +437,7 @@ const BUILDERS = { "searxng": buildSearxngRequest, "xquik": buildXquikRequest, "ollama-search": buildOllamaSearchRequest, - "zai-search": buildZaiSearchRequest, + "glm": buildGlmSearchRequest, }; /** diff --git a/open-sse/handlers/search/normalizers.js b/open-sse/handlers/search/normalizers.js index a2b6a1d8..3b415ae5 100644 --- a/open-sse/handlers/search/normalizers.js +++ b/open-sse/handlers/search/normalizers.js @@ -257,7 +257,7 @@ function normalizeOllamaSearch(data, _query, _searchType) { return { results, totalResults: results.length }; } -function normalizeZaiSearch(data, _query, _searchType) { +function normalizeGlmSearch(data, _query, _searchType) { const now = new Date().toISOString(); // MCP envelope: { result: { content: [{ type: "text", text: "" }] } } let payload = data; @@ -270,7 +270,7 @@ function normalizeZaiSearch(data, _query, _searchType) { : Array.isArray(payload) ? payload : []; const results = items.map((item, idx) => - makeResult("zai-search", { + makeResult("glm", { title: item.title, url: item.link || item.url, snippet: item.content || "", @@ -295,7 +295,7 @@ const NORMALIZERS = { "searxng": normalizeSearxng, "xquik": normalizeXquik, "ollama-search": normalizeOllamaSearch, - "zai-search": normalizeZaiSearch, + "glm": normalizeGlmSearch, }; /** diff --git a/open-sse/providers/registry/glm.js b/open-sse/providers/registry/glm.js index 969582c8..6c5f0f6e 100644 --- a/open-sse/providers/registry/glm.js +++ b/open-sse/providers/registry/glm.js @@ -53,6 +53,20 @@ export default { { id: "glm-4.7", name: "GLM 4.7" }, { id: "glm-4.6v", name: "GLM 4.6V (Vision)" }, ], + serviceKinds: ["llm", "webSearch"], + // Coding plan bundles web search on the same API key as chat. + searchConfig: { + baseUrl: "https://api.z.ai/api/mcp/web_search_prime/mcp", + method: "POST", + authType: "apikey", + authHeader: "bearer", + costPerQuery: 0, + searchTypes: ["web"], + defaultMaxResults: 5, + maxMaxResults: 50, + timeoutMs: 10000, + cacheTTLMs: 300000, + }, features: { usage: true, usageApikey: true, diff --git a/open-sse/providers/registry/index.js b/open-sse/providers/registry/index.js index 1f4beec7..ab71e2e7 100644 --- a/open-sse/providers/registry/index.js +++ b/open-sse/providers/registry/index.js @@ -98,7 +98,6 @@ import p95 from "./xai.js"; import p96 from "./xiaomi-mimo.js"; import p97 from "./xiaomi-tokenplan.js"; import p98 from "./youcom.js"; -import p124 from "./zai-search.js"; import p99 from "./alims-intl.js"; import p100 from "./codebuddy-intl.js"; // Temporarily hidden — no tool calling support (trae SOLO agent / windsurf gRPC skip ToolCallChunk). @@ -225,7 +224,6 @@ export default [ p96, p97, p98, - p124, p99, p100, // p102, // trae — hidden, no tool calling diff --git a/open-sse/providers/registry/zai-search.js b/open-sse/providers/registry/zai-search.js deleted file mode 100644 index b94f7651..00000000 --- a/open-sse/providers/registry/zai-search.js +++ /dev/null @@ -1,34 +0,0 @@ -export default { - id: "zai-search", - alias: "zai-search", - display: { - name: "GLM Coding Search", - icon: "travel_explore", - color: "#2563EB", - textIcon: "GS", - website: "https://z.ai", - notice: { - text: "Web search via the Z.AI Coding plan MCP endpoint. Reuses the API key from the GLM Coding provider.", - apiKeyUrl: "https://open.bigmodel.cn/usercenter/apikeys", - }, - }, - category: "apikey", - authType: "apikey", - authModes: ["apikey"], - serviceKinds: ["webSearch"], - // Credential fallback: reuses the GLM Coding plan API key — one key, chat + search. - credentialFallback: "glm", - searchConfig: { - baseUrl: "https://api.z.ai/api/mcp/web_search_prime/mcp", - method: "POST", - authType: "apikey", - authHeader: "bearer", - costPerQuery: 0, - freeMonthlyQuota: 0, - searchTypes: ["web"], - defaultMaxResults: 5, - maxMaxResults: 50, - timeoutMs: 10000, - cacheTTLMs: 300000, - }, -}; diff --git a/public/providers/zai-search.svg b/public/providers/zai-search.svg deleted file mode 100644 index a80e4f26..00000000 --- a/public/providers/zai-search.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - Z - .AI - diff --git a/src/shared/utils/providerIcon.js b/src/shared/utils/providerIcon.js index 5d26b57e..7e058520 100644 --- a/src/shared/utils/providerIcon.js +++ b/src/shared/utils/providerIcon.js @@ -8,9 +8,6 @@ const ICON_ALIASES = { "ollama-search": "ollama", }; -// Providers that ship an .svg logo instead of .png. -const SVG_PROVIDER_IDS = new Set(["zai-search"]); - // Runtime only — first 404 remembers id for the whole session const failedIds = new Set(); @@ -29,13 +26,10 @@ export function resolveProviderIconId(providerId) { return aliased; } -/** `/providers/{id}.{png|svg}` or null when previously failed. */ +/** `/providers/{id}.png` or null when previously failed. */ export function getProviderIconSrc(providerId) { const id = resolveProviderIconId(providerId); - if (!id) return null; - // svg for vector logos, png for everything else - const ext = SVG_PROVIDER_IDS.has(id) ? "svg" : "png"; - return `/providers/${id}.${ext}`; + return id ? `/providers/${id}.png` : null; } /** Call from img onError so later mounts skip the request. */