Commit Graph
4871 Commits
Author SHA1 Message Date
Wesley Liddick a2779cd5f3 Merge pull request #4428 from alfadb/fix/anthropic-haiku-full-mimicry
fix(gateway): 修复 Haiku OAuth 请求被归入额外用量
v0.1.157
2026-07-16 16:55:11 +08:00
Wesley Liddick dbef64bb45 Merge pull request #4427 from yan9651688/feat/channel-monitor-one-click-copy
feat(channel-monitor): add safe one-click duplication
2026-07-16 16:54:22 +08:00
Wesley Liddick 3ecfcc48ae Merge pull request #4429 from Wei-Shaw/feat/role-stepup-admin-2fa-password
feat(security): 角色提升纳入 step-up 2FA + 管理员 2FA 密码验证 + 审计日志页优化
2026-07-16 16:53:51 +08:00
shaw 35748d8c51 feat(security): gate admin role promotion behind step-up 2FA and harden admin TOTP verification
- 提升用户为管理员 / 创建管理员账号纳入敏感操作:handler 级 EnforceStepUp 门控
  (admin API key 拒绝、未启用 TOTP 拒绝、无 grant 返回 STEP_UP_REQUIRED),
  目标已是管理员的日常编辑不触发
- 管理员启用/停用 2FA 一律使用密码验证(默认通知邮箱常收不到验证码),
  verification-method 按用户角色返回;普通用户行为不变
- 用户编辑/创建弹窗接入 useStepUp:命中 STEP_UP_REQUIRED 弹 TOTP 验证并自动重试
- 审计日志清理入口与其他敏感操作对齐:未启用 2FA 时直接提示先启用 TOTP,
  不再弹出无法完成的验证码输入框(后端强制现场 TOTP 语义不变)
- 审计日志页重构:DataTable 布局、详情弹窗分区展示、时间范围改为 ops 同款
  下拉(预设窗口 + 自定义起止支持时分)
2026-07-16 16:49:08 +08:00
yan9651688 e2e375d694 Make repeated channel-monitor setup safer
Admins often recreate monitors with the same endpoint, model, and request settings. A server-side duplicate keeps the stored API key out of the browser, creates a disabled copy for review, and uses stable operation identity to recover ambiguous retries without creating extra rows.

