Commit Graph
3758 Commits
Author SHA1 Message Date
Wesley Liddick 1b4029b050 Merge pull request #4595 from kinsolee/fix/http-bridge-failover-terminal-safety
fix(openai): make HTTP bridge failover safe
2026-07-20 10:29:00 +08:00
Wesley Liddick 139a3d4346 Merge pull request #4589 from huangjunsen0406/fix/anthropic-message-start-stop-reason-null
fix(apicompat): emit null stop_reason on Anthropic message_start
2026-07-20 10:28:52 +08:00
Wesley Liddick 8c9cda1803 Merge pull request #4583 from BenjaminAaron196/codex/ops-report-email-template
(feat) 运维定时报表支持可编辑摘要模板与多语言展示
2026-07-20 10:28:44 +08:00
Wesley Liddick 0a8831777b Merge pull request #4619 from superman2003/fix/grok-manual-test-scheduling-gate
fix(grok): let manual connection tests bypass the scheduling gate
2026-07-20 10:26:55 +08:00
Wesley Liddick 34c8dbd604 Merge pull request #4618 from superman2003/fix/system-update-detach-request-ctx
fix(update): detach in-place update from the HTTP request lifetime
2026-07-20 10:26:47 +08:00
Wesley Liddick e311d368d3 Merge pull request #4611 from superman2003/fix/codex-models-manifest-401-unschedulable
fix(openai): mark OAuth accounts unschedulable on Codex models manifest 401
2026-07-20 10:26:39 +08:00
Wesley Liddick f133fde643 Merge pull request #4602 from jianjianai/new/perf-responses-image-intent
perf(openai): 复用 Responses 生图意图判定
2026-07-20 10:26:31 +08:00
Wesley Liddick c0b8f6b0a8 Merge pull request #4601 from jianjianai/new/perf-responses-sse-type
perf(openai): 复用 Responses SSE 事件类型解析
2026-07-20 10:26:23 +08:00
Wesley Liddick 9ccc9077cc Merge pull request #4581 from wucm667/feat/issue-4375-github-release-token
feat: support GitHub token for update checks
2026-07-20 10:26:15 +08:00
Wesley Liddick f5e484aa70 Merge pull request #4625 from wucm667/fix/issue-4624-sticky-force-cache-billing
fix(handler): avoid cache billing on same-account retry
2026-07-20 10:24:38 +08:00
Wesley Liddick 032001598a Merge pull request #4617 from wucm667/fix/issue-4610-anthropic-json-content-type
fix(openai): correct buffered messages content type
2026-07-20 10:24:22 +08:00
Wesley Liddick 6def36a171 Merge pull request #4614 from cugxuan/codex/fix-subscription-expiry-days
fix(subscription): round remaining days up
2026-07-20 10:24:14 +08:00
shaw 2518691dbc fix(config): 为 trusted_proxies 与 forwarded_client_ip_headers 注册 BindEnv,修复 env 可达性守卫测试
#4593 引入的 TestConfigKeysAreEnvReachable 与 #4604 新增的两个配置键语义相撞:
两键在 setDefaults 中无注册,守卫测试判定其环境变量不可达。

