Skip to content

Feature/glm z ai provider#62

Open
Multikus wants to merge 2 commits into
Zen4-bit:mainfrom
Multikus:feature/glm-z-ai-provider
Open

Feature/glm z ai provider#62
Multikus wants to merge 2 commits into
Zen4-bit:mainfrom
Multikus:feature/glm-z-ai-provider

Conversation

@Multikus

Copy link
Copy Markdown

No description provided.

Multikus and others added 2 commits June 19, 2026 20:15
Add a new z.ai/GLM provider following the existing engine pattern.
The zai-engine.js script runs inside the chat.z.ai BrowserView, mints a
guest JWT (or uses the logged-in token from localStorage), signs requests
with the site's X-Signature HMAC scheme, and streams responses via SSE.

Wires the provider through provider-api, browser-manager, main-v2,
rest-api (aliases + docs), the MCP server (ask_glm tool + router), and the
UI. Updates README with the provider, engine table, and API examples.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Include the zai (GLM) provider in the WebSocket server's auto-provider
picker so it can be selected when no specific provider is requested,
matching the REST gateway's provider ordering.

The Electron renderer UI (tab + provider card) and the /docs chat widget
(model dropdown, battle selector, color maps, model grid) already cover
GLM; the renderer's enable list is data-driven from the backend
defaultSettings, so no further markup is required.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add GLM-5.2 (z.ai) provider with signed SSE engine, REST/MCP wiring, and UI support
✨ Enhancement 📝 Documentation 🕐 40+ Minutes

Grey Divider

Description

• Add a new z.ai-backed GLM provider with guest JWT auth, HMAC request signing, and SSE streaming.
• Wire the provider through Electron provider-api, REST gateway aliases/docs, MCP tools, and
 auto-provider pickers.
• Expose GLM in the Electron UI tabs/settings and the /docs chat widget model & battle selectors.
Diagram

graph TD
  U[Clients] --> REST["REST API + /docs widget"] --> PICK["Provider picker + aliases"] --> ELEC["Electron main/provider-api"] --> VIEW["BrowserView chat.z.ai"] --> ENG["zai-engine.js"] --> ZAPI["z.ai SSE API"]
  U --> WS["WS server"] --> PICK
  U --> MCP["MCP server (ask_glm)"] --> PICK
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use Zhipu/GLM official API (API key) instead of browser-session engine
  • ➕ More stable contract and fewer breakages from site frontend changes
  • ➕ Avoids scraping/signature reverse-engineering and localStorage token reliance
  • ➕ Easier to test and monitor with standard HTTP clients
  • ➖ Requires users to obtain/manage API keys and handle billing
  • ➖ May not match z.ai feature parity/UX expectations
  • ➖ Loses the 'works with existing browser session' convenience
2. DOM-driven send/receive fallback (like other providers) instead of engine-only
  • ➕ More resilient if the internal API/signature scheme changes
  • ➕ Potentially simpler operationally (no crypto signing needed)
  • ➖ Hard to robustly extract/stream output across UI changes
  • ➖ Typically slower and more brittle than calling the underlying API
  • ➖ May not support clean streaming semantics

Recommendation: The current engine-based approach is reasonable for a 'no API key' provider and matches the existing provider-engine architecture. The main risk is churn in z.ai’s signature scheme/FE version and token behavior; consider adding lightweight health checks/telemetry (e.g., surfacing signature/auth failure reasons) and documenting recovery steps (open chat.z.ai, reload, re-mint token) to reduce support burden.

Files changed (9) +371 / -26

Enhancement (8) +350 / -22
browser-manager.cjsAdd z.ai BrowserView config and readiness detection +18/-1

Add z.ai BrowserView config and readiness detection

• Registers a new 'zai' provider with URL/partition/color. Adds provider-domain mapping and a z.ai-specific 'usable state' check (token in localStorage or presence of a chat input).

electron/browser-manager.cjs

index-v2.htmlExpose GLM tab and settings card in Electron renderer UI +20/-0

Expose GLM tab and settings card in Electron renderer UI

• Adds styling and UI elements for a GLM (z.ai) tab plus a settings provider card with toggle. Introduces provider-specific color mapping for z.ai in the UI surface.

electron/index-v2.html

main-v2.cjsWire zai provider into settings, cookies, and error handling +14/-5

Wire zai provider into settings, cookies, and error handling

• Adds 'zai' to response state and default settings, cookie restore domain config, and open-in-browser URL mapping. Ensures the provider path is engine-only by throwing a clear error if the injected engine fails (no DOM fallback).

electron/main-v2.cjs

provider-api.cjsLoad and dispatch to injected Z.AI engine (__proximaZAI) +9/-5

Load and dispatch to injected Z.AI engine (__proximaZAI)

• Maps 'zai' to the new zai-engine.js loader, adds API readiness detection, enables send/reset routing via __proximaZAI, and includes zai in the reset-all provider list.

electron/provider-api.cjs

zai-engine.jsNew Z.AI engine: guest JWT auth, X-Signature HMAC, SSE streaming +252/-0

New Z.AI engine: guest JWT auth, X-Signature HMAC, SSE streaming

• Introduces an injected engine for chat.z.ai that retrieves a session token (localStorage or guest mint), signs requests using the site’s HMAC-based X-Signature scheme, and parses SSE responses into final text. Exposes a __proximaZAI interface with send() and newConversation().

