Skip to content

v0.0.21 ​

✨ New Features ​

  • Full zh/en internationalization (i18n):
    • Every admin page (channels / tokens / users / plans / subscriptions / orders / admin orders / logs / redemptions / admin dashboard / system / cluster / operations / pricing / top-up / payment / personal settings), the console dashboard, landing page, login / register / password reset / OAuth, terms of service and privacy policy now support Chinese and English.
    • A language switcher (LangSwitcher) is added to the top bar and the landing navbar; the choice is persisted to localStorage.lang and synced to <html lang>.
    • Menus, page copy, table columns, modals, buttons, hints, form validation and Message toasts all switch in real time.
  • Arco Design component localization: App.vue injects the Arco locale bundle (zh-cn / en-us) via a-config-provider, localizing date pickers, pagination, empty states, Popconfirm and other built-in components.
  • Per-page message modules with automatic deep merge: new src/i18n/pages/*.js page modules are auto-loaded by src/i18n/pages.js through import.meta.glob and recursively deep-merged, so modules sharing a namespace never clobber each other.
  • Token page UI improvements:
    • "Remaining / Used" quota is now laid out horizontally with a baseline-aligned / separator.
    • The key column gains a "view full key" modal with one-click copy and close.
    • A new "Available Models" column shows X / Unrestricted; clicking it opens a grid + dot modal listing models, falling back to all available models when the token is unrestricted.
  • tiktoken BPE embedded offline: //go:embed bundles the cl100k_base / o200k_base / p50k_base / r50k_base BPE files (~6.4 MB) into the binary, so token counting is exact with zero configuration and no network, covering gpt-3.5-turbo / gpt-4 / gpt-4o and friends.

🐛 Bug Fixes ​

  • Fixed Redis user-quota cache drift versus the real balance (multiple paths):
    • IncreaseUserQuota now refreshes Redis after a direct DB write, so top-ups / admin grants / invite rewards become visible on the very next request.
    • In batch mode (BatchUpdateEnabled=true), batchUpdate refreshes the affected users' cache after flushing, keeping users.quota and user_quota:<id> aligned.
    • Admin UpdateUser refreshes the cache after overwriting quota, preventing persistent false 403s after a quota edit.
    • The "trusted, skip pre-consume" guard in preConsumeQuota is moved before the Redis decrement, so funded requests no longer drift the cache on every call; on pre-consume failure, the prior Redis decrement is rolled back via RedisIncrease.
    • The user_quota cache low-water refresh threshold is raised (500 → 50_000), narrowing the drift dead zone caused by high-price models (~80_000 quota per pre-consume) and fixing persistent false insufficient_user_quota 403s.
  • Fixed token-counting panic in firewalled / offline environments: the tiktoken download timeout left the fallback incomplete, SyncOptions flipped ApproximateTokenEnabled back to false, and Encode() was eventually called on a nil encoder; embedding the BPE files removes the whole chain.
  • Fixed "never expire" tokens being treated as expired: the expiry sentinel is unified from "only -1 means never expire" to "<=0 means never expire" (model/token.go / controller/token.go), fixing the false "token expired" error when enabling tokens whose legacy/dirty value was 0; the frontend adds a buildTokenExpiredTime helper so "never expire" is always submitted as -1.

🔧 Refactor ​

  • httpBpeLoader now resolves in three tiers: embedded (default, works out of the box) → TIKTOKEN_CACHE_DIR (escape hatch for custom encodings, bypassing embedded and HTTP) → HTTP download (last resort for future URL changes). The previous implicit fallback to the system temp data-gym-cache directory is dropped (it was invisible and prone to go clean -cache collateral damage).

📚 Documentation ​

  • README roadmap updated: "Internationalization (i18n)" moved to Done and a new "More languages" item added; synced across all 8 README languages (zh / zh-TW / en / ja / ru / de / ko / ar).

🧪 Tests ​

  • preConsumeQuota regression tests: pure-function formula, insufficient-balance 403 without DB mutation, trusted path leaving both user.quota and token.remain_quota untouched, normal pre-consume path, and Plan short-circuit.
  • User-quota and cache helper unit tests: direct-write semantics, negative-quota rejection, increase/decrease roundtrip consistency, and no-op rollback when Redis is disabled.
  • tiktoken embedded loader 3-tier fallback tests: SHA1 validation of all 4 embedded files, graceful handling of unknown URLs, parsing cl100k_base, end-to-end encoding for gpt-3.5 / gpt-4 / gpt-4o, TIKTOKEN_CACHE_DIR override, and HTTP fallback.
  • Token expiry sentinel tests: never-expire always submits -1 (never 0), <=0 is not treated as expired, and >0 expires correctly.

⚠️ Upgrade Notes ​

  • Zero database migration: no schema changes.
  • Frontend rebuild required: changes under web/default-pro/ need npm run build so the assets are re-embedded into the Go binary.
  • Binary size grows by ~6.4 MB: the 4 embedded tiktoken BPE files buy offline operation and non-blocking startup; set TIKTOKEN_CACHE_DIR to override with custom encodings.
  • Language switching: defaults to Chinese; switch from the top bar after login or from the landing navbar. The choice is stored in localStorage.lang.
  • Build & test:
    • go build ./... passes.
    • go test ./model/ ./controller/ ./middleware/ is green.
    • cd web/default-pro && npm run build passes.