不能按守卫注释直接 SetDefault:viper 的 IsSet 会连同 defaults 一起上报,
任何已注册默认值都会让 load() 中 trustedProxiesConfigured 的显式配置探测
永远为真,摧毁 #4600 的 absent/empty 区分。改用 BindEnv 注册——绑定键同样
进入 AllKeys()(守卫测试与 Unmarshal 均可见),而变量缺席时不影响 IsSet。
两个环境变量本就由 load() 中 os.LookupEnv 手工解析,行为不变。
2026-07-20 09:41:02 +08:00
Wesley Liddick bfabfe60c8 Merge pull request #4593 from StarryKira/fix/image-storage-env-unreachable
fix: 异步生图开关配了却不生效(环境变量被静默丢弃 + 迁移到后台开关)
2026-07-20 09:20:15 +08:00
wucm667 a2acbf553b fix(handler): avoid cache billing on same-account retry 2026-07-20 02:20:58 +08:00
JlypxandSisyphus dd0cbe91c9 fix: 避免复制客户端 IP 原子状态
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:22:45 +08:00
JlypxandSisyphus ff5b0e6254 test: 更新客户端 IP 设置响应契约
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:09:47 +08:00
JlypxandSisyphus fedeba2568 feat: 审计客户端 IP 请求头变更
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:09:37 +08:00
JlypxandSisyphus 3c86e249f4 feat: 接入客户端 IP 请求头管理接口
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:09:21 +08:00
JlypxandSisyphus f72958d530 feat: 持久化客户端 IP 请求头设置
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:09:11 +08:00
JlypxandSisyphus 8b8b6b3132 feat: 定义客户端 IP 请求头系统设置
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:09:00 +08:00
JlypxandSisyphus 9bc7d10c08 fix: 快照自定义客户端 IP 请求头
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:08:48 +08:00
JlypxandSisyphus 496005d688 fix: 按自定义请求头解析客户端 IP
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:08:36 +08:00
JlypxandSisyphus 041db5d824 feat: 支持自定义客户端 IP 请求头配置
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-20 00:08:26 +08:00
superman2003 4a97491be6 fix(grok): let manual connection tests bypass the scheduling gate
Grok OAuth 'test connection' reused the production GrokTokenProvider
request path, whose eligibility gate rejects any account that is not
currently schedulable (manual switch off, rate limited, overloaded,
temporarily cooled down). Every such test failed before reaching xAI
with the generic 'oauth refresh account state changed', while
Codex/OpenAI account tests read credentials regardless of scheduling
state (#4598).

Add GetAccessTokenForManualTest and use it from the account test
service:

- skips the request-path scheduling eligibility gate so admins can
  probe excluded accounts; credential integrity checks (configured
  proxy present, refresh token present) still apply
- refreshes expired tokens through the shared OAuthRefreshAPI without
  the request-path marker, so the lock protocol and DB re-read keep
  working while scheduling state no longer blocks the refresh;
  credential rotation for non-active accounts stays blocked inside
  RefreshIfNeeded
- falls back to the still-valid current token when a refresh attempt
  fails or another worker holds the refresh lock, and otherwise
  surfaces the concrete refresh error instead of the generic message

Fixes #4598
2026-07-19 22:40:58 +08:00
superman2003 35b5edb24c fix(update): detach in-place update from the HTTP request lifetime
The in-place update ran entirely inside c.Request.Context(). Browsers and
reverse proxies commonly abort long-idle requests (axios global timeout
30s, nginx proxy_read_timeout 60s by default), which canceled the request
context mid-download and killed every slow update with
'download failed: context canceled' while the version stayed unchanged.
Users behind slow GitHub links saw the update button fail at a wall-clock
ceiling (~60s) on every attempt (#4504).

- Run PerformUpdate and RollbackToVersion on a context detached from the
  request (context.WithoutCancel) and bounded by a 15-minute deadline so
  the 10-minute GitHub download client owns its own timeout. A client
  disconnect no longer aborts the binary swap; retries then hit the
  system operation lock or report 'Already up to date'.
- Raise the frontend timeout for the update/rollback calls from the
  global 30s axios default to 15 minutes so the browser can actually
  wait for the result.

Fixes #4504
2026-07-19 22:40:44 +08:00
wucm667 01062c3244 fix(openai): correct buffered messages content type 2026-07-19 22:28:49 +08:00
JlypxandSisyphus 93717394b2 fix: 迁移客户端 IP 兼容开关
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-19 21:41:45 +08:00
JlypxandSisyphus 6aa6b3a968 fix: 将客户端 IP 模式注入请求上下文
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-19 21:41:12 +08:00
JlypxandSisyphus 39107ca457 fix: 安全初始化 Gin 可信代理
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-19 21:40:32 +08:00
JlypxandSisyphus 6e2ba0e4cd fix: 统一请求级客户端 IP 模式
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-19 21:39:49 +08:00
JlypxandSisyphus 8a147fcc51 fix: 解析显式可信代理配置
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-19 21:39:24 +08:00
cugxuan d0fa8c63f1 fix(subscription): round remaining days up 2026-07-19 21:37:26 +08:00
superman2003andCursor 3ed2873f14 fix(openai): mark OAuth accounts unschedulable on Codex models manifest 401
The Codex models manifest path returned upstream 401s straight to the
client without feeding them into the account state machinery. A revoked
or invalidated OAuth account therefore stayed active and schedulable,
kept being selected for subsequent /models requests, and produced
repeated 502s until an admin ran a manual connection test (#4544).

- Route ChatGPT-backend manifest 401s through the shared upstream-error
  handling: token cache invalidation, temp-unschedulable cooldown for
  refreshable OAuth accounts, permanent disable for
  token_revoked/token_invalidated, plus the runtime scheduling block.
- Treat ChatGPT-backend manifest 401s as failover-eligible so the
  current /models request can switch to a healthy account instead of
  returning 502. Custom API key upstream 401s keep the existing
  no-failover, no-disable behavior since their /models auth is not
  authoritative for the account.
- Skip Agent Identity accounts: their 401s can be task-scoped and have
  a dedicated recovery flow.
- Attach the selected account to the ops error-log context so /models
  failures record the account_id.

Fixes #4544

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 21:13:27 +08:00
Jlypx 732aeef880 fix: 兼容反代和 Docker 客户端 IP 解析 2026-07-19 19:41:01 +08:00
jjaw f7979ae8ff 优化 Responses SSE 事件类型解析 2026-07-19 18:50:33 +08:00
jjaw 8fd6f91b7e 优化 Responses 生图意图复用 2026-07-19 18:49:08 +08:00
Kinso 7840eb1c49 [verified] fix(openai): make HTTP bridge failover safe
Route first-turn pre-response transport, HTTP, and SSE failures through the existing account failover path without replaying later turns. Require a real Responses terminal event and preserve platform-specific OpenAI/Grok error side effects.
2026-07-19 17:13:27 +08:00
harukaandClaude Opus 4.8 6102d64274 fix(wire): 补上 PromptAdminService 的绑定,恢复 wire 代码生成
ProviderSet 提供了 NewPromptAdminHandler,也绑定了 PromptEngine,却没有为
PromptAdminService 绑定实现,导致 go generate ./cmd/server 直接失败:

  no provider found for securityaudit.PromptAdminService
  needed by *securityaudit.PromptAdminHandler

*PromptService 本就实现了该接口的全部方法,wire_gen.go 也一直是手工维护到位的
(补上绑定后重新生成的结果与现有文件逐字节一致),只是生成这条路被堵死了,
后续任何依赖改动都无法再靠 go generate 同步。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHreE5pzCkSYz7J45fmd2Y
2026-07-19 01:03:41 -07:00
harukaandClaude Opus 4.8 b08cab91a9 feat(image-storage): 异步生图对象存储改为后台配置,保存即生效
此前开启异步生图必须改服务器上的 config.yaml 并重启容器(#4542),且若想
复用已配置的备份 S3,还得把同一套凭证再填一遍(#4458)。

- 新增 ImageStorageSettingService:配置存 settings 表,SecretAccessKey 经
  SecretEncryptor 加密落库、读回脱敏、留空表示沿用旧值,与备份 S3 配置同一套做法。
- reuse_backup_s3(默认开)直接借用 backup_s3_config 的端点与密钥,只用自己的
  bucket/prefix 区分对象,因此备份走 backups/、图片走 images/,且密钥不会在库里存两份。
- ImageTaskService 的启用状态改由 ImageStorageResolver 在运行时解析并缓存,
  保存设置后 Invalidate 使下次请求重建客户端——不再需要重启。
- repository 侧由提供实例改为提供工厂,客户端才可能在运行期重建。
- 轮询接口的门控从 enabled() 放宽为 Pollable():关掉开关只拒绝新提交,
  已受理的任务仍可取回结果,不再被中途吞掉。
- config.yaml 的 image_storage 保留为回落,后台从未保存过时沿用,
  升级前已用配置文件开启的部署不受影响。
- 管理端 GET/PUT/POST /admin/backups/image-storage,PUT 与备份 S3 配置一样要求
  step-up 2FA:改写存储目标同样能把生成内容导向外部账号。

注:go generate ./cmd/server 在当前 upstream 基线上即失败(securityaudit.
PromptAdminService 缺 provider),故 wire_gen.go 为手工同步。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHreE5pzCkSYz7J45fmd2Y
2026-07-19 00:56:21 -07:00
huangjunsen ba2b0044e3 fix(apicompat): emit null stop_reason on Anthropic message_start
Use *string for AnthropicResponse.StopReason so streaming message_start
serializes as JSON null instead of "", matching official Anthropic wire
format and avoiding strict client turn-finalization failures.
2026-07-19 13:05:24 +08:00
Jlypx 2cff4bf169 fix: 修复 golangci-lint 检查错误 2026-07-19 11:39:20 +08:00
Jlypx 361983cf4d feat: 优化运维定时报表邮件模板 2026-07-19 11:23:26 +08:00
wucm667 510ee451bd feat: support GitHub token for update checks 2026-07-19 11:02:56 +08:00
github-actions[bot] d4b9797ff7 chore: sync VERSION to 0.1.161 [skip ci] 2026-07-18 14:18:28 +00:00
Wesley Liddick 19149ca196 Merge pull request #4558 from fengshao1227/fix/antigravity-plan-type-preserve
fix(antigravity): 保留付费 tier 的 PlanType,IneligibleTiers 仅标记异常状态
2026-07-18 21:48:44 +08:00
Wesley Liddick 831812b39d Merge pull request #4556 from superman2003/fix/grok-free-probe-encrypted-recovery
fix(grok): stabilize Free probes and encrypted reasoning recovery
2026-07-18 21:48:31 +08:00
li 72b29a7d4e fix(antigravity): 保留付费 tier 的 PlanType,IneligibleTiers 仅标记异常状态
Fixes #4519
2026-07-18 21:43:54 +08:00
shaw 14608dc6d4 Merge origin/main into codex/secure-protected-video-content-4498
Reconcile with #4539 (grok media account model mapping), now on main:
- handler/grok_media.go non-failover error path keeps both changes —
  #4539's grokMediaScheduleModel(account, routingModel, nil) schedule
  attribution and this branch's IsResponseCommitted guard
- auto-merged sections verified: routing/classify use #4539's routingModel,
  video lookup owner-binding and no-failover semantics intact, ForwardGrokMedia
  keeps mapping block (skipped for lookup endpoints via RequiresRequestBody),
  empty-image failover, and video-status URL rewrite in order
2026-07-18 21:38:17 +08:00
shaw 8a95a46a69 Merge origin/main into codex/secure-protected-video-content-4498
Resolve conflicts with main:
- service/grok_media.go: keep both post-response blocks — #4497's empty
  image-output failover (main) runs first for image endpoints, then this
  branch's video-status content-URL rewrite; the endpoint conditions are
  mutually exclusive
- handler/openai_gateway_credential_failover_loop_test.go: mark the stub
  OAuth accounts media-eligible via the grok_media_eligible extra override,
  because this branch moved grok media failover coverage to the generation
  endpoint, which is now gated by #4540's paid-eligibility probe on main
2026-07-18 21:31:28 +08:00