正确转发 Usage 数据#2
Conversation
feat(proxy): add TypeScript implementation of DeepSeek proxy server Add a complete TypeScript proxy server that converts OpenAI Responses API requests to DeepSeek Chat Completions API. This includes support for streaming/non-streaming responses, tool/function call conversions, and XML function call parsing. - Convert OpenAI Responses API requests to DeepSeek Chat Completions format - Support both streaming and non-streaming responses - Handle tool/function call conversions - Parse XML function calls from DeepSeek responses - Map model names between OpenAI and DeepSeek - Provide health check endpoint - Implement graceful shutdown with signal handling Add AGENTS.md documentation covering project overview, features, API endpoints, environment variables, and development instructions. chore(converter): add usage conversion function for DeepSeek responses Add convert_deepseek_usage_to_responses function to properly map DeepSeek usage metrics (prompt_tokens, completion_tokens, total_tokens) to the expected response format. Apply this conversion across all response types including tool calls and regular responses. ```
Review Summary by QodoFix usage data conversion and forwarding in DeepSeek proxy
WalkthroughsDescription• Add convert_deepseek_usage_to_responses() function to properly map DeepSeek usage metrics to OpenAI Responses API format • Apply usage conversion across all response types (tool calls, regular, XML-based) • Pass usage data from DeepSeek stream chunks to StreamChunk output • Add comprehensive AGENTS.md documentation for TypeScript proxy server Diagramflowchart LR
A["DeepSeek Response<br/>with usage"] -->|convert_deepseek_usage_to_responses| B["Mapped Usage<br/>prompt_tokens → input_tokens"]
B -->|apply to all responses| C["Tool Calls Response"]
B -->|apply to all responses| D["Regular Response"]
B -->|apply to all responses| E["XML Tool Calls"]
B -->|apply to stream chunks| F["Stream Chunk Output"]
C -->|OpenAI Responses API| G["Downstream Apps"]
D -->|OpenAI Responses API| G
E -->|OpenAI Responses API| G
F -->|OpenAI Responses API| G
File Changes1. src/converter.ts
|
Code Review by Qodo
1. convert_deepseek_usage_to_responses uses any
|
| export function convert_deepseek_usage_to_responses(usage: any): any { | ||
| if (!usage || typeof usage !== 'object') { | ||
| return { input_tokens: 0, output_tokens: 0, total_tokens: 0 }; | ||
| } | ||
| return { | ||
| input_tokens: usage.prompt_tokens ?? 0, | ||
| output_tokens: usage.completion_tokens ?? 0, | ||
| total_tokens: usage.total_tokens ?? 0 | ||
| }; | ||
| } |
There was a problem hiding this comment.
1. convert_deepseek_usage_to_responses uses any 📘 Rule violation ⚙ Maintainability
The newly added convert_deepseek_usage_to_responses(usage: any): any bypasses strict TypeScript typing by introducing any in both parameter and return types. This weakens type safety and can mask schema/field mismatches at compile time.
Agent Prompt
## Issue description
New code introduces `any` types (`usage: any` and return `any`) in `convert_deepseek_usage_to_responses`, which weakens strict typing guarantees.
## Issue Context
The project compliance requires strict TypeScript typing; this helper can be typed with a small interface/type describing DeepSeek usage input and the normalized Responses usage output.
## Fix Focus Areas
- src/converter.ts[727-736]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| export function convert_deepseek_usage_to_responses(usage: any): any { | ||
| if (!usage || typeof usage !== 'object') { | ||
| return { input_tokens: 0, output_tokens: 0, total_tokens: 0 }; | ||
| } | ||
| return { | ||
| input_tokens: usage.prompt_tokens ?? 0, | ||
| output_tokens: usage.completion_tokens ?? 0, | ||
| total_tokens: usage.total_tokens ?? 0 | ||
| }; |
There was a problem hiding this comment.
2. Sse usage变成0 🐞 Bug ≡ Correctness
convert_deepseek_usage_to_responses 将 usage 字段从 DeepSeek 的 prompt_tokens/completion_tokens 改为 input_tokens/output_tokens,但 streaming.ts 的 build_completed_event 仍只读取 prompt_tokens/completion_tokens。结果是在“非流式响应被包装成模拟 SSE”时,response.completed 会输出全 0 的 usage。
Agent Prompt
## Issue description
非流式转换后的 `responses_response.usage` 现在是 `{input_tokens, output_tokens, total_tokens}`,但 `streaming.ts` 的 `build_completed_event()` 仍按 `{prompt_tokens, completion_tokens, total_tokens}` 映射,导致模拟 SSE 的 `response.completed` usage 归零。
## Issue Context
- `convert_deepseek_usage_to_responses()` 将 DeepSeek usage 键名改成 Responses usage。
- `handle_non_streaming_response()` 在 `original_request.stream=true` 时会调用 `generate_simulated_sse(responses_response, ...)`。
- `generate_simulated_sse()` 把 `responses_response.usage` 传给 `build_completed_event()`,但后者只读取 `prompt_tokens/completion_tokens`。
## Fix Focus Areas
- src/streaming.ts[596-612]
- src/streaming.ts[614-708]
## Suggested fix
在 `build_completed_event(response_id, usage)` 中同时兼容两套字段:
- 若存在 `usage.input_tokens`/`usage.output_tokens`,直接使用它们
- 否则回退到 `usage.prompt_tokens`/`usage.completion_tokens`
并保证 `total_tokens` 也按同样逻辑取值。这样模拟 SSE 与真实 streaming 两条路径都能得到正确 usage。
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
feat(security): sanitize sensitive data from logs - Disable full request logging in converter.ts that could contain sensitive data - Implement header sanitization in server.ts to redact authorization, x-api-key, and shutdown secrets with truncated values - Remove debug file writing functionality that could leak sensitive data - Disable message logging in streaming.ts that could expose sensitive information ```
9a8b70b to
7738511
Compare
用于让 CC-Switch 类的下游应用可以拿到完整正确的响应结果。