Modify - #2555
Conversation
新增传透模式功能,允许直接转发请求到上游服务商, 不做额外处理或转换,支持SSE流式响应的透传。 feat(controller): 添加Token余额查询接口 新增GET /usage/api/balance接口,用于获取Token余额信息, 包括余额、配额、状态等详细信息。 feat(relay): 实现传透模式响应透传功能 实现传透模式下的响应透传,支持流式和非流式响应的直接转发, 包含完整的错误处理和重试机制。
- 移除token余额查询接口的/api前缀,从/api/usage/api/balance调整为/usage/api/balance - 将chat-stream透传模式路由从/api/chat-stream调整为/chat-stream - 统一路由分组结构,提升路由配置的清晰度 - 添加关键限流中间件到余额查询接口
- 引入ChatStreamRequest结构体,统一加密请求格式解析 - 实现usage信息提取功能,支持流式和非流式响应的usage获取 - 重构计费逻辑,支持上游usage和本地估算相结合的计费方式 - 添加模型映射、渠道重试时重新初始化ChannelMeta等功能 - 优化输入token估算算法,支持图片等多类型内容估算 - 维护兼容性,保留旧接口并提供新接口带usage返回
- 添加敏感词检测功能,仅检测data字段内容 - 实现精确的token计算,替代原有的估算方法 - 支持对data、images、model字段进行精确token计算 - 添加图片token的精确计算逻辑,失败时使用默认值 - 集成用户组倍率信息到消费记录中 - 公开GetImageTokenForPassthrough方法供透传模式使用
将日志记录从logger.SysLog改为common.SysLog,确保在图像token计算失败时 能够正确记录日志信息,提高系统的可观测性。
- 在 genPassthroughRelayInfo 中调用 InitFirstResponseTime 确保首字时间正确初始化 - 新增 InitFirstResponseTime 方法用于手动创建 RelayInfo 场景的首字时间设置 - 保持与 genBaseRelayInfo 一致的初始化行为
- 在GetTokenBalance函数中添加注释说明强制从数据库读取的原因 - 将model.GetTokenByKey的第二个参数改为true,强制从数据库读取 而不是使用缓存,以确保返回的余额数据是最新的准确数据
- 移除未使用的 strings 包导入 - 将 RemainQuota 字段类型从 int 改为 int64 以支持更大数值 - 从 Authorization header 获取 token 改为从 context 获取 token_id - 直接通过 token_id 查询数据库获取 token 信息,提高查询效率 - 保持与 GetSubscription 接口的一致性 - 修复 token 验证逻辑,提高安全性
- 移除 BalanceResponse 结构体,直接使用 gin.H 返回数据 - 修改认证方式,从 Authorization header 中解析 token - 添加 Bearer token 验证逻辑 - 强制从数据库读取 token 信息,确保余额数据准确性 - 更新 remain_amount 计算说明注释
当用户配置为无限制配额(unlimited_quota)时,显示token的剩余配额; 当用户配置为有限配额时,显示用户的总配额余额。 该修改解决了无限制配额用户无法正确显示余额的问题, 并增强了余额获取的逻辑以支持不同配额类型的用户。
|
Caution Review failedThe pull request is closed. WalkthroughThis PR introduces a new token balance retrieval endpoint and a passthrough relay handler for streaming requests. The balance endpoint authenticates via Bearer token and returns token quota/status information. The passthrough handler manages chat-stream requests with retry logic, quota pre-consumption, and usage extraction from upstream responses. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant RelayPassthrough
participant Service
participant ChannelAdaptor
participant UpstreamAPI
participant PassthroughHandler
Client->>RelayPassthrough: POST /chat-stream (encrypted payload)
RelayPassthrough->>RelayPassthrough: Validate model & data
RelayPassthrough->>RelayPassthrough: Perform sensitive content checks
loop Retry Loop (bounded)
RelayPassthrough->>Service: getPassthroughChannel()
Service-->>RelayPassthrough: Channel (with adaptor)
RelayPassthrough->>RelayPassthrough: Apply model mapping
RelayPassthrough->>Service: calculateInputTokens()
Service-->>RelayPassthrough: Token count
RelayPassthrough->>Service: PreConsumeQuota()
alt Quota Available
Service-->>RelayPassthrough: Success (set defer rollback)
else Insufficient Quota
Service-->>RelayPassthrough: Error
RelayPassthrough->>RelayPassthrough: Return error
end
RelayPassthrough->>PassthroughHandler: PassthroughHelperWithUsage()
PassthroughHandler->>ChannelAdaptor: DoRequest(request body)
ChannelAdaptor->>UpstreamAPI: Forward request
UpstreamAPI-->>ChannelAdaptor: Response (streaming/non-streaming)
ChannelAdaptor-->>PassthroughHandler: Response
alt Streaming Response
PassthroughHandler->>PassthroughHandler: Stream to client while extracting usage
PassthroughHandler->>PassthroughHandler: Parse Server-Sent Events (data: lines)
PassthroughHandler->>PassthroughHandler: Extract usage from event
else Non-Streaming Response
PassthroughHandler->>PassthroughHandler: Extract usage from response JSON
PassthroughHandler->>Client: Send response
end
PassthroughHandler-->>RelayPassthrough: Usage (or estimated tokens on fallback)
alt Success
RelayPassthrough->>Service: postPassthroughConsumeQuotaWithUsage()
Service-->>RelayPassthrough: Confirm consumption
RelayPassthrough-->>Client: Success response
RelayPassthrough->>RelayPassthrough: Exit retry loop
else Retry Eligible Error
RelayPassthrough->>RelayPassthrough: Log retry attempt
RelayPassthrough->>Service: ReturnPreConsumedQuota() (defer)
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45-60 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (7)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.