Commit Graph
5407 Commits
Author SHA1 Message Date
wucm667 dfdbc27709 fix(openai): default missing passthrough instructions 2026-07-31 18:55:15 +08:00
github-actions[bot] 7ceabb3fd5 chore: sync VERSION to 0.1.169 [skip ci] 2026-07-31 09:19:08 +00:00
Wesley Liddick 26d894ef4f Merge pull request #5137 from Wei-Shaw/fix/upstream-url-path-segment-validation
fix(gateway): 收紧上游 URL 路径片段校验
v0.1.169
2026-07-31 16:46:00 +08:00
shaw 017f6bbd5e fix(gateway): 收紧上游 URL 路径片段校验
网关有若干位置会把客户端可控的字符串拼进上游请求的 URL path(Responses
子路径、Gemini 模型名)。此前这些字符串未经校验直接参与拼接,可能改变上游
请求的路径结构,使实际发出的请求与客户端意图不一致。

- 新增 internal/service/upstream_path_guard.go:路径片段闭集允许清单
  (\w + `-` + `.`),拒绝空片段、纯点片段、超长片段与过深后缀
- /responses/*subpath 三条路由入口新增守卫,不可转发的子路径直接 404;
  service 层同时保证不产出不合规后缀,拼接函数再兜底一层
- Gemini AI Studio 原先 5 处重复的 URL 拼接收敛为唯一构造点
  buildGeminiAIStudioModelActionURL(校验模型片段 + action 白名单)
- Gemini native / GetModel handler 增加入口校验;ForwardAIStudioGET 逐片段校验
- Grok video 端点的 request_id 增加片段合规校验

合法子路径(/compact、/compact/detail、/{id}/cancel 形态)与既有模型名行为
不变,通配路由保留。
2026-07-31 16:11:45 +08:00
Wesley Liddick f9d2791693 Merge pull request #5032 from Ricardo-binZzz/fix/release-pricing-fallback-resource
fix(release): include pricing fallback resources
2026-07-31 14:00:07 +08:00
Ricardo-binZzz 105e5c5da3 fix(release): include pricing fallback resources 2026-07-31 13:51:22 +08:00
Wesley Liddick bf0fc03ab7 Merge pull request #5018 from hongheshan-svg/fix/glm-5.2-fallback-pricing
fix(billing): 补上 glm-5.2 兜底价,避免被 glm-5 子串匹配抢走
2026-07-31 12:00:45 +08:00
Wesley Liddick 2be08f3f39 Merge pull request #4913 from jeshica/fix/anthropic-count-tokens-max-tokens
fix: strip max_tokens from Anthropic count tokens
2026-07-31 11:58:28 +08:00
hongheshan-svgandClaude Opus 5 493955f7bd fix(billing): add glm-5.2 fallback pricing to stop glm-5 substring match
glm-5.2 has no entry in the fallback table, so getFallbackPricing falls
through to `strings.Contains(modelLower, "glm-5")` and prices it at
GLM-5 rates ($1.00 in / $3.20 out per MTok) instead of the official
z.ai rates ($1.40 / $4.40) — roughly 27% under.

LiteLLM carries no bare `glm-5.2` key either (only provider-prefixed
`cloudflare/@cf/zai-org/glm-5.2` and `fireworks_ai/.../glm-5p2`, which
the lookup candidates never match), so the request always lands on the
fallback path and the discrepancy shows up directly in usage logs.

Add the glm-5.2 entry (same price as glm-5.1 per docs.z.ai) and match it
before the bare `glm-5` branch, with a note that dotted variants must
precede it. The existing regression test asserting the old glm-5 price
is updated accordingly.

Source: https://docs.z.ai/guides/overview/pricing

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 11:49:30 +08:00
zhiyu 53aa5cd247 test: align ModelMappingPreservesOtherFields with max_tokens strip
The count_tokens path now strips max_tokens; this sibling test also
exercises ForwardCountTokens but still asserted max_tokens preservation.
Flip its assertion to expect the field is filtered, matching
CountTokensFiltersGenerationFields.
2026-07-31 11:47:21 +08:00
Wesley Liddick 0a45be17d8 Merge pull request #5033 from Ricardo-binZzz/fix/sub2api-no-new-privileges
fix(deploy): prevent application privilege gains
2026-07-31 11:44:28 +08:00
Wesley Liddick 60f6dc91cf Merge pull request #5115 from zvensmoluya/codex/update-gpt56-luna-terra-pricing
[codex] update GPT-5.6 Luna and Terra pricing
2026-07-31 11:44:21 +08:00
Wesley Liddick 1702ee1362 Merge pull request #5078 from wucm667/fix/issue-5072-subscription-expiry-label
fix(frontend): correct subscription expiry labels
2026-07-31 11:44:07 +08:00
Wesley Liddick c4b461c68c Merge pull request #5063 from lucas-ward/codex/issue-4211
fix(payment): keep subscription plan titles readable
2026-07-31 11:44:00 +08:00
Wesley Liddick 3c387a164d Merge pull request #5060 from alexj11324/codex/passkey-deployment-guidance
fix: clarify passkey deployment guidance
2026-07-31 11:43:53 +08:00
Wesley Liddick e854132a57 Merge pull request #4953 from spongehah/brn-qwen3guard-auxiliary-fields
feat(security-audit): allow Qwen3Guard auxiliary fields
2026-07-31 11:43:47 +08:00
Wesley Liddick a8cd33eead Merge pull request #5048 from wucm667/fix/issue-5041-claude-auto-classifier
fix(anthropic): recognize auto mode classifier
2026-07-31 11:43:39 +08:00
Wesley Liddick 276d9cbd9b Merge pull request #4993 from 17Yuns/fix/smtp-message-format
fix(email): generate standards-compliant SMTP messages
2026-07-31 11:43:32 +08:00
Wesley Liddick 1f8b3a9c60 Merge pull request #5037 from heathermhuang/codex/fix-composite-available-models
fix(channels): show Composite models by platform
2026-07-31 11:43:25 +08:00
Wesley Liddick c9156c1e7f Merge pull request #5053 from wucm667/fix/issue-5015-skip-unschedulable-refresh
fix(account): skip unschedulable token refresh candidates
2026-07-31 11:43:18 +08:00
Wesley Liddick 91850d36e6 Merge pull request #5030 from Ricardo-binZzz/fix/ops-cleanup-success-log-level
fix(logging): record cleanup success at info level
2026-07-31 11:43:11 +08:00
Wesley Liddick 6fa784fdd0 Merge pull request #5118 from Wei-Shaw/fix/openai-proxy-stream-circuit-fail-open
fix(openai): 代理断流熔断改为 fail-open 偏好,修复共用代理部署下的调度不可用
2026-07-31 10:42:24 +08:00
shaw da49ce3f29 fix(openai): fail open proxy stream circuit and collapse burst disconnects
The proxy stream circuit introduced in v0.1.164 (#4749) removes every
account behind a quarantined proxy from scheduling. When all schedulable
accounts share one proxy (a common deployment), two mid-stream
disconnects within a minute zeroed out capacity for 10 minutes and every
request failed with 502. One HTTP/2 connection loss also killed all
multiplexed streams at once, tripping the threshold from a single event.

- Quarantine now degrades to a preference: when the only reason no
  account is available is proxy quarantine, selection retries once with
  the quarantine bypassed, so capacity can never reach zero.
- Disconnects within 3s per proxy collapse into one failure event.
- Add gateway.openai_proxy_stream_circuit.disabled escape hatch.
- A completed stream still clears the quarantine immediately; TTL,
  thresholds and recording guards are unchanged.
2026-07-31 10:30:30 +08:00
Zven 313121f3f7 test(pricing): update requested Terra cost 2026-07-31 10:02:04 +08:00
Zven 488d3b09ec test(pricing): update Terra billing ratios 2026-07-31 09:55:16 +08:00
Zven b2d895fb8d fix(pricing): update GPT-5.6 Luna and Terra rates 2026-07-31 09:42:46 +08:00
wucm667 fb40211305 fix(frontend): correct subscription expiry labels 2026-07-30 12:47:05 +08:00
wucm667 352b21f4e2 fix(claude): relax marker to tolerate category element in classifier output
Real claude-cli/2.1.220 samples insert <category>...</category> between
</block> and <reason>, breaking the previous literal marker.
Also fix an unchecked type assertion in the test suite.
2026-07-29 23:25:02 +08:00
BayinForge 0ee9ea5765 fix(payment): keep subscription plan titles readable 2026-07-29 21:23:16 +08:00
Zhixuan Jiang 711056f5b7 fix: clarify passkey deployment guidance 2026-07-29 08:58:33 -04:00
wucm667 ac90355a87 fix(account): skip unschedulable token refresh candidates 2026-07-29 18:35:56 +08:00
wucm667 54b1f8f6b3 fix(anthropic): recognize auto mode classifier 2026-07-29 16:55:42 +08:00
Ricardo-binZzz 0010894f99 fix(deploy): prevent application privilege gains 2026-07-29 13:25:05 +08:00
Ricardo-binZzz 0353cdadfe fix(logging): record cleanup success at info level 2026-07-29 13:25:03 +08:00
Heatherm Huang 92dc61d401 fix(channels): show composite models by platform
Expand visible Composite groups into each configured concrete model platform while preserving ordinary group isolation and empty-state behavior.\n\nFixes #4985
2026-07-29 12:32:44 +08:00
github-actions[bot] 5a6143097d chore: sync VERSION to 0.1.168 [skip ci] 2026-07-29 03:51:01 +00:00
github-actions[bot] b9c7cb8e24 chore: sync VERSION to 0.1.167 [skip ci] 2026-07-29 03:36:59 +00:00
Wesley Liddick 99c8e4bf75 Merge pull request #4973 from yiancode/fix/openai-live-store-resilience
fix(openai-live): Live 会话 finalize 与 observer 对 store 故障的容错,防止用量记录静默丢失
v0.1.168
2026-07-29 09:42:56 +08:00
Wesley Liddick f2d824836f Merge pull request #5008 from hansnow/fix/claude-sonnet-5-status-alias
fix(frontend): 补充 Claude Sonnet 5 模型状态别名
2026-07-29 09:41:54 +08:00
Wesley Liddick 6e1cbed423 Merge pull request #5024 from Wei-Shaw/fix/passkey-disabled-toast
fix(profile): 修复未配置 Passkey 时 /profile 每次访问都弹「加载 Passkey 失败」
2026-07-29 09:41:06 +08:00
shaw acad7f1a09 fix(profile): stop passkey load error toast when feature is disabled
The PASSKEY_DISABLED silence guard compared the string error code
against error.code, but the api client puts the numeric envelope code
there and the string code in error.reason, so the guard never matched
and every /profile visit on deployments without WebAuthn configured
showed a spurious "failed to load passkeys" toast.

Read error.reason instead, and skip the credentials request entirely
when the feature is disabled so the card no longer issues a request
that is guaranteed to fail with 403.
2026-07-28 22:51:58 +08:00
Wesley Liddick 8fd01c2814 Merge pull request #5003 from feeeei/main
feat(模型广场): add model plaza with group-scoped pricing showcase
2026-07-28 20:02:52 +08:00
Wesley Liddick 39903f006e Merge pull request #5005 from Wei-Shaw/refactor/scoped-column-updates
refactor(repository): scope user/api-key updates to explicitly declared columns
2026-07-28 19:43:50 +08:00
hansnow 32618e71e4 fix(frontend): 补充 Claude Sonnet 5 状态别名 2026-07-28 18:17:38 +08:00
shaw 86fb4781f4 refactor(repository): scope user/api-key updates to declared columns
UserRepository.Update and APIKeyRepository.Update rewrote the whole row on
every call, regardless of which fields the caller meant to change. Several
columns on those tables are maintained by dedicated atomic paths (balance
deduction, quota and rate-limit counters, limit adjustments, activity
timestamps), so a caller holding a slightly older snapshot could silently
roll them back - a lost update.

Both methods now take an explicit column mask and persist only the columns
the caller declares; everything else keeps its current database value.

- All user and API-key call sites declare exactly what they mutate, which
  turns admin edits and profile saves into genuine partial updates.
- Email uniqueness locking/lookup and allowed_groups sync only run when
  those fields are part of the update.
- UserUpdateFields deliberately has no balance/total_recharged members, so
  Update cannot touch them. New AdjustBalance/SetBalance apply the change in
  a single statement and return before/after values; admin balance
  adjustment uses them instead of read-modify-write.
- promo_codes.used_count is no longer written by Update; it is only ever
  incremented by the redemption path.
- The billing hot path that marks an API key quota-exhausted writes only
  status.
- Dropped a no-op row write in RevokeAllUserTokens: users has no
  token_version column, so it persisted nothing while still overwriting
  concurrently-updated columns.

Adds integration coverage that a stale snapshot cannot revert concurrent
atomic writes, and unit coverage pinning the column set each entry point
declares.
2026-07-28 17:21:32 +08:00
feeeei 720c405e35 feat: add model plaza with group-scoped pricing showcase
- public /model-plaza page (standalone + admin-embedded) listing groups
  with discounted effective prices alongside LiteLLM official reference
- faceted platform/group/rate filters: cross-dimension options gray out
  instead of disappearing, platform-tinted chips via accent color-mix
- paid-price columns highlighted with per-platform tint band
- OptionalJWT middleware so anonymous and signed-in users share one route
- admin settings: enable switch, require-auth switch, markdown description
2026-07-28 16:19:41 +08:00
Wesley Liddick 2e432173f7 Merge pull request #4920 from alexj11324/feat/passkey-auth
feat: add passkey authentication
2026-07-28 14:58:37 +08:00
shaw 38ef8dc069 feat: require account password for passkey enrollment and revocation
A hijacked session must not be able to silently add a passkey as a
persistent backdoor or remove the victim's credentials. Registration
(begin) and deletion now verify the account password server-side,
reusing the existing PASSWORD_REQUIRED / PASSWORD_INCORRECT errors.

The password is used instead of TOTP step-up so the guard also protects
deployments that never configured a TOTP encryption key. The password
key in both request bodies is covered by the audit middleware's
key-substring redaction, so no credential material reaches audit_logs.

Frontend: the add-passkey form gains a current-password field, and the
delete confirmation is now a dialog with a password input (replacing
window.confirm), mirroring the TOTP disable dialog. Backend error
messages (e.g. wrong password) are surfaced instead of the generic
failure toast. Rename remains password-free as it is cosmetic.
2026-07-28 14:12:46 +08:00
17Yuns edac19e87a fix(email): generate standards-compliant SMTP messages 2026-07-28 12:28:46 +08:00
shaw 97f44b21bb fix: keep passkey switch coupled to WebAuthn config and fix CI issues
- parseSettings now reports passkey_enabled=false whenever the WebAuthn
  deployment config is absent: a stale "true" row left behind after the
  config is removed previously made the admin update gate reject every
  settings save while the UI toggle was disabled, leaving no recovery
  path from the admin panel. Added a regression test.
- update the admin settings API contract goldens with the new
  passkey_enabled/passkey_configured/passkey_rp_id/passkey_rp_origins
  fields.
- errcheck: check rows.Close in passkey repository (repo convention).
- staticcheck QF1001: apply De Morgan's law in WebAuthn origin scheme
  validation.
2026-07-28 11:45:18 +08:00