electron/providers/zai-engine.js

rest-api.cjsAdd z.ai/GLM model aliases and /docs widget support +15/-8

Add z.ai/GLM model aliases and /docs widget support

• Adds MODEL_ALIASES for zai/glm naming variants and includes zai in the auto-provider preference ordering. Updates the embedded docs/chat widget dropdowns, battle selector, color maps, and model grid to include GLM (z.ai).

electron/rest-api.cjs

ws-server.cjsInclude zai in WS auto-provider selection ordering +1/-1

Include zai in WS auto-provider selection ordering

• Extends the WebSocket server's pickBestProvider ordering to consider zai alongside existing providers when auto-selecting an enabled backend.

electron/ws-server.cjs

mcp-server-v3.jsAdd zai provider to router and introduce ask_glm MCP tool +21/-2

Add zai provider to router and introduce ask_glm MCP tool

• Adds a zai AIProvider, updates the SmartRouter ordering to include zai, and registers a dedicated ask_glm tool with optional file context injection. Uses the existing disabled-provider checks and tool response/error helpers.

src/mcp-server-v3.js

Documentation (1) +21 / -4
README.mdDocument GLM provider, engine, and REST usage example +21/-4

Document GLM provider, engine, and REST usage example

• Adds GLM (z.ai) to the provider table and engine matrix, and includes a curl example for glm-5.2. Documents accepted aliases that route to the new z.ai provider.

README.md

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Settings merge drops zai 🐞 Bug ☼ Reliability
Description
loadSettings() shallow-merges saved settings over defaultSettings, so older settings.json
files replace the whole providers object and can omit the newly added zai entry. The new GLM
toggle/tab then dereferences settings.providers.zai (e.g. in toggleProvider) and can throw,
preventing users from enabling GLM after upgrading.
Code

electron/main-v2.cjs[R63-67]

        perplexity: { enabled: true, loggedIn: false },
        chatgpt: { enabled: true, loggedIn: false },
        claude: { enabled: false, loggedIn: false },
-        gemini: { enabled: true, loggedIn: false }
+        gemini: { enabled: true, loggedIn: false },
+        zai: { enabled: false, loggedIn: false }
Evidence
The main process loads settings with a shallow merge, so an older saved providers object can
overwrite defaults and drop the new zai key. The UI now renders a ZAI provider card/toggle and the
toggle handler assumes settings.providers[provider] exists, which will throw when `provider ===
'zai'` and the key is missing.

electron/main-v2.cjs[61-85]
electron/index-v2.html[1139-1149]
electron/index-v2.html[1471-1485]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`loadSettings()` does a shallow object spread (`{...defaultSettings, ...saved}`), which overwrites the entire nested `providers` map when an older `settings.json` is present. After adding the new `zai` provider UI toggle, `settings.providers.zai` can be missing, causing runtime errors when toggling or switching to ZAI.

## Issue Context
This primarily impacts upgrade/migration scenarios (existing installs) where `settings.json` was created before `zai` existed.

## Fix Focus Areas
- electron/main-v2.cjs[61-85]
- electron/index-v2.html[1139-1149]
- electron/index-v2.html[1471-1485]

## Implementation notes
- In `loadSettings()`, deep-merge nested provider defaults:
 - `providers: { ...defaultSettings.providers, ...(saved.providers || {}) }`
 - (Optionally) also deep-merge per-provider objects to backfill new fields like `loggedIn`.
- Consider adding a defensive guard either in the renderer (`toggleProvider`) or, preferably, in the main process before returning settings to the UI: if `settings.providers[provider]` is missing, initialize it from defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread electron/main-v2.cjs
Comment on lines 63 to +67
perplexity: { enabled: true, loggedIn: false },
chatgpt: { enabled: true, loggedIn: false },
claude: { enabled: false, loggedIn: false },
gemini: { enabled: true, loggedIn: false }
gemini: { enabled: true, loggedIn: false },
zai: { enabled: false, loggedIn: false }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Settings merge drops zai 🐞 Bug ☼ Reliability

loadSettings() shallow-merges saved settings over defaultSettings, so older settings.json
files replace the whole providers object and can omit the newly added zai entry. The new GLM
toggle/tab then dereferences settings.providers.zai (e.g. in toggleProvider) and can throw,
preventing users from enabling GLM after upgrading.
Agent Prompt
## Issue description
`loadSettings()` does a shallow object spread (`{...defaultSettings, ...saved}`), which overwrites the entire nested `providers` map when an older `settings.json` is present. After adding the new `zai` provider UI toggle, `settings.providers.zai` can be missing, causing runtime errors when toggling or switching to ZAI.

## Issue Context
This primarily impacts upgrade/migration scenarios (existing installs) where `settings.json` was created before `zai` existed.

## Fix Focus Areas
- electron/main-v2.cjs[61-85]
- electron/index-v2.html[1139-1149]
- electron/index-v2.html[1471-1485]

## Implementation notes
- In `loadSettings()`, deep-merge nested provider defaults:
  - `providers: { ...defaultSettings.providers, ...(saved.providers || {}) }`
  - (Optionally) also deep-merge per-provider objects to backfill new fields like `loggedIn`.
- Consider adding a defensive guard either in the renderer (`toggleProvider`) or, preferably, in the main process before returning settings to the UI: if `settings.providers[provider]` is missing, initialize it from defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant