- 13 Apr, 2026 11 commits
-
-
shaw authored
-
Wesley Liddick authored
fix(sidebar): prevent version update dropdown clipping
-
Wesley Liddick authored
fix(gateway): 兼容 Cursor /v1/chat/completions 的 Responses API body
-
Wesley Liddick authored
fix(frontend): reduce account usage request fan-out on pagination
-
Wesley Liddick authored
fix(frontend): lower QR code error correction level to reduce density
-
Wesley Liddick authored
fix(payment): register Alipay/Wxpay providers for base payment types
-
Wesley Liddick authored
fix: anthropic 非流式路径丢失 delta 内容(镜像 b2e379cf)
-
knowsky404 authored
-
sakurawztlt authored
b2e379cf 引入的 BufferedResponseAccumulator 已修复了 chat_completions 非流式路径和 responses OAuth 非流式路径,但遗漏了 Anthropic /v1/messages 非流式路径 (handleAnthropicBufferedStreamingResponse)。 当客户端请求 stream=false 且模型开启思考时,上游 response.completed 终态事件的 output 字段可能为空,实际 message 内容通过 response.output_text.delta 增量事件下发。旧代码只读终态事件的 Response, 导致客户端收到的 content 字段为空 ([{"type":"text"}])。 本 commit 将 b2e379cf 的相同修复模式镜像到 Anthropic 路径:在 SSE 扫描 过程中用 BufferedResponseAccumulator 累积 delta 内容,终态 output 为空 时通过 SupplementResponseOutput 补充重建。 同时修复 handleAnthropicBufferedStreamingResponse 遗漏 response.done 事件类型的问题,与 chat completions 路径保持一致,避免上游发送 response.done 时 handler 认不出终态事件、最终返回 502 的潜在问题。 BufferedResponseAccumulator 已在 chatcompletions_responses_test.go 有 完整单元测试覆盖(TextOnly/ToolCalls/Reasoning/Mixed/SupplementEmpty/ NoSupplementWhenOutputExists/EmptyDeltas/IgnoresNonFunctionCallItems), 本次复用相同累加器无需新增测试。
-
erio authored
Closes #1607
-
erio authored
fix(payment): fix Alipay/Wxpay direct provider type mapping and enable cross-provider load balancing Two issues fixed: 1. Alipay.SupportedTypes() returned ["alipay_direct"] and Wxpay returned ["wxpay_direct"], but the frontend sends payment_type="alipay"/"wxpay". The registry lookup failed with "payment method (alipay) is not configured". Fix: return the base types ["alipay"]/["wxpay"]. 2. When multiple providers support the same payment type (e.g. EasyPay and Alipay direct both handle "alipay"), only the last-registered provider's instances were reachable — the registry mapped one type to one provider key, and SelectInstance queried by that single key. Fix: bypass the registry in invokeProvider and let SelectInstance query across all providers when providerKey is empty. The selected instance's own ProviderKey (now included in InstanceSelection) is used to create the correct provider, enabling true cross-provider load balancing. Closes #1592
-
- 12 Apr, 2026 10 commits
-
-
qingyuzhang authored
-
qingyuzhang authored
-
github-actions[bot] authored
-
shaw authored
-
shaw authored
-
Wesley Liddick authored
fix: handle Anthropic credit balance exhausted (400) as account error
-
Wesley Liddick authored
fix(sidebar): smooth sidebar collapse behavior
-
Wesley Liddick authored
fix(frontend): 补全 messages 调度国际化文案
-
Wesley Liddick authored
docs(payment): add built-in payment configuration guide and settings links
-
bot authored
When an Anthropic API key's credit balance is depleted, the upstream returns HTTP 400 with message containing "credit balance". Previously, the 400 handler only checked for "organization has been disabled", so credit-exhausted accounts kept being scheduled — every request returned the same error. Treat this case identically to 402 (Payment Required): call handleAuthError → SetError to stop scheduling the account until an admin manually recovers it after topping up credits. Closes #1586
-
- 11 Apr, 2026 19 commits
-
-
qingyuzhang authored
# Conflicts: # frontend/src/components/layout/AppSidebar.vue
-
shuanbao0 authored
在前一个 commit 的 isResponsesShape 短路路径基础上,补充对 Cursor 云端 带过来的、Codex 上游统一不支持的顶层 Responses API 参数的剥离: - prompt_cache_retention - safety_identifier - metadata - stream_options 根因补充:这条 raw-body 透传路径为了保留 Cursor 的 input 数组整体结构, 不再经过 ChatCompletionsRequest 的反序列化过滤,所以这些 Go 结构体里 没有对应字段的参数会被原样发到上游,上游返回: Unsupported parameter: <field> 常规 Chat Completions 转换路径天然通过 ChatCompletionsRequest 丢弃未知字段, 不受影响;此处仅在 isResponsesShape 分支内用 sjson.DeleteBytes 显式过滤, 作用域最小。剥离列表与 openai_gateway_service.go:2034 的 unsupportedFields 语义对齐。 另外在 applyCodexOAuthTransform 的 OAuth 兜底 strip 列表里同步追加 prompt_cache_retention,作为对该函数所有其他 OAuth 调用点的 defense in depth(当前只有 Cursor 路径的短路已在前面剥过,但保留这一层更稳)。 测试: - TestCursorMixedShape_StripsUnsupportedFields — 验证所有 4 个字段都被剥 - TestApplyCodexOAuthTransform_StripsPromptCacheRetention — OAuth 兜底路径 Co-Authored-By:Claude Opus 4.6 (1M context) <noreply@anthropic.com>
-
erio authored
-
erio authored
-
erio authored
-
erio authored
-
erio authored
-
erio authored
-
erio authored
- Fix webhook URLs: /payment/webhook/<provider> not /payment/<provider>/notify - Remove notifyUrl/returnUrl from provider config tables (auto-generated by UI) - Adjust wxpay publicKeyId/certSerial to match frontend optional marking
-
erio authored
- Add docs/PAYMENT.md and docs/PAYMENT_CN.md with full payment setup guide - Mark Sub2ApiPay as deprecated in ecosystem tables (payment is now built-in) - Add built-in payment system to features list in all 3 READMEs
-
shuanbao0 authored
Cursor 云端 (User-Agent: Go-http-client/2.0) 发往 /v1/chat/completions 的 body 使用 Responses API 格式: {"model":"gpt-5.4","input":[{"role":"system","content":"..."}],"stream":true} 原代码用 ChatCompletionsRequest 反序列化,该结构体没有 Input 字段, Cursor 的 input 数组被静默丢弃,ChatCompletionsToResponses 转换后产出 input: null,Codex 上游以 "Invalid type for 'input': expected a string, but got an object" 拒绝请求(上游 typeof null === 'object')。 修复:在 ForwardAsChatCompletions 里用 gjson 检测 body shape,当 input 存在且 messages 缺失时,跳过 Chat→Responses 转换,用 sjson 仅改写 model 字段后原样透传 body。billing 所需的 ServiceTier 和 Reasoning.Effort 通过 gjson 从 raw body 提取,下游 codex OAuth transform 路径保持不变。 测试:新增 openai_cursor_warmup_pipeline_test.go,覆盖 5 个 shape 检测 用例(正向/标准请求不误伤/两字段共存/空 body/JSON 回读)。 Co-Authored-By:Claude Opus 4.6 (1M context) <noreply@anthropic.com>
-
Wesley Liddick authored
feat(payment): add complete payment system with multi-provider support
-
erio authored
-
erio authored
# Conflicts: # frontend/src/api/admin/settings.ts # frontend/src/stores/app.ts # frontend/src/types/index.ts # frontend/src/views/admin/SettingsView.vue
-
erio authored
Upstream removed sora feature (090_drop_sora.sql) but left i18n keys and wire.go references. Clean up: - Remove entire sora i18n block from en.ts and zh.ts (~190 lines) - Remove sora nav key and unused 'data' settings tab key - Remove sora_client_enabled from settings (fork-specific) - Remove SoraMediaCleanupService from wire.go
-
erio authored
The API client's error interceptor was dropping the reason and metadata fields from backend error responses. This caused PaymentView to miss specific error codes (TOO_MANY_PENDING, CANCEL_RATE_LIMITED) and fall back to generic error messages.
-
erio authored
-
erio authored
Stripe payment path was setting expiresAt to empty string, causing PaymentStatusPanel to fall back to hardcoded 30-minute default when the popup redirect switches to the waiting view.
-
Wesley Liddick authored
fix: 修复多个 UI 和功能问题 - 表格排序搜索、导出逻辑、分页配置和状态筛选
-