Constraint: Stored monitor API keys must never be returned to the browser
Constraint: Applying a request template must preserve internal duplicate recovery metadata
Rejected: Rebuild the monitor from list data | list responses only contain a masked API key
Rejected: Copy runtime state and history | a duplicate should start as an unverified configuration
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep duplicated monitors disabled until an administrator reviews and enables them
Tested: Go unit tests for repository, service, and admin handler; integration-tag compile; go vet; golangci-lint v2.9; frontend Vitest, ESLint, typecheck, production build; Playwright duplicate flow
Not-tested: PostgreSQL container integration locally because Docker is unavailable; CI will execute the database-backed suite
2026-07-16 16:30:19 +08:00
alfadb 1f5ee8123f fix(gateway): apply full Claude Code mimicry to Haiku 2026-07-16 15:45:22 +08:00
Wesley Liddick 393a8fe56a Merge pull request #4424 from StarryKira/fix/4417-responses-image-account-capability
fix(gateway): route image-intent /v1/responses only to Responses-capable accounts (#4417)
2026-07-16 15:35:45 +08:00
Wesley Liddick 09729ba54c Merge pull request #4406 from StarryKira/agent/fix-4326-async-image-object-storage
feat: 异步生图任务与结果轮询(重新引入 #4381)+ 结果落对象存储
2026-07-16 15:35:04 +08:00
shaw 590efe29a5 Merge remote-tracking branch 'origin/main' into agent/fix-4326-async-image-object-storage
# Conflicts:
#	backend/cmd/server/wire_gen.go
2026-07-16 15:32:38 +08:00
Wesley Liddick 813920607e Merge pull request #4418 from Wei-Shaw/feat/audit-log-and-credential-hardening
feat(security): 操作审计日志 + 会话IP/UA绑定 + 敏感操作 step-up 2FA
2026-07-16 15:27:13 +08:00
harukaandClaude Opus 4.8 605b026cc4 fix(gateway): route image-intent /v1/responses only to Responses-capable accounts (#4417)
For OpenAI-compatible API-key accounts, /v1/responses requests with
image-generation intent could be scheduled to accounts whose upstream
does not support the Responses API (extra.openai_responses_supported=false).
The flag was only consulted at forward time, where such accounts are
silently downgraded to a Chat-Completions path that cannot produce images,
causing upstream 4xx/5xx or canceled requests.

Fix:
- Add endpoint capability OpenAIEndpointCapabilityResponses. Its check in
  SupportsOpenAIEndpointCapability excludes only OpenAI API-key accounts
  probed as unsupported (mirroring the forward-time downgrade condition);
  OAuth/Grok/unprobed accounts keep existing behavior, and a responses-
  capable upstream must still pass the chat_completions gate. Reusing the
  existing requiredCapability plumbing makes every scheduler filter path
  enforce it with no scheduler signature changes.
- Request the responses capability at the HTTP Responses and
  ResponsesWebSocket call sites only when imageIntent && platform==openai,
  so non-image requests keep the downgrade path and Grok's own image path
  is untouched.
- Normalize max_tokens -> max_output_tokens on the native responses
  forward path (PlatformOpenAI), and strip prompt_cache_options alongside
  prompt_cache_retention/safety_identifier.

/v1/images/generations continues to use native image capability (unchanged).

Tests: capability truth table, scheduler exclusion of unsupported accounts,
and forward-path transform behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KXpzKKvsb5jW2GvgBQqnnZ
2026-07-16 00:23:40 -07:00
shaw 2d97207d41 fix(settings): 审计日志保留天数清空时回退默认值避免保存 400
audit_log_retention_days 用 v-model.number 绑定数字框,管理员清空输入框时
得到空串,后端 int 字段 ShouldBindJSON 解析空串失败返回 400,导致整次系统
设置保存被拒。payload 构建时对空/非法值回退默认 180(与后端
parseAuditLogRetentionDays("") 语义一致;显式 0 仍表示永久保留)。
2026-07-16 15:19:19 +08:00
shaw d67a2cad2b fix(lint): 检查 audit 键归一化中 WriteRune 返回值 (errcheck)
golangci-lint errcheck 报 audit_log.go:115 未检查 (*strings.Builder).WriteRune
返回值。Builder.WriteRune 永不返回错误,按仓库惯例以 _, _ = 显式丢弃。
2026-07-16 15:05:19 +08:00
shaw 2de6ccb071 fix(security): 补齐审计日志脱敏缺口 + step-up 下载/取消体验修复
审计发现修复:

高危——审计日志请求体脱敏不全(audit_logs 沦为明文凭证聚合点):
- 键名归一化比对(小写+去分隔符),覆盖 privateKey/apiv3key 等无分隔符与 camelCase 写法
- 程序化并入 SensitiveCredentialKeys 与 providerSensitiveConfigFields 两份权威敏感表,防清单漂移
- 补齐 proxy_key(内嵌代理密码)、custom_key(自设 API Key 明文)精确键
- Codex session 导入路由 body 整体由粘贴的 auth JSON 构成,键级脱敏无法覆盖,整体不入库
- 新增守卫测试:两份权威表的每个键必须被审计脱敏命中;provider_key 等渠道标识保留以便追责

中危——step-up 前端体验:
- 备份下载改同页 anchor 导航(预签名 URL 后端强制 attachment disposition),
  避免 step-up 弹窗 await 耗尽瞬态激活后 window.open 被浏览器拦截
- useStepUp.run 用户取消时抛 StepUpCancelledError sentinel,
  三个调用点静默处理,不再把取消误报为红色错误 toast

低危:
- 修正审计中间件挂载位置的陈旧注释(实际挂在认证之后)
- 审计 body 捕获改 LimitReader 按 256KB 上限截断读取,超出部分拼接回填,
  避免大体积导入请求被完整复制进内存两次
- TOTP step-up 弹窗验证成功后即时清空验证码输入
2026-07-16 14:38:16 +08:00
shaw a1af031969 fix(test): gofmt 审计日志测试 + 补齐 settings 契约 golden 两新字段
- audit_log_test.go: gofmt map 对齐
- api_contract_test.go: GET /admin/settings 两处 golden 补 session_binding_enabled/audit_log_retention_days
2026-07-16 13:58:50 +08:00
shaw 0ddd58aaf9 feat(security): 操作审计日志 + 会话IP/UA绑定 + 敏感操作 step-up 2FA
应对管理员访问凭证失守导致的数据外泄风险,新增三层防护:

审计日志(admin-only 可见,用户不可见)
- 新增 append-only audit_logs 表(migration 180)+ 异步批量写入 + 保留期清理
- 审计中间件挂在 admin/user/auth/admin-payment 组认证之后:记录所有变更类
  请求 + 白名单敏感读取(账号/代理导出、备份下载、admin/user API key 读取)
- 请求头凭证首尾掩码;请求体 JSON 递归脱敏(api_key/password 等擦除,base_url
  保留以便追责);非 JSON body 不入库
- 无单条删除;全量清空需现场 TOTP 校验、拒绝 admin API key、未启用 2FA 不允许,
  清空后同步写入留痕记录

会话 IP/UA 绑定(默认开启,可在系统设置关闭)
- JWT 携带 session id + IP/UA 指纹哈希;IP 或 UA 任一变化即撤销会话家族并要求
  重新登录;旧 token 无指纹时放行以平滑升级

敏感操作 step-up 2FA(sudo 窗口 15 分钟)
- 账号/代理导出、DB 备份创建/下载、S3 目标修改要求近期 TOTP 二次验证;admin API
  key 一律拒绝;前端 useStepUp 组合式 + TotpStepUpDialog 弹码后自动重试
- API key 查看按需求暂不加强管控

前端:新增 /admin/audit-logs 操作日志页面(筛选/详情/2FA 清空)、侧边栏入口、
step-up 弹窗接入导出与备份流程、安全设置项(绑定开关 + 日志保留天数)、zh/en i18n
2026-07-16 13:47:50 +08:00
harukaandClaude Opus 4.8 0eb6e21aaa feat: 异步图片任务结果落对象存储
为异步生图任务增加 S3 兼容对象存储支持,任务结果不再把大图内联存进 Redis:

- 新增可插拔接口 service.ImageStorage(Save -> url),适配别的厂商只需实现它
- S3 实现 S3ImageStorage(AWS S3 / R2 / 阿里云 OSS / MinIO),与备份共用 S3 客户端构造
- 新增 image_storage 配置(config.yaml + IMAGE_STORAGE_* 环境变量),默认关闭
- enabled 同时作为总开关:关闭或未配置对象存储时,异步生图接口返回 404 且不写
  Redis,从根上避免几 MB 的 b64_json 结果撑爆 Redis
- 完成时把图片上传对象存储并把结果改写为短链接(公开直链或 presigned),
  上传失败则任务标记为失败

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SM1tf3CFVRzC7guuhBXvMd
2026-07-15 19:57:37 -07:00
haruka e5e94d1eb1 docs: document async image task API 2026-07-15 19:57:37 -07:00
haruka 1fb942dd77 feat: add async image generation tasks 2026-07-15 19:57:37 -07:00
Wesley Liddick 09c6c6d740 Merge pull request #4387 from yardbirds0/feat/upstream-rate-scheduling
feat: 按上游计费倍率调度 OpenAI 账号
2026-07-16 10:46:29 +08:00
shaw 0408bdb34f Merge remote-tracking branch 'origin/main' into feat/upstream-rate-scheduling
# Conflicts:
#	backend/internal/handler/openai_gateway_handler.go
2026-07-16 10:31:21 +08:00
Wesley Liddick ab978e615e Merge pull request #4385 from yardbirds0/feat/upstream-billing-probe
feat: 增加上游 Sub2API 计费倍率探测与账号展示
2026-07-16 10:27:45 +08:00
Wesley Liddick 8d36ce3d20 Merge pull request #4108 from yardbirds0/feat/key-billing-info
feat: 增加 API Key 计费倍率自省接口
2026-07-16 10:27:35 +08:00
shaw e2bb90a80d fix(test): tls.peet.ws 站点故障时跳过 TLS 指纹集成测试
skipIfExternalServiceUnavailable 的不可用特征清单漏掉 EOF/connection
reset/broken pipe,站点半死返回空响应断开时测试走 Fatalf 导致 CI 必红。
补齐特征清单,并把读体失败、非 200 状态码、响应体非法 JSON 一并归为
外部服务不可用跳过;站点健康时指纹校验行为不变。
2026-07-16 09:51:41 +08:00
Wesley Liddick 08828293b7 Merge pull request #4404 from Wei-Shaw/revert-4381-agent/fix-4326-async-image-tasks
Revert "feat: 支持异步生图任务与结果轮询"
2026-07-16 09:48:09 +08:00
Wesley Liddick 502097026f Revert "feat: 支持异步生图任务与结果轮询" 2026-07-16 09:47:27 +08:00
Wesley Liddick a3a227c858 Merge pull request #4381 from StarryKira/agent/fix-4326-async-image-tasks
feat: 支持异步生图任务与结果轮询
2026-07-16 09:44:26 +08:00
Wesley Liddick 51f2b0e3ee Merge pull request #4382 from wp-a/fix/openai-responses-rejected-field-retries
[codex] retry explicitly rejected Responses fields
2026-07-16 09:37:36 +08:00
Wesley Liddick 531ae04a0b Merge pull request #4395 from wp-a/fix/openai-body-limit-failover
[codex] fail over account-specific OpenAI body limits
2026-07-16 09:33:48 +08:00
Wesley Liddick e4329a04e8 Merge pull request #4393 from superman2003/fix/grok-codex-compatibility
fix(grok): improve Codex compatibility and key setup
2026-07-16 09:33:20 +08:00
Wesley Liddick f3138ceb43 Merge pull request #4384 from wp-a/fix/openai-model-scoped-transient-cooldown
[codex] scope OpenAI transient cooldowns by model
2026-07-16 09:33:09 +08:00
Wesley Liddick 1c5c42c183 Merge pull request #4394 from siyuan-123/codex/pr-gpt56-pat-alpha-search
fix(openai): route PAT alpha search via responses web_search
2026-07-16 09:32:59 +08:00
Wesley Liddick 3fc0336e1d Merge pull request #4377 from wp-a/fix/openai-ws-ingress-lifecycle
[codex] close OpenAI WS ingress reads cleanly
2026-07-16 09:32:50 +08:00
Wesley Liddick 807850769f Merge pull request #4396 from StarryKira/fix/4386-image-input-pricing
fix(billing): 图像输入 token 按独立单价计费(gpt-image-2 图片编辑)
2026-07-16 09:32:29 +08:00
Wesley Liddick 8852194670 Merge pull request #4402 from wucm667/fix/issue-4399-oauth-image-usage
fix(openai): 修复 OAuth 生图工具用量计费
2026-07-16 09:32:18 +08:00
Wesley Liddick 4226ff8e3a Merge pull request #4392 from jianjianai/new/perf-bulk-account-platform-scope
perf(scheduler): 按平台收窄批量账户事件重建
2026-07-16 09:31:59 +08:00
Wesley Liddick ff08694d79 Merge pull request #4400 from jianjianai/new/perf-scheduler-payload-reuse
perf: 复用同批次调度快照账号载荷写入
2026-07-16 09:31:51 +08:00
Wesley Liddick 7e43ebc792 Merge pull request #4369 from wp-a/fix/openai-wsv2-malformed-json
[codex] reject malformed OpenAI WS v2 events
2026-07-16 09:31:39 +08:00
Wesley Liddick 4a50d05393 Merge pull request #4380 from wucm667/fix/issue-4357-responses-lite-context
fix(openai): normalize Responses Lite reasoning context
2026-07-16 09:31:29 +08:00
Wesley Liddick ba01199812 Merge pull request #4376 from drgnchan/hotfix/find-n6-table-scroll
fix(frontend): preserve horizontal table scrolling on tablets
2026-07-16 09:31:16 +08:00
Wesley Liddick 25d7797d83 Merge pull request #4379 from wucm667/fix/issue-4348-reject-image-chat-models
fix(openai): reject image models on chat completions
2026-07-16 09:31:05 +08:00
wucm667 d22f4d9b5b fix(openai): use image tool usage for OAuth billing 2026-07-16 08:48:43 +08:00
jjaw f552448fb2 复用调度快照账号载荷写入 2026-07-16 04:07:15 +08:00
harukaandClaude Opus 4.8 62d57c02d8 feat(billing): usage_logs 单独记录图片输入 token 与费用
图片编辑/图生图请求的图片输入 token 此前并入 input_tokens/input_cost,
无法对账。拆分上报口径,total_cost 保持不变。

后端:
- CostBreakdown 新增 ImageInputCost;computeTokenBreakdown 将图片输入费用
  从 InputCost 拆出(InputCost 从此仅含文本输入),并纳入 tier 倍率与总额;
  长上下文合并路径同步携带 ImageInputCost
- 迁移 179:usage_logs 新增 image_input_tokens / image_input_cost 列
- UsageLog、insert/query 仓储(含定位参数数组、CTE 列表、扫描顺序)、
  DTO 与 mapper 补齐两列
- openai_gateway_usage 从 usage 与 cost 落库图片输入 token/费用

前端:
- UsageLog 类型、imageUsage 工具(hasImageInputTokens/Cost、textInputTokens)
- 用量表 token 徽标、Token/费用 tooltip 与单价行按图/文输入拆分展示
- zh/en usage.* i18n

测试:
- 新增 gpt-image-2 图片编辑复现用例(复现 #4386 的 $0.016081 期望值)
- 新增 usage 提取器图片输入 token 解析用例(input_tokens_details.image_tokens)
- 更新 doubao 图文分价用例与仓储/契约测试以匹配新的 input/image 拆分口径

相关 #4386。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015wcJTKDddxXSQrepSs3wrU
2026-07-15 10:03:38 -07:00
王鹏 ad5e2a85b7 test(openai): validate body-limit error envelope 2026-07-16 00:52:26 +08:00
Tian Lee 90ee85f3ef feat: 按上游计费倍率调度 OpenAI 账号 2026-07-16 00:40:46 +08:00
siyuan 72fada40f6 fix(lint): check alpha search builder writes 2026-07-16 00:36:38 +08:00
siyuan 695665cbc8 fix(openai): fallback PAT alpha search to responses web_search 2026-07-16 00:36:38 +08:00
siyuan 776f3f0de7 fix(openai): align alpha search PAT forwarding 2026-07-16 00:36:38 +08:00
harukaandClaude Opus 4.8 06e03f467a feat(billing): 渠道自定义定价支持图片输入 token 单价 image_input_price
渠道 token 计费模式此前无法为图片输入 token 单独定价,gpt-image-2
图片编辑等请求的图像输入被按文本 input_price 计费。新增
channel_model_pricing.image_input_price 列及全链路支持。

后端:
- 迁移 178:channel_model_pricing 新增 image_input_price 列
- ChannelModelPricing 新增 ImageInputPrice 字段,repo 读写、校验补齐
- model_pricing_resolver / GetModelPricingWithChannel 映射到
  ImageInputPricePerToken;未配置时归零,由 computeTokenBreakdown
  回退文本输入价(向后兼容,与 image_output_price 的渠道权威规则一致)
- admin / 用户侧定价 DTO 与 model-pricing 自动填充接口补充该字段

前端:
- 渠道定价表单新增「图片输入」价格输入(token 模式)
- API 类型、表单模型、form↔API 换算、自动填充、用户侧模型定价卡展示
- zh/en i18n 标签

相关 #4386。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015wcJTKDddxXSQrepSs3wrU
2026-07-15 09:35:34 -07:00