5 Commits
Author SHA1 Message Date
m1saka ecdf0c44d1 Fix upstream 400: flatten multi-part content arrays and sanitize invalid tool_calls
build / build (push) Successful in 2m31s
The Zhanlu upstream gateway returns HTTP 400 (请求消息格式错误) for two
message-structure issues that AI coding tools like MiMoCode produce:

1. Multi-part content arrays — OpenAI SDKs send content as
   [{type:"text",text:"…"}] arrays; the gateway only accepts string
   content. normalizeMessages now flattens text-only arrays into a
   concatenated string (non-text parts like images are preserved).

2. Invalid tool_calls — when a tool call fails, MiMoCode emits
   {name:"invalid", arguments:{"tool":"task","error":"…"}}
   placeholders. The gateway rejects function names not in the tools list
   and non-object arguments (e.g. "-1"). normalizeMessages now
   sanitizes these in place: the real tool name is extracted from the
   arguments' "tool" field (falling back to an arbitrary declared
   tool), and non-JSON-object arguments are replaced with "{}". No
   messages or tool results are removed, preserving the full
   conversation context including error feedback.

Verified with the exact error.md request: 0/10 400 errors after fix
(vs 10/10 before). Model returns valid streaming responses with task
tool calls.
2026-08-23 22:16:32 +08:00
root 8a1cf4d61f Redesign admin UI: unified tabbed console, humanized and paginated stats
build / build (push) Successful in 2m32s
- Unify /admin/login and /admin/stats into a single /admin page with tabs
  (Token stats default, credential login); old paths redirect to /admin.
- Restyle from dark glass-morphism to a clean light theme (single accent,
  system font stack, 1px-bordered cards, generous whitespace).
- Humanize token counts with K/M/B suffixes via a humanNum template func.
- Paginate recent requests client-side (10 per page) with a compact pager.
- Drop the database path from the UI.
- Fix mobile horizontal overflow caused by grid min-width:auto.
2026-08-19 17:12:30 +08:00
m1saka fa9640d919 Add token usage stats and consolidate credentials in SQLite
build / build (push) Successful in 2m34s
- New internal/stats (types) and internal/store (SQLite owner: requests + credentials tables, WAL); store implements stats.Recorder.
- Stream (SSE tee) and non-stream chat paths parse upstream usage incl. cached_tokens and record per-request; add /api/stats, /api/stats/reset, /admin/stats HTML with cache hit rate.
- Drop credentials.json: remove auth file I/O and ZHANLU_CREDENTIALS_FILE; credential precedence is env vars > db row.
2026-08-19 15:52:00 +08:00
m1saka 7d8a5b6f74 Update proxy to Zhanlu v1.4.2 provider flow
The 1.4.2 extension replaced the old signed/encrypted chat gateway with an
OpenAI-compatible aigateway. Align the proxy with the new flow:

- Use ecloud.10086.cn login/model base URLs, zhanlu_ide plugin headers and
  v1.4.2 plugin version
- Provision the model API key via SM2-signed get-or-create after v1/login
  profile fetch; store api_key/model_base_url/email in credentials
- Chat via Bearer apiKey against {modelBaseUrl}/chat/completions with plain
  OpenAI SSE passthrough; fetch /v1/models from the gateway model-info endpoint
- Force HTTP/1.1 upstream (gateway drops HTTP/2 ALPN negotiation with EOF)
- Drop obsolete AES body encryption, model name mapping and vscode headers
2026-08-05 14:55:28 +08:00
M1saka d4dd3a0f1b Initial zhanlu OpenAI proxy
build / build (push) Successful in 53s
2026-07-08 09:13:45 +08:00