- 08 Apr, 2026 5 commits
-
-
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
-
当上游返回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>
-
上游API近期更新后,response.completed终态SSE事件的output字段可能为空, 实际内容仅通过response.output_text.delta等增量事件下发。流式路径不受影响, 但chat_completions非流式路径和responses OAuth非流式路径只依赖终态事件的 output,导致返回空响应。 新增BufferedResponseAccumulator累积器,在SSE扫描过程中收集delta事件内容 (文本、function_call、reasoning),当终态output为空时补充重建。 同时修复handleChatBufferedStreamingResponse遗漏response.done事件类型的问题。
-
-
- 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 列 + 筛选下拉
-
- 03 Apr, 2026 1 commit
-
-
陈曦 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>
-
- 17 Mar, 2026 1 commit
-
-
Ethan0x0000 authored
Propagate UpstreamModel through ForwardResult and OpenAIForwardResult in Anthropic direct, API-key passthrough, Bedrock, and OpenAI gateway flows. Extract optionalNonEqualStringPtr and optionalTrimmedStringPtr into usage_log_helpers.go. Store upstream_model only when it differs from the requested model. Also introduces anthropicPassthroughForwardInput struct to reduce parameter count.
-
- 16 Mar, 2026 1 commit
-
-
QTom authored
根因:多个用户共享同一 OAuth 账号时,conversation_id/session_id 头 未做用户隔离,导致上游 chatgpt.com 将不同用户的请求关联到同一会话。 HTTP SSE 修复: - 新增 isolateOpenAISessionID(apiKeyID, raw),将 API Key ID 混入 session 标识符(xxhash),确保不同 Key 的用户产生不同上游会话 - buildUpstreamRequest: OAuth 分支先 Del 客户端透传的 session 头, 再用隔离值覆盖 - buildUpstreamRequestOpenAIPassthrough: 透传路径同样隔离 - ForwardAsAnthropic: Anthropic Messages 兼容路径同步修复 - buildOpenAIWSHeaders: WS 路径的 OAuth session 头同步隔离
-
- 15 Mar, 2026 2 commits
-
-
erio authored
- Add 5th error filter switch IgnoreInsufficientBalanceErrors to suppress upstream insufficient balance / insufficient_quota errors from ops log - Extract hardcoded error strings into package-level constants for shouldSkipOpsErrorLog, normalizeOpsErrorType, classifyOpsPhase, and classifyOpsIsBusinessLimited - Define ErrNoAvailableAccounts sentinel error and replace all errors.New("no available accounts") call sites - Update tests to use require.ErrorIs with the sentinel error -
Ethan0x0000 authored
将入站、上游与路径三类端点分布统一到使用记录页的一致化卡片交互中,并补齐端点元数据与统计链路,提升排障与流量分析效率。
-
- 14 Mar, 2026 1 commit
-
-
InCerry authored
-
- 12 Mar, 2026 1 commit
-
-
ius authored
-
- 11 Mar, 2026 6 commits
-
-
CoolCoolTomato authored
-
shaw authored
将 /v1/chat/completions 端点从 ResponseWriter 劫持模式重构为独立的 类型安全转换路径,与 Anthropic Messages 端点架构对齐: - 在 apicompat 包新增 Chat Completions 完整类型定义和双向转换器 - 新增 ForwardAsChatCompletions service 方法,走 Responses API 上游 - Handler 改为独立的账号选择/failover 循环,不再劫持 Responses handler - 提取 handleCompatErrorResponse 为 Chat Completions 和 Messages 共用 - 删除旧的 forwardChatCompletions 直传路径及相关死代码
-
CoolCoolTomato authored
-
ius authored
-
ius authored
-
7976723 authored
基于 @yulate 在 PR #648 (commit 0bb6a392) 的工作,解决了与最新 main 分支的合并冲突。 原始功能(@yulate): - 添加 /v1/chat/completions 和 /chat/completions 兼容端点 - 将 Chat Completions 请求转换为 Responses API 格式并转换回来 - 添加 API Key 直连转发支持 - 包含单元测试 Co-authored-by:yulate <yulate@users.noreply.github.com>
-
- 09 Mar, 2026 1 commit
-
-
kyx236 authored
1. 识别OpenAI "An error occurred while processing your request" 临时性400错误 并触发failover,同时在池模式下标记RetryableOnSameAccount,允许同账号重试 2. ForwardAsAnthropic路径同步支持临时性400错误的识别和同账号重试 3. HelpTooltip组件使用Teleport渲染到body,修复在dialog内被裁切的问题
-