- 23 Apr, 2026 3 commits
-
-
erio authored
Revert payment/wechat, sora/claude-max cleanup, fork-only migrations, and cosmetic changes that were brought in by the release sync commit. Keep only channel-monitor related improvements: - PublicSettingsInjectionPayload named struct with drift test - ChannelMonitorRunner graceful shutdown in wire - image_output_price in SupportedModelChip - Simplified buildSelfNavItems in AppSidebar - Gateway WARN logs for 503 branches
-
erio authored
- Extract PublicSettingsInjectionPayload named struct with drift test - Add channel_monitor_default_interval_seconds to SSR injection - Add image_output_price to SupportedModelChip - Simplify AppSidebar buildSelfNavItems (admins see available channels) - Add gateway WARN logs for 503 no-available-accounts branches - Wire ChannelMonitorRunner into provideCleanup for graceful shutdown - Add migrations 130/131 (CC template userid fix + mimicry field cleanup) - Clean up fork-only features (sora, claude max simulation, client affinity) - Remove ~320 obsolete i18n keys - Add codexUsage utility, WechatServiceButton, BulkEditAccountModal - Tidy go.sum
-
meteor041 authored
-
- 22 Apr, 2026 1 commit
-
-
lucas morgan authored
- 同步 OpenAI 图片生成与编辑接口 - 接入图片请求解析、账号调度、转发与用量记录 - 接入图片计费与图片用量落库 - 限制 OAuth 生图仅支持无显式模型和尺寸的基础请求
-
- 15 Apr, 2026 2 commits
-
-
erio authored
refactor: extract ReadUpstreamResponseBody to deduplicate upstream response read + too-large error handling Consolidates 9 call sites of resolveUpstreamResponseReadLimit + readUpstreamResponseBodyLimited + ErrUpstreamResponseBodyTooLarge error handling into a single ReadUpstreamResponseBody function with TooLargeWriter callback for API-format-specific error responses (Anthropic, OpenAI, countTokens).
-
Wesley Liddick authored
-
- 14 Apr, 2026 6 commits
-
-
erio authored
Backend: - gateway_handler: pass subject.UserID instead of int64(0) for user-level routing - setting_handler: add missing BalanceLowNotifyRechargeURL to UpdateSettings response - openai_gateway_service: use applyAccountStatsCost for account stats pricing integration - embed_on: add local file override (data/public/) for embedded frontend assets Frontend: - useTableSelection: add batchUpdate method for batch operations - AccountsView: virtual scrolling params, Set-based isSelected, swipe virtualization - ProxiesView: add batchUpdate to selection and swipe-select - BulkEditAccountModal: fix submit handler to prevent event object as argument - SettingsView: move payload construction outside try block - i18n: add general translation keys (saved, deleted, view, validation, allowUserRefund) - api/client: reorder error fields for consistency - stores/payment: clarify pollOrderStatus JSDoc
-
erio authored
Priority was wrong: - Before: custom rules → LiteLLM (when ApplyPricingToAccountStats) → nil - After: custom rules → totalCost (when ApplyPricingToAccountStats) → LiteLLM → nil When ApplyPricingToAccountStats is enabled, use the request's actual client billing cost (before multiplier) as account_stats_cost, instead of recalculating from LiteLLM per-token prices which produced incorrect values for per-request billing mode. LiteLLM model pricing is now the final fallback (priority 3), used only when neither custom rules nor ApplyPricingToAccountStats apply.
-
erio authored
WebSearch tri-state switch: - Account-level web_search_emulation changed from bool to tri-state string: "default" (follow channel) / "enabled" / "disabled" - shouldEmulateWebSearch checks channel config when account is "default" - SQL migration converts old bool values - Frontend select replaces toggle in Edit/CreateAccountModal Account stats pricing: - resolveAccountStatsCost uses upstream model (post-mapping) for matching - Priority: custom rules → model pricing file (when toggle on) → default - Custom rules always configurable, independent of toggle - Account ID field changed to searchable selector filtered by platform - Description updated to reflect new behavior Quota notification cache fix: - CheckAccountQuotaAfterIncrement fetches real-time account from DB - Reconstructs pre-increment usage for accurate threshold crossing detection - New AccountQuotaReader interface (minimal: GetByID only) Usage tooltip: - Per-request/image billing shows per-request price instead of $0 token price - Token billing continues to show input/output price per million tokens
-
erio authored
- resolveAccountStatsCost now uses the final upstream model (after account-level mapping) to match custom pricing rules, fixing the issue where requested model (e.g. claude-sonnet-4-5) didn't match rules configured for upstream model (e.g. claude-opus-4-6) - Remove tryChannelPricing fallback — only custom rules are applied, unmatched requests use default formula (total_cost × rate) - Remove unused billingService and serviceTier parameters - Update description: "启用后将支持自定义账号统计的模型价格"
-
erio authored
- User balance low notification: email alert when balance drops below configurable threshold (user email + verified extra emails) - Account quota notification: broadcast email to admin-configured recipients when daily/weekly/total quota usage exceeds alert threshold - Admin settings: global enable/disable, default threshold, quota notification email list (Email Settings tab) - User profile: enable/disable, custom threshold, add/remove extra notification emails with verification code flow - Account quota: per-dimension alert toggle and threshold in quota control card - Trigger logic: first-crossing only (old >= threshold && new < threshold for balance; old < threshold && new >= threshold for quota), naturally prevents duplicate notifications without Redis dedup
-
erio authored
Allow channels to configure independent model pricing for account statistics cost calculation, decoupled from user billing. Backend: - Migration 101: channels.apply_pricing_to_account_stats toggle, channel_account_stats_pricing_rules/model_pricing tables, usage_logs.account_stats_cost column - resolveAccountStatsCost: match rules by group/account, then channel pricing, fallback to original formula when unconfigured - Integrate into both GatewayService.recordUsageCore and OpenAIGatewayService.RecordUsage - Update 8 account stats SQL queries to use COALESCE(account_stats_cost, total_cost) * account_rate_multiplier - 23 unit tests for matching, pricing lookup, and cost calculation Frontend: - Channel edit dialog: toggle + custom rules UI with group/account multi-select and pricing entry cards - API types and i18n (zh/en)
-
- 08 Apr, 2026 1 commit
-
-
ius authored
-
- 07 Apr, 2026 3 commits
-
-
Elysia authored
当上游返回SSE格式响应(如sub2api链路)时,API Key账号的非流式路径 未检测SSE,导致终态事件中空output直接透传给客户端。 - 将Content-Type SSE检测从仅OAuth扩展至所有账号类型 - 重命名handleOAuthSSEToJSON为handleSSEToJSON(无OAuth专属逻辑) - 为透传路径新增handlePassthroughSSEToJSON,支持SSE转JSON及空output重建 Co-Authored-By:Claude Opus 4.6 (1M context) <noreply@anthropic.com>
-
shaw authored
上游API近期更新后,response.completed终态SSE事件的output字段可能为空, 实际内容仅通过response.output_text.delta等增量事件下发。流式路径不受影响, 但chat_completions非流式路径和responses OAuth非流式路径只依赖终态事件的 output,导致返回空响应。 新增BufferedResponseAccumulator累积器,在SSE扫描过程中收集delta事件内容 (文本、function_call、reasoning),当终态output为空时补充重建。 同时修复handleChatBufferedStreamingResponse遗漏response.done事件类型的问题。
-
Alex authored
-
- 05 Apr, 2026 1 commit
-
-
shaw authored
When a channel has no model mapping for the requested model, ChannelMappedModel equals OriginalModel (the user's arbitrary input). Combined with the default BillingModelSource="channel_mapped", this incorrectly overrides the BillingModel set by the OpenAI format conversion layer (e.g., gpt-5.4 from DefaultMappedModel) back to the unmapped original model (e.g., glm) which has no pricing — resulting in zero-cost billing. Add guard condition so the channel_mapped override only fires when the channel actually changed the model (ChannelMappedModel != OriginalModel).
-
- 04 Apr, 2026 15 commits
-
-
erio authored
Eliminates unnecessary indirection layer. The wrapper function only called normalizeCodexModel with a special case for "gpt 5.3 codex spark" (space-separated variant) that is no longer needed. All call sites now use normalizeCodexModel directly.
-
erio authored
- Change channel cache TTL from 60s to 10min (reduce unnecessary DB queries) - Actively rebuild cache after CRUD instead of lazy invalidation - Add slog.Warn logging for channel pricing restriction blocks (4 places)
-
erio authored
P0-1: Credits degraded response retry + fail-open - Add isAntigravityDegradedResponse() to detect transient API failures - Retry up to 3 times with exponential backoff (500ms/1s/2s) - Invalidate singleflight cache between retries - Fail-open after exhausting retries instead of 5h circuit break P1-1: Fix channel restriction pre-check timing conflict - Swap checkClaudeCodeRestriction before checkChannelPricingRestriction - Ensures channel restriction is checked against final fallback groupID P1-2: Add interval pricing validation (frontend + backend) - Backend: ValidateIntervals() with boundary, price, overlap checks - Frontend: validateIntervals() with Chinese error messages - Rules: MinTokens>=0, MaxTokens>MinTokens, prices>=0, no overlap P2: Fix cross-platform same-model pricing/mapping override - Store cache keys using original platform instead of group platform - Lookup across matching platforms (antigravity→anthropic→gemini) - Prevents anthropic/gemini same-name models from overwriting each other
-
erio authored
- Fix 7 stale comments still mentioning "限制检查" in handlers/services - Make billingModelForRestriction explicitly list channel_mapped case - Add slog.Warn for error swallowing in ResolveChannelMapping and needsUpstreamChannelRestrictionCheck - Document sticky session upstream check exemption
-
erio authored
- PricingSourceChannel/LiteLLM/Fallback for resolver source - MediaTypeImage/Video/Prompt for result.MediaType - Reuse BillingModeToken/BillingModeImage for billing mode - Reuse BillingModelSourceChannelMapped/PlatformAnthropic in handler
-
erio authored
- clearCreditsExhausted: sync Redis scheduler cache after DB update - Image billing mode UI: write to per_request_price instead of image_output_price - OpenAI RecordUsage: use BillingModelSourceRequested constant, add s.cfg nil guard - Fix i18n key path: admin.channels.perRequestPriceRequired → admin.channels.form.perRequestPriceRequired
-
erio authored
-
erio authored
- Fix errcheck: defer rows.Close() with nolint - Fix errcheck: type assertion with ok check in channel cache - Fix staticcheck ST1005: lowercase error string - Fix staticcheck SA5011: nil check cost before use in openai gateway - Fix gofmt: format chatcompletions_to_responses.go
-
erio authored
- Parse candidatesTokensDetails from Gemini API to separate image/text output tokens - Add image_output_tokens and image_output_cost to usage_log (migration 089) - Support per-image-token pricing via output_cost_per_image_token from model pricing data - Channel pricing ImageOutputPrice override works in token billing mode - Auto-fill image_output_price in channel pricing form from model defaults - Add "channel_mapped" billing model source as new default (migration 088) - Bills by model name after channel mapping, before account mapping - Fix channel cache error TTL sign error (115s → 5s) - Fix Update channel only invalidating new groups, not removed groups - Fix frontend model_mapping clearing sending undefined instead of {} - Credits balance precheck via shared AccountUsageService cache before injection - Skip credits injection for accounts with insufficient balance - Don't mark credits exhausted for "exhausted your capacity on this model" 429s -
erio authored
- 渠道模型映射:支持精确匹配和通配符映射,按平台隔离 - 渠道模型定价:支持 token/按次/图片三种计费模式,区间分层定价 - 模型限制:渠道可限制仅允许定价列表中的模型 - 计费模型来源:支持 requested/upstream 两种计费模型选择 - 用量统计:usage_logs 新增 channel_id/model_mapping_chain/billing_tier/billing_mode 字段 - Dashboard 支持 model_source 维度(requested/upstream/mapping)查看模型统计 - 全部 gateway handler 统一接入 ResolveChannelMappingAndRestrict - 修复测试:同步 SoraGenerationRepository 接口、SQL INSERT 参数、scan 字段
-
erio authored
- 4个缺失handler入口添加渠道映射+限制检查(ChatCompletions/Responses/Gemini) - 模型限制错误信息优化,区分"模型不可用"和"无账号" - OpenAI RecordUsage RequestedModel 改用 OriginalModel - ResolveChannelMappingAndRestrict/ReplaceModelInBody 抽取到 ChannelService 消除跨service重复 - validateNoDuplicateModels 按 platform:model 去重 - 删除 Channel.ResolveMappedModel 死代码和 CalculateCostWithChannel Deprecated方法 - 移除冗余nil检查,抽取 validatePricingBillingMode 公共校验
-
erio authored
- 抽取 ResolveChannelMappingAndRestrict 统一入口(5处→1个方法) - 抽取 BuildModelMappingChain 到 ChannelMappingResult 方法(5处→1行调用) - OpenAI 三入口 Forward 前应用渠道映射到请求体 - OpenAI Responses/Messages 限制检查添加错误响应 - 清理前端 3 处 console.log 调试日志
-
erio authored
- 定价查找支持通配符(suffix *),最长前缀优先匹配 - 模型限制(restrict_models)同样支持通配符匹配 - OpenAI 网关接入渠道映射/BillingModelSource/模型限制 - 按次/图片计费模式创建时强制要求价格或层级(前后端) - 用户使用记录列表增加计费模式 badge 列
-
erio authored
- GatewayService/OpenAIGatewayService 注入 ModelPricingResolver - RecordUsage 从旧路径迁移到 CalculateCostUnified(支持 per_request/image 模式) - 无渠道时自动回退旧路径,保持原有行为 - 长上下文双倍计费仅在无渠道定价时生效 - CostBreakdown 新增 BillingMode 字段,使用日志记录实际计费模式 - 模型限制错误改为与"无可用账号"相同的 503 响应
-
erio authored
- DB: usage_logs 表新增 billing_mode VARCHAR(20) 列 - 后端: RecordUsage 写入时根据 image_count 判定计费模式 - 前端: 使用记录表格新增计费模式 badge 列 + 筛选下拉
-
- 01 Apr, 2026 1 commit
-
-
YanzheL authored
When no explicit session signals (session_id, conversation_id, prompt_cache_key) are provided, derive a stable session seed from the request body content (model + tools + system prompt + first user message) to enable sticky routing and prompt caching for non-Codex clients using the Chat Completions API. This mirrors the content-based fallback already present in GatewayService. GenerateSessionHash, adapted for the OpenAI gateway's request formats (both Chat Completions messages and Responses API input). JSON fragments are canonicalized via normalizeCompatSeedJSON to ensure semantically identical requests produce the same seed regardless of whitespace or key ordering. Closes #1421
-
- 31 Mar, 2026 1 commit
-
-
YanzheL authored
-
- 30 Mar, 2026 1 commit
-
-
qingyuzhang authored
-
- 28 Mar, 2026 1 commit
-
-
wucm667 authored
当账号配置了模型映射(如 claude-sonnet-4-6 → glm-5.0)时,系统错误地 使用映射后的上游模型名计算费用。由于上游模型(如 glm-5.0)在定价系统中 没有价格配置,导致计费失败后被静默置为 0,用户不被扣费。 修改 forwardResultBillingModel 优先返回请求模型名,并移除 OpenAI 路径 中 BillingModel 字段对计费模型的覆盖逻辑。
-
- 24 Mar, 2026 1 commit
-
-
InCerry authored
-
- 23 Mar, 2026 1 commit
-
-
qingyuzhang authored
-
- 22 Mar, 2026 1 commit
-
-
Wang Lvyuan authored
-
- 20 Mar, 2026 1 commit
-
-
Ethan0x0000 authored
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent ) Co-authored-by:
Sisyphus <clio-agent@sisyphuslabs.ai